コード例 #1
0
    def visitExpressionMultiplicative(
            self, ctx: LanguageParser.ExpressionMultiplicativeContext):
        if ctx.MUL_OP() or ctx.DIV_OP() or ctx.MOD_OP() or ctx.EXP_OP():
            operand_one = self.visitExpressionMultiplicative(
                ctx.expressionMultiplicative())
            operand_two = self.visitExpressionUnary(ctx.expressionUnary())

            if operand_one.type is not Type.NUMBER or operand_two.type is not Type.NUMBER:
                raise exceptions.TypeMismatchException(
                    "The multiplicative operators can only be applied to values of type NUMBER."
                )

            if ctx.MUL_OP():
                result = operand_one.value * operand_two.value
            elif ctx.DIV_OP():
                result = operand_one.value / operand_two.value
            elif ctx.MOD_OP():
                result = operand_one.value % operand_two.value
            elif ctx.EXP_OP():
                result = operand_one.value**operand_two.value
            else:
                raise Exception()

            return Value(Type.NUMBER, result)

        return self.visitExpressionUnary(ctx.expressionUnary())
コード例 #2
0
    def visitExpressionRelational(
            self, ctx: LanguageParser.ExpressionRelationalContext):

        expression_additive = ctx.expressionAdditive()

        if ctx.LT_OP() or ctx.GT_OP() or ctx.LTOE_OP() or ctx.GTOE_OP():
            operand_one = self.visitExpressionRelational(
                ctx.expressionRelational())
            operand_two = self.visitExpressionAdditive(expression_additive)

            if operand_one.type is not Type.NUMBER or operand_two.type is not Type.NUMBER:
                raise exceptions.TypeMismatchException(
                    "The relational operators can only be applied to values of type NUMBER."
                )

            if ctx.LT_OP():
                result = operand_one.value < operand_two.value
            elif ctx.GT_OP():
                result = operand_one.value > operand_two.value
            elif ctx.LTOE_OP():
                result = operand_one.value <= operand_two.value
            elif ctx.GTOE_OP():
                result = operand_one.value >= operand_two.value
            else:
                raise Exception()

            return Value(Type.BOOL, result)

        return self.visitExpressionAdditive(expression_additive)
コード例 #3
0
    def visitExpressionAdditive(self,
                                ctx: LanguageParser.ExpressionAdditiveContext):
        if ctx.ADD_OP() or ctx.SUB_OP():
            operand_one = self.visitExpressionAdditive(
                ctx.expressionAdditive())
            operand_two = self.visitExpressionMultiplicative(
                ctx.expressionMultiplicative())

            if operand_one.type != operand_two.type:
                raise exceptions.TypeMismatchException(
                    "The additive operators must be applied to values of the same types.",
                    None, operand_one.type, operand_two.type)

            # Numbers
            if operand_one.type is Type.NUMBER:
                if ctx.ADD_OP():
                    return Value(Type.NUMBER,
                                 operand_one.value + operand_two.value)
                else:  # SUB
                    return Value(Type.NUMBER,
                                 operand_one.value - operand_two.value)

            if operand_one.type is Type.STRING:
                if ctx.ADD_OP():
                    return Value(Type.STRING,
                                 operand_one.value + operand_two.value)
                else:
                    raise Exception("Unsupported string - string")

        return self.visitExpressionMultiplicative(
            ctx.expressionMultiplicative())
コード例 #4
0
    def execute(self, arguments):
        list = arguments[0]
        if list.type != Type.LIST:
            raise exceptions.TypeMismatchException(
                "list_push must be called on list.", None, list.type,
                Type.LIST)

        for to_push in arguments[1:]:
            list.value.append(to_push)
