Ejemplo n.º 1
0
    def evaluator(cls, node, environment):
        left = expressionEvaluator(doAssert=True)(node.left, environment).value
        right = expressionEvaluator(doAssert=True)(node.right,
                                                   environment).value
        supportedTypes = [Type.INTEGER, Type.FLOAT]

        if not left.type in supportedTypes:
            raise RuntimeException(
                f"Operator '{node.operator.value}' is supported only by {[t.name.lower() for t in supportedTypes]} type",
                node.left.pos)

        if not right.type in supportedTypes:
            raise RuntimeException(
                f"Operator '{node.operator.value}' is supported only by {[t.name.lower() for t in supportedTypes]} type",
                node.right.pos)

        if node.operator.value == "*":
            return getProperTypeProvider(left.value * right.value)

        if node.operator.value == "/":
            if right.value == 0:
                raise RuntimeException("Attempt to divide by 0",
                                       node.right.pos)

            value = left.value / right.value

            if left.type == right.type == Type.INTEGER and int(value) == value:
                return Type.integer(int(value))

            return getProperTypeProvider(value)

        raise RuntimeError("This line should never be reached")
Ejemplo n.º 2
0
    def evaluator(cls, node, environment):
        left = expressionEvaluator(doAssert=True)(node.left, environment).value
        right = expressionEvaluator(doAssert=True)(node.right,
                                                   environment).value

        if node.operator.value == "==":
            return cls.equalOperatorEvaluator(left, node.operator, right)

        if node.operator.value == "!=":
            return cls.notEqualOperatorEvaluator(left, node.operator, right)

        return cls.otherRelationOperatorsEvaluator(left, node.operator, right)
Ejemplo n.º 3
0
    def evaluator(cls, node, environment):
        map = {}
        keyEvaluator = Evaluator.oneOf(
            Evaluator.forNodes(lambda node, environment: EvaluationResult.OK(Type.string(node.value)), Identifier),
            expressionEvaluator(doAssert=True)
        )
        for entry in node.children:
            key = keyEvaluator(entry.key, environment).value
            if key in map:
                raise RuntimeException(f"Duplicated key '{key.stringify()}' found in map", entry.pos)
            map[key] = expressionEvaluator(doAssert=True)(entry.value, environment).value

        return Type.map(map)
Ejemplo n.º 4
0
    def evaluator(cls, node, environment):
        condition = expressionEvaluator(doAssert=True)(node.condition,
                                                       environment).value

        if condition.type != Type.BOOL:
            raise RuntimeException(
                f"Only {Type.BOOL.name.lower()} types can be used as conditions in conditional expression",
                node.condition.pos)

        if condition.value:
            return expressionEvaluator(doAssert=True)(node.ifNode,
                                                      environment).value
        else:
            return expressionEvaluator(doAssert=True)(node.elseNode,
                                                      environment).value
Ejemplo n.º 5
0
    def evaluator(cls, node, environment):
        value = expressionEvaluator(doAssert=True)(node.value, environment).value

        if value.type != Type.BOOL:
            raise RuntimeException(f"Operator '{node.operator.value}' is supported only by {Type.BOOL.name.lower()} type", node.value.pos)

        return Type.bool(not value.value)
Ejemplo n.º 6
0
def evaluate(node, environment):
    from smnp.runtime.evaluators.program import ProgramEvaluator
    from smnp.runtime.evaluators.expression import expressionEvaluator
    from smnp.runtime.evaluators.condition import IfElseStatementEvaluator
    from smnp.runtime.evaluators.block import BlockEvaluator
    from smnp.runtime.evaluators.imports import ImportEvaluator
    from smnp.runtime.evaluators.function import FunctionDefinitionEvaluator
    from smnp.runtime.evaluators.function import ReturnEvaluator
    from smnp.runtime.evaluators.extend import ExtendEvaluator
    from smnp.runtime.evaluators.throw import ThrowEvaluator

    result = Evaluator.oneOf(
        Evaluator.forNodes(ProgramEvaluator.evaluate, Program),
        Evaluator.forNodes(IfElseStatementEvaluator.evaluate, IfElse),
        Evaluator.forNodes(BlockEvaluator.evaluate, Block),
        Evaluator.forNodes(ImportEvaluator.evaluate, Import),
        Evaluator.forNodes(FunctionDefinitionEvaluator.evaluate,
                           FunctionDefinition),
        Evaluator.forNodes(ReturnEvaluator.evaluate, Return),
        Evaluator.forNodes(ExtendEvaluator.evaluate, Extend),
        Evaluator.forNodes(ThrowEvaluator.evaluate, Throw),
        #Evaluator.forNodes(ImportEvaluator.evaluate, ImportNode),
        #Evaluator.forNodes(FunctionDefinitionEvaluator.evaluate, FunctionDefinitionNode),
        #Evaluator.forNodes(ExtendEvaluator.evaluate, ExtendNode),
        #Evaluator.forNodes(BlockEvaluator.evaluate, BlockNode),
        #Evaluator.forNodes(ReturnEvaluator.evaluate, ReturnNode),
        expressionEvaluator())(node, environment)

    if not result.result:
        raise RuntimeException("Cannot evaluate program", node.pos)

    return result
Ejemplo n.º 7
0
 def evaluator(cls, node, environment):
     try:
         name = node.name.value
         arguments = abstractIterableEvaluator(expressionEvaluator(True))(
             node.arguments, environment)
         return environment.invokeFunction(name, arguments)
     except RuntimeException as e:
         raise updatePos(e, node)
