コード例 #1
0
ファイル: Compiler.py プロジェクト: Plecra/McScript
    def comparison(self, tree):
        token_a, token_operator, token_b = tree.children

        a = self.compileState.toResource(token_a)
        b = self.compileState.toResource(token_b)
        operator = ScoreRelation(token_operator)

        try:
            node = a.operation_test_relation(self.compileState, operator, b)
        except TypeError:
            raise McScriptUnsupportedOperationError(operator.name, a.type(), b.type(), self.compileState)

        if len(node["conditions"]) == 1 and isinstance(node["conditions"][0], ConditionalNode.IfBool):
            cond = node["conditions"][0]
            return BooleanResource(int(cond["val"]), None)

        # if currently looking for a condition, return it directly
        if self.compileState.currentContext().user_data.get_is_condition():
            return node

        stack = self.compileState.expressionStack.next()
        self.compileState.ir.append(StoreFastVarFromResultNode(
            stack,
            node
        ))
        return BooleanResource(None, stack)
コード例 #2
0
ファイル: Compiler.py プロジェクト: Plecra/McScript
    def index_setter(self, tree):
        accessor, index, value = tree.children

        accessor = self.visit(accessor)
        index = self.compileState.toResource(index)
        value = self.compileState.toResource(value)

        try:
            return accessor.operation_set_element(self.compileState, index, value)
        except TypeError:
            raise McScriptUnsupportedOperationError("[]=", accessor.type(), None, self.compileState)
コード例 #3
0
ファイル: Compiler.py プロジェクト: Plecra/McScript
    def array_accessor(self, tree):
        """ Accesses an element on an array"""
        accessor_, index_ = tree.children

        accessor = self.visit(accessor_)
        index = self.compileState.toResource(index_)

        try:
            self.compileState.currentTree = index_
            return accessor.operation_get_element(self.compileState, index)
        except TypeError:
            raise McScriptUnsupportedOperationError("[]", accessor.type(), None, self.compileState)
コード例 #4
0
ファイル: Compiler.py プロジェクト: Plecra/McScript
    def control_for(self, tree):
        _, var_name, _, expression, block = tree.children

        resource = self.compileState.toResource(expression)
        try:
            iterator = resource.get_iterator(self.compileState)
        except TypeError:
            raise McScriptUnsupportedOperationError("iteration", resource.type(), None, self.compileState)

        while (value := iterator.next()) is not None:
            with self.compileState.node_block(ContextType.UNROLLED_LOOP, block.line, block.column) as block_function:
                self.compileState.currentContext().add_var(var_name, value)
                self.visit(block)
            self.compileState.ir.append(FunctionCallNode(block_function))
コード例 #5
0
ファイル: Compiler.py プロジェクト: Plecra/McScript
    def binaryOperation(self, *args, assignment_resource: Resource = None):
        number1, *values = args

        # whether the first number may be overwritten
        is_temporary = isinstance(number1, Resource) and not number1.is_variable
        all_static = all(is_static(i) for i in args[::2])

        # the first number can also be a list. Then just do a binary operation with it
        if isinstance(number1, list):
            number1 = self.binaryOperation(*number1)
            is_temporary = True

        number1 = self.compileState.toResource(number1)

        # by default all operations are in-place. This is not wanted, so the resource is copied
        if isinstance(number1, ValueResource) and (not all_static and not is_temporary):
            # copy, except the assign resource is number1 (OPT)
            if assignment_resource is None:
                number1 = number1.copy(self.compileState.expressionStack.next(), self.compileState)

        for i in range(0, len(values), 2):
            operator, number2, = values[i:i + 2]

            if isinstance(number2, list):
                # number2 is now also temporary, but is will not change anyways
                number2 = self.binaryOperation(*number2)
            elif is_static(number1) and not is_static(number2) and number2.is_variable:
                # if the first value is static and the second a variable, they may not be swapped
                # so store the first value
                number1 = number1.store(self.compileState)

            # get the operator enum type
            operator = BinaryOperator(operator)

            number2 = self.compileState.toResource(number2)

            if not isinstance(number2, ValueResource):
                raise ValueError(
                    "ToDO: Implement boolean operations for non value-resources")

            try:
                number1 = number1.numericOperation(
                    number2, operator, self.compileState)
            except TypeError:
                raise McScriptUnsupportedOperationError(operator.value, number1.type(), number2.type(),
                                                        self.compileState)

        return number1
コード例 #6
0
ファイル: Compiler.py プロジェクト: Plecra/McScript
    def unary_operation(self, tree):
        # noinspection PyShadowingNames
        def doOperation(operator: UnaryOperator, value: Resource):
            if operator == UnaryOperator.MINUS:
                return value.operation_negate(self.compileState)
            raise ValueError(
                f"Unknown unary operator {operator.name} in unary_operation")

        operator, value = tree.children
        value = self.compileState.toResource(value)
        operator = UnaryOperator(operator)

        # first try to do the operation on the resource itself.
        # if that is not possible, load the resource and try again
        try:
            return doOperation(operator, value)
        except TypeError:
            raise McScriptUnsupportedOperationError(operator.name, value.type(), None, self.compileState)
コード例 #7
0
ファイル: ResourceBase.py プロジェクト: Plecra/McScript
 def numericOperation(self, other: ValueResource, operator: BinaryOperator,
                      compileState: CompileState) -> Resource:
     """
     Performs a numeric operation with this resource.
     The operation should be performed in-place
     """
     if not isinstance(other, type(self)):
         raise TypeError()
     try:
         if operator == BinaryOperator.PLUS:
             return self.operation_plus(other, compileState)
         elif operator == BinaryOperator.MINUS:
             return self.operation_minus(other, compileState)
         elif operator == BinaryOperator.TIMES:
             return self.operation_times(other, compileState)
         elif operator == BinaryOperator.DIVIDE:
             return self.operation_divide(other, compileState)
         elif operator == BinaryOperator.MODULO:
             return self.operation_modulo(other, compileState)
     except TypeError:
         raise McScriptUnsupportedOperationError(operator.name, self.type(),
                                                 other.type(), compileState)
     raise ValueError("Unknown operator: " + repr(operator))