示例#1
0
 def valueNumber(self) -> float:
     try:
         return float(self.valueString)
     except:
         Error.handleFromElement(element=self.element,
                                 message="Expected a valid number.")
     return 0.0  # To make mypy happy
示例#2
0
 def valueString(self) -> str:
     value = self.value
     if value is None:
         Error.handleFromElement(element=self.element,
                                 message="A value must be present.")
     assert value is not None
     return value
示例#3
0
    def resolve(self, contracts: "Contracts") -> None:
        """
		Merge a base contract into this one. The order is important, as type are inherited from the deepest base.
		"""

        elementBuilder = ElementBuilder.cast(self.element, ElementBuilder)
        for contract in reversed([*contracts]):
            # Check if the type already exists, if so attempt to merge the 2 types.
            existing = self.get(contract.type)
            if existing is not None:
                contractTraits = AllContracts.all.get(contract.type)
                assert contractTraits, "All contracts should have been validated already."
                try:
                    contract = contractTraits.resolveConflict(base=contract,
                                                              derived=existing)
                except Exception as e:
                    Error.handleFromElement(element=self.element,
                                            message=str(e))
                # Remove the existing contract if resolved into a new contract
                if contract is not None:
                    self.remove(contract.type)

            if contract is not None:
                elementBuilder.pushFrontElementToNestedSequence(
                    self.sequenceKind, contract.element)

        # Construct a dummy Validation to check the arguments
        maybeSchema = self.validationForAll
        if maybeSchema:
            Validation(schema=[maybeSchema])
示例#4
0
 def errorSymbolConflict_(element1: Element, element2: Element) -> None:
     message = Error.handleFromElement(
         element=element1,
         message="Symbol name is in conflict...",
         throw=False)
     message += Error.handleFromElement(element=element2,
                                        message="...with this one.",
                                        throw=False)
     raise Exception(message)
示例#5
0
    def validate(self) -> None:
        """
		Validate the contracts. it checks the follow:
			- Valid contract types.
		"""

        for contract in self:
            contractTraits = AllContracts.allPublic.get(contract.type)
            if contractTraits is None:
                Error.handleFromElement(
                    element=self.element,
                    message="Contract of type '{}' is not supported.".format(
                        contract.type))
示例#6
0
def elementToEntity(element: Element,
	extension: typing.Optional[typing.Dict[str, typing.Type[EntityType]]] = None) -> EntityType:
	"""
	Instantiate an entity from an element.
	"""

	Error.assertHasAttr(element=element, attr="category")
	category = element.getAttr("category").value

	if extension and category in extension:
		return extension[category](element=element)

	if category not in CATEGORY_TO_ENTITY:
		Error.handleFromElement(element=element, message="Unexpected element category: {}".format(category))

	return CATEGORY_TO_ENTITY[category](element=element)
示例#7
0
    def _render(
        self, substitutions: typing.Union[SubstitutionsAccessor,
                                          SubstitutionWrapper]
    ) -> typing.Tuple[ResultType, SubstitutionWrapper]:

        sequence = self.parser.parse()
        *_, last = sequence
        if last.getAttrValue("category",
                             None) in ["if", "else", "for", "macro"]:
            Error.handleFromElement(element=last,
                                    message="Unterminated control block.")

        visitor = Visitor(substitutions, *self.args, **self.kwargs)
        result = visitor.visit(sequence)

        return result, visitor.substitutions
示例#8
0
    def readValue(self, element: Element) -> typing.Any:
        """
		Read a value from an element.
		"""

        Error.assertHasAttr(element=element, attr="value")
        Error.assertHasAttr(element=element, attr="type")
        valueType = element.getAttr("type").value
        value = element.getAttr("value").value
        if valueType == "name":
            return self.resolveName(value)
        elif valueType == "number":
            return float(value)
        elif valueType == "string":
            return value
        elif valueType == "true":
            return True
        elif valueType == "false":
            return False
        Error.handleFromElement(element=element,
                                message="Unsupported value type.")