Ejemplo n.º 8
0
    def evaluator(cls, node, environment):
        string = expressionEvaluator(doAssert=True)(node.value,
                                                    environment).value

        if string.type != Type.STRING:
            raise RuntimeException(
                f"Only {Type.STRING.name.lower()} types can be thrown",
                node.value.pos)

        raise CustomException(string.value, node.pos)
Ejemplo n.º 9
0
    def doFilter(cls, filter, environment):
        if type(filter) is not NoneNode:
            evaluation = expressionEvaluator(doAssert=True)(filter,
                                                            environment).value
            if evaluation.type != Type.BOOL:
                raise RuntimeException(
                    f"Expected {Type.BOOL.name.lower()} as filter expression, found {evaluation.type.name.lower()}",
                    filter.pos)

            return evaluation.value

        return True
Ejemplo n.º 10
0
    def evaluator(cls, node, environment):
        left = expressionEvaluator(doAssert=True)(node.left, environment).value
        right = expressionEvaluator(doAssert=True)(node.right,
                                                   environment).value

        if left.type in [Type.INTEGER, Type.FLOAT
                         ] and right.type in [Type.INTEGER, Type.FLOAT]:
            return cls.numberEvaluator(left, node.operator, right)

        if left.type == right.type == Type.STRING:
            return cls.stringEvaluator(left, node.operator, right)

        if left.type == right.type == Type.LIST:
            return cls.listEvaluator(left, node.operator, right)

        if left.type == right.type == Type.MAP:
            return cls.mapEvaluator(left, node.operator, right)

        raise RuntimeException(
            f"Operator {node.operator.value} is not supported by {left.type.name.lower()} and {right.type.name.lower()} types",
            node.operator.pos)
Ejemplo n.º 11
0
    def evaluator(cls, node, environment):
        left = expressionEvaluator(doAssert=True)(
            node.left, environment
        ).value  #TODO check if it isn't necessary to verify 'result' attr of EvaluatioNResult
        right = node.right

        if type(right) == Identifier:
            try:
                return left.properties[right.value]
            except KeyError:
                raise RuntimeException(
                    f"Unknown property '{right.value}' of type '{left.type.name.lower()}'",
                    right.pos)

        if type(right) == FunctionCall:
            try:
                arguments = abstractIterableEvaluator(
                    expressionEvaluator(doAssert=True))(right.arguments,
                                                        environment)
                return environment.invokeMethod(left, right.name.value,
                                                arguments)
            except RuntimeException as e:
                raise updatePos(e, right)
Ejemplo n.º 12
0
 def evaluator(cls, node, environment):
     if len(environment.callStack) > 0:
         returnValue = expressionEvaluator()(node.value, environment).value
         raise Return(returnValue)
         # Disclaimer
         # Exception system usage to control program execution flow is really bad idea.
         # However because of lack of 'goto' instruction equivalent in Python
         # there is a need to use some mechanism to break function execution on 'return' statement
         # and immediately go to Environment's method 'invokeFunction()' or 'invokeMethod()',
         # which can handle value that came with exception and return it to code being executed.
     else:
         raise RuntimeException(
             "Cannot use 'return' statement outside a function or method",
             node.pos, environment)
Ejemplo n.º 13
0
    def boolEvaluator(cls, node, environment, evaluatedIterator, parameters,
                      filter):
        output = []

        if len(parameters) > 0:
            raise RuntimeException(
                f"Loop with logic iterator can't' handle any parameters",
                node.parameters.pos)

        condition = evaluatedIterator
        while condition.value:
            if cls.doFilter(filter, environment):
                output.append(evaluate(node.right, environment).value)
            condition = expressionEvaluator(doAssert=True)(node.left,
                                                           environment).value

        return output
Ejemplo n.º 14
0
    def evaluator(cls, node, environment):
        target = node.left.value
        value = expressionEvaluator(doAssert=True)(
            node.right, environment
        ).value  #TODO check if it isn't necessary to verify 'result' attr of EvaluatioNResult
        environment.scopes[-1][target] = value

        return value


#
# def evaluateAssignment(assignment, environment):
#     target = assignment.target.identifier
#     value = evaluate(assignment.value, environment)
#     if value.type == Type.VOID:
#         raise RuntimeException(f"Expected expression, found '{value.type.name}'", assignment.value.pos)
#     scopeOfExistingVariable = environment.findVariableScope(target)
#     if scopeOfExistingVariable is not None:
#         scopeOfExistingVariable[target] = value
#     else:
#         environment.scopes[-1][target] = value
Ejemplo n.º 15
0
    def evaluator(cls, node, environment):
        iterator = expressionEvaluator(doAssert=True)(node.left,
                                                      environment).value
        parameters = [identifier.value for identifier in node.parameters
                      ] if type(node.parameters) != NoneNode() else []

        try:
            environment.appendScope()

            output = {
                Type.INTEGER: cls.numberEvaluator,
                Type.BOOL: cls.boolEvaluator,
                Type.LIST: cls.listEvaluator,
                Type.MAP: cls.mapEvaluator
            }[iterator.type](node, environment, iterator, parameters,
                             node.filter)

            environment.popScope()
        except KeyError:
            raise RuntimeException(
                f"The {iterator.type.name.lower()} type cannot stand as an iterator for loop statement",
                node.left.pos)

        return Type.list(output)
Ejemplo n.º 16
0
 def evaluator(cls, node, environment):
     list = abstractIterableEvaluator(expressionEvaluator(doAssert=True))(node, environment)
     return Type.list(list)
Ejemplo n.º 17
0
 def evaluator(cls, node, environment):
     left = expressionEvaluator(doAssert=True)(node.left, environment).value
     right = expressionEvaluator(doAssert=True)(node.right, environment).value
     return Type.bool(left.value and right.value)