class Runtime: def __init__(self, records={}, parent=None): self.parent = parent self.records = records def run(self, ast, records={}): self.records.update(records) if ast["type"] == "Program": return self.program(ast) def program(self, ast): return self.block(ast.get("body")) def block(self, ast): for statement in ast.get("body"): s = self.switch(statement) if s != None: return s def switch(self, ast): t = ast["type"] if t == "VariableDeclaration": self.variable_declaration(ast) if t == "AssignmentExpression": self.assignment_expression(ast) if t == "CallExpression": self.call_function(ast) if t == "ReturnStatement": return self.exec_return(ast) def assignment_expression(self, ast): id = ast.get("identifier").get("name") v = ast.get("value") l = self.literal(v) self.records[id] = self.unquote(v) def _is_call_function(self, ast): return ast["type"] == "CallExpression" def call_function(self,ast): id = ast.get("callee").get("name") args = ast.get("arguments") unquoted_args = [] for arg in args: unquoted_args.append(self.unquote(arg)) fu = self.records.get(id) if fu == None: raise Exception("Function not found: " + id) return fu(*unquoted_args) def unquote(self, ast): if self._is_identifier(ast): return self.records.get(ast.get("name")) if self._is_literal(ast): return self.literal(ast) if self._is_call_function(ast): return self.call_function(ast) def variable_declaration(self, ast): id = ast.get("identifier").get("name") v = ast.get("value") self.records[id] = self.unquote(v) def literal(self, ast): if ast.get("type") == "StringLiteral": return ast.get("value") elif ast.get("type") == "NumericLiteral": return int(ast.get("value")) elif ast.get("type") == "FloatLiteral": return float(ast.get("value")) elif ast.get("type") == "BooleanLiteral": return bool(ast.get("value")) def _is_identifier(self, ast): return ast["type"] == "Identifier" def _is_literal(self, ast): return ast["type"] in ["NumericLiteral", "StringLiteral", "FloatLiteral", "BooleanLiteral"] def exec_return(self, ast): v = ast.get("value") if self._is_literal(v): return self.literal(v) if self._is_identifier(v): return self.records.get(v.get("name")) if self._is_call_function(v): return self.call_function(v) def debug_print_records(self): print(self.records)