mirror of
https://github.com/BoardWare-Genius/jarvis-models.git
synced 2025-12-13 16:53:24 +00:00
108 lines
3.4 KiB
Python
108 lines
3.4 KiB
Python
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")
|
|
self.set_identifier_value(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.get_identifier_value(id)
|
|
if fu == None:
|
|
raise Exception("Function not found: " + id)
|
|
return fu(*unquoted_args)
|
|
|
|
def get_identifier_value(self, key):
|
|
v = self.records.get(key)
|
|
if v != None:
|
|
return v
|
|
if self.parent != None:
|
|
return self.parent.get_identifier_value(key)
|
|
return None
|
|
|
|
def set_identifier_value(self, key, value):
|
|
v = self.records.get(key)
|
|
if v != None:
|
|
self.records[key] = value
|
|
return
|
|
if self.parent != None:
|
|
self.parent.set_identifier_value(key, value)
|
|
return
|
|
raise Exception("Identifier not found: " + key)
|
|
|
|
def unquote(self, ast):
|
|
if self._is_identifier(ast):
|
|
return self.get_identifier_value(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) |