コード例 #5
0
    def visitStatementAssignmentBracket(
            self, ctx: LanguageParser.StatementAssignmentBracketContext):
        subject = self.visitExpressionPrimary(ctx.expressionPrimary())
        index = self.visitExpression(
            ctx.expressionBracketAccess().expression())
        to_assign = self.visitExpression(ctx.expression())

        if subject.type != Type.LIST and subject.type != Type.MAP:
            raise exceptions.TypeMismatchException(
                "[] applied to invalid value.")
        if subject.type == Type.LIST and index.type != Type.NUMBER:
            raise exceptions.TypeMismatchException("List index must be number",
                                                   None, index.type,
                                                   Type.Number)

        if subject.type == Type.LIST:
            subject.value[int(index.value)] = to_assign
        else:
            subject.value[index.value] = to_assign
コード例 #6
0
    def visitExpressionOr(self, ctx: LanguageParser.ExpressionOrContext):

        if ctx.OR_OP() is not None:
            operand_one = self.visitExpressionOr(ctx.expressionOr())
            operand_two = self.visitExpressionAnd(ctx.expressionAnd())

            if operand_one.type is not Type.BOOL or operand_two.type is not Type.BOOL:
                raise exceptions.TypeMismatchException(
                    "The or operator (||) can only be applied to values of type BOOL.",
                    [])

            return Value(Type.BOOL, operand_one.value or operand_two.value)

        return self.visitExpressionAnd(ctx.expressionAnd())
コード例 #7
0
    def visitExpressionUnary(self, ctx: LanguageParser.ExpressionUnaryContext):

        if ctx.NOT_OP():
            operand = self.visitExpressionPrimary(ctx.expressionPrimary())
            if operand.type is not Type.BOOL:
                raise exceptions.TypeMismatchException(
                    "The not operator (!) can only be applied to values of type BOOL."
                )

            return Value(Type.BOOL, not operand.value)

        if ctx.TYPE():
            operand = self.visitExpressionPrimary(ctx.expressionPrimary())
            return Value(Type.STRING, operand.get_type_name())

        if ctx.DEC_OP():
            operand = self.visitExpressionPrimary(ctx.expressionPrimary())
            if operand.type is not Type.NUMBER:
                raise exceptions.TypeMismatchException(
                    "The not dec (--) can only be applied to values of type NUMBER."
                )

            operand.value = operand.value - 1
            return operand

        if ctx.INC_OP():
            operand = self.visitExpressionPrimary(ctx.expressionPrimary())
            if operand.type is not Type.NUMBER:
                raise exceptions.TypeMismatchException(
                    "The not dec (++) can only be applied to values of type NUMBER."
                )

            operand.value = operand.value + 1
            return operand

        return self.visitExpressionPrimary(ctx.expressionPrimary())
コード例 #8
0
    def visitStatementIf(self, ctx: LanguageParser.StatementIfContext):
        conditional = self.visitExpression(ctx.expression())
        if conditional.type is not Type.BOOL:
            raise exceptions.TypeMismatchException(
                "If conditions must be type boolean", None, conditional.type,
                Type.BOOL)

        try:
            self._stack.push(Frame())
            if conditional.value:
                return self.visitCodeBlock(ctx.codeBlock())
            elif ctx.statementElse() is not None:
                return self.visitCodeBlock(ctx.statementElse().codeBlock())
        finally:
            self._stack.pop()
コード例 #9
0
    def visitStatementWhile(self, ctx: LanguageParser.StatementWhileContext):
        self._stack.push(Frame())

        try:
            while True:
                conditional = self.visitExpression(ctx.expression())
                if conditional.type is not Type.BOOL:
                    raise exceptions.TypeMismatchException(
                        "If conditions must be type boolean", None,
                        conditional.type, Type.BOOL)
                if conditional.value:
                    ret = self.visitCodeBlock(ctx.codeBlock())
                    if ret is not None:
                        return ret
                else:
                    return None
        finally:
            self._stack.pop()
コード例 #10
0
    def visitStatementFor(self, ctx: LanguageParser.StatementForContext):
        self.visitStatementVariableDeclaration(
            ctx.statementVariableDeclaration())
        ret = Value(Type.NULL, None)
        while True:

            conditional = self.visitExpression(
                ctx.statementExpression().expression())

            if conditional.type is not Type.BOOL:
                raise exceptions.TypeMismatchException(
                    "For conditions must be type boolean", None,
                    conditional.type, Type.BOOL)
            if conditional.value:
                ret = self.visitCodeBlock(ctx.codeBlock())
                if ret is not None:
                    ret = ret
                    break
                self.visitExpression(ctx.expression())
            else:
                break

        return ret