示例#9
0
 def transform(entity: Type, nested: typing.List[str],
               reference: bool) -> TypeConversionCallableReturn:
     maybeContractMin = entity.contracts.get("min")
     isSigned = True if maybeContractMin is None or maybeContractMin.valueNumber < 0 else False
     maybeContractMax = entity.contracts.get("max")
     bits = 32
     if maybeContractMax is not None:
         maxValue = maybeContractMax.valueNumber
         if maxValue < 2**8:
             bits = 8
         elif maxValue < 2**16:
             bits = 16
         elif maxValue < 2**32:
             bits = 32
         elif maxValue < 2**64:
             bits = 64
         else:
             Error.handleFromElement(
                 element=entity.element,
                 message="Value too large, max supported is 64-bit.")
     if isSigned:
         return "bzd::Int{}Type".format(bits), nested
     return "bzd::UInt{}Type".format(bits), nested
示例#10
0
    def visitElement(self, element: Element, result: T) -> T:
        """
		Main visitor, called each time a new element is discovered.
		"""

        entity = elementToEntity(element=element,
                                 extension=self.elementToEntityExtenstion)

        # Handle nested object
        if isinstance(entity, Nested):

            self.level += 1

            for category in CATEGORIES:
                sequence = element.getNestedSequence(category)
                if sequence is not None:
                    self.parents.append(
                        Parent(entity=entity, category=category))
                    nestedResult = self._visit(sequence, result)
                    self.entityToNested(category, entity, nestedResult, result)
                    self.parents.pop()

            self.level -= 1

            self.visitNestedEntities(entity, result)

        # Handle expression
        elif isinstance(entity, Expression):

            self.visitExpression(entity, result)

        # Handle method
        elif isinstance(entity, Method):

            self.visitMethod(entity, result)

        # Handle using
        elif isinstance(entity, Using):

            self.visitUsing(entity, result)

        # Handle using
        elif isinstance(entity, Enum):

            self.visitEnum(entity, result)

        # Handle namespace
        elif isinstance(entity, Namespace):

            Error.assertTrue(
                element=element,
                condition=(self.level == 0),
                message="Namespaces can only be declared at top level.")

            self.visitNamespace(entity, result)

            # Update the current namespace
            self.parents.append(Parent(entity=entity))

        # Handle use
        elif isinstance(entity, Use):

            self.visitUse(entity, result)

        # Should never go here
        else:
            Error.handleFromElement(element=element,
                                    message="Unexpected entity: {}".format(
                                        type(entity)))

        return result
示例#11
0
    def visitElement(self, element: Element, result: ResultType) -> ResultType:
        """
		Go through all elements and dispatch the action.
		"""

        Error.assertHasAttr(element=element, attr="category")
        category = element.getAttr("category").value

        try:

            # Raw content
            if category == "content":
                Error.assertHasAttr(element=element, attr="content")
                string = element.getAttr("content").value
                result.append(string)

            # Substitution
            elif category == "substitution":
                self.visitSubstitution(element=element, result=result)

            # Comments
            elif category == "comment":
                pass

            # End statement
            elif category == "end":
                # Reset the else flag here to make sure nested if without else do not trigger.
                self.followElse = False

            # For loop block
            elif category == "for":
                block = self.visitForBlock(element=element)
                self.appendBlock(element=element, result=result, block=block)

            # If block
            elif category == "if":
                Error.assertHasAttr(element=element, attr="condition")
                conditionStr = element.getAttr("condition").value
                block = self.visitIfBlock(element=element,
                                          conditionStr=conditionStr)
                self.appendBlock(element=element, result=result, block=block)

            # Else block
            elif category == "else":
                block = []
                if self.followElse:
                    conditionStr = element.getAttrValue("condition",
                                                        "True")  # type: ignore
                    block = self.visitIfBlock(element=element,
                                              conditionStr=conditionStr)
                self.appendBlock(element=element, result=result, block=block)

            # Macro block
            elif category == "macro":
                self.visitMacro(element=element)

            elif category == "include":
                block = self.visitInclude(element=element)
                self.appendBlock(element=element, result=result, block=block)

            else:
                raise Exception("Unsupported category: '{}'.".format(category))

        # Propagate processed exception to the top layer
        except ExceptionParser as e:
            raise e

        except Exception as e:
            Error.handleFromElement(element=element, message=str(e))

        return result
示例#12
0
 def error(self, message: str, throw: bool = True) -> str:
     return Error.handleFromElement(element=self.element,
                                    message=message,
                                    throw=throw)