def evaluator(cls, node, environment): environment.appendScope() for child in node.children: evaluate(child, environment) environment.popScope()
def _interpret(lines, source, printTokens=False, printAst=False, execute=True, baseEnvironment=None): environment = Environment([{}], functions, methods, source=source) if baseEnvironment is not None: environment.extend(baseEnvironment) try: tokens = tokenize(lines) if printTokens: print(tokens) ast = parse(tokens) if printAst: ast.print() if execute: evaluate(ast, environment) return environment except RuntimeException as e: e.environment = environment e.file = environment.source raise e
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: evaluate(node.ifNode, environment) else: evaluate(node.elseNode, environment)
def mapEvaluator(cls, node, environment, evaluatedIterator, parameters, filter): output = [] if len(parameters) > 3: raise RuntimeException( f"Loop with map iterator can handle only three parameters", node.parameters.pos) i = 0 for key, value in evaluatedIterator.value.items(): if len(parameters) == 1: environment.scopes[-1][parameters[0]] = value if len(parameters) == 2: environment.scopes[-1][parameters[0]] = key environment.scopes[-1][parameters[1]] = value if len(parameters) == 3: environment.scopes[-1][parameters[0]] = Type.integer(i) environment.scopes[-1][parameters[1]] = key environment.scopes[-1][parameters[2]] = value i += 1 if cls.doFilter(filter, environment): output.append(evaluate(node.right, environment).value) return output
def evaluator(cls, node, environment): value = evaluate(node.value, environment).value try: return { Type.INTEGER: cls.evaluateForInteger, Type.FLOAT: cls.evaluateForFloat, Type.STRING: cls.evaluateForString, Type.LIST: cls.evaluateForList }[value.type](value.value) except KeyError: raise RuntimeException( f"Type {value.type.name.lower()} does not support '{node.operator.value}' operator", node.pos)
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
def numberEvaluator(cls, node, environment, evaluatedIterator, parameters, filter): output = [] if len(parameters) > 1: raise RuntimeException( f"Loop with numeric iterator can handle only one parameter", node.parameters.pos) for i in range(evaluatedIterator.value): if len(parameters) > 0: environment.scopes[-1][parameters[0]] = Type.integer(i) if cls.doFilter(filter, environment): output.append(evaluate(node.right, environment).value) return output
def listEvaluator(cls, node, environment, evaluatedIterator, parameters, filter): output = [] if len(parameters) > 2: raise RuntimeException( f"Loop with list iterator can handle only two parameters", node.parameters.pos) for i, value in enumerate(evaluatedIterator.value): if len(parameters) == 1: environment.scopes[-1][parameters[0]] = value if len(parameters) == 2: environment.scopes[-1][parameters[0]] = Type.integer(i) environment.scopes[-1][parameters[1]] = value if cls.doFilter(filter, environment): output.append(evaluate(node.right, environment).value) return output
def evaluateReturn(returnNode, environment): return evaluate(returnNode.value, environment)
def evaluator(cls, node, environment): for n in node.children: evaluate(n, environment)
def evaluator(cls, node, environment): for child in node.children: evaluate(child, environment)