コード例 #11
0
    def visitExpressionPrimary(self,
                               ctx: LanguageParser.ExpressionPrimaryContext):

        expression_paren = ctx.expressionParenthesized()
        if expression_paren is not None:
            return self.visitExpressionParenthesized(expression_paren)

        expression_func = ctx.expressionFunction()
        if expression_func is not None:
            return self.visitExpressionFunction(expression_func)

        expression_var = ctx.expressionVariable()
        if expression_var is not None:
            return self.visitExpressionVariable(expression_var)

        expression_list = ctx.expressionList()
        if expression_list is not None:
            return self.visitExpressionList(expression_list)

        expression_map = ctx.expressionMap()
        if expression_map is not None:
            return self.visitExpressionMap(expression_map)

        expression_lit = ctx.expressionLiteral()
        if expression_lit is not None:
            return self.visitExpressionLiteral(expression_lit)

        expression_closure = ctx.expressionClosure()
        if expression_closure is not None:
            return self.visitExpressionClosure(expression_closure)

        field_access = ctx.expressionFieldAccess()
        if field_access is not None:
            field_name = field_access.IDENTIFIER().getText()
            subject = self.visitExpressionPrimary(ctx.expressionPrimary())
            field_value = subject.fields.get(field_name)
            if field_value is None:
                raise exceptions.UnknownFieldException(subject, field_name)

            return field_value

        closure_invocation = ctx.expressionClosureInvocation()
        if closure_invocation is not None:
            subject = self.visitExpressionPrimary(ctx.expressionPrimary())
            closure = subject.value
            if subject.type != Type.CLOSURE:
                raise exceptions.TypeMismatchException(
                    "Cannot only use .() operator on CLOSURE.", None,
                    subject.type, Type.CLOSURE)

            arguments = map(
                lambda expression: self.visitExpression(expression),
                closure_invocation.arguments().expression())

            new_frame = Frame()
            new_frame.set_variables(zip(closure.parameters, arguments))
            self._stack.push(new_frame)
            if closure.expression is not None:
                result = self.visitExpression(closure.expression)
            else:
                result = self.run_returnable(closure.statements)

            self._stack.pop()
            return result

        method_access = ctx.expressionMethodAccess()
        if method_access is not None:
            method_name = method_access.IDENTIFIER().getText()
            subject = self.visitExpressionPrimary(ctx.expressionPrimary())
            method_instance = subject.methods.get(method_name)

            if method_instance is None:
                raise exceptions.UnknownMethodException(subject, method_name)

            arguments = map(
                lambda expression: self.visitExpression(expression),
                method_access.arguments().expression())

            new_frame = Frame()
            new_frame.set_variables(zip(method_instance.parameters, arguments))
            new_frame.set_variable("this", subject)
            self._stack.push(new_frame)
            result = self.visitCodeBlock(method_instance.code)
            self._stack.pop()
            return result

        new_expression = ctx.expressionNew()
        if new_expression is not None:
            return self.visitExpressionNew(new_expression)

        bracket_access = ctx.expressionBracketAccess()
        if bracket_access is not None:
            subject = self.visitExpressionPrimary(ctx.expressionPrimary())
            if subject.type != Type.LIST and subject.type != Type.MAP:
                raise exceptions.TypeMismatchException(
                    "[] applied to invalid value.")
            index = self.visitExpression(bracket_access.expression())
            if subject.type == Type.LIST and index.type != Type.NUMBER:
                raise exceptions.TypeMismatchException(
                    "List index must be number", None, index.type, Type.Number)
            if subject.type == Type.LIST:
                value = subject.value[int(index.value)].value
            else:
                temp = subject.value.get(index.value)
                value = temp and temp.value

            return Value(get_type_of(value), value)