Files
@ c296b5584a9d
Branch filter:
Location: Jasinta/src/jasinta.py
c296b5584a9d
2.4 KiB
text/x-python
basic variable declaration and arithmetic addition
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | from std import lib as stdlib
class Undefined:
pass
def evaluate(node, context):
if node is None:
return None
node_type = node["type"]
if node_type == "Identifier":
for ctx in reversed(context):
if node["name"] in ctx:
return ctx[node["name"]]
return Undefined
cls = node_index[node_type]
obj = cls(node)
return obj.eval(context)
class Program:
def __init__(self, node):
self.node = node
def eval(self, context):
program_context = [*context, dict()]
for node in self.node["body"]:
evaluate(node, program_context)
class ExpressionStatement:
def __init__(self, node):
self.node = node
def eval(self, context):
evaluate(self.node["expression"], context)
class CallExpression:
def __init__(self, node):
self.node = node
def eval(self, context):
callee = evaluate(self.node["callee"], context)
arguments = [evaluate(arg, context) for arg in self.node["arguments"]]
return callee(*arguments)
class MemberExpression:
def __init__(self, node):
self.node = node
def eval(self, context):
obj = evaluate(self.node["object"], context)
prop = evaluate(self.node["property"], [obj])
return prop
class BinaryExpression:
def __init__(self, node):
self.node = node
def eval(self, context):
left = evaluate(self.node["left"], context)
right = evaluate(self.node["right"], context)
# in fact this doesn't follow JavaScript "+" semantics
if self.node["operator"] == "+":
return left+right
else:
raise NotImplementedError
class EmptyStatement:
def __init__(self, node):
pass
def eval(self, context):
pass
class VariableDeclaration:
def __init__(self, node):
self.node = node
def eval(self, context):
for node in self.node["declarations"]:
evaluate(node, context)
class VariableDeclarator:
def __init__(self, node):
self.node = node
def eval(self, context):
value = evaluate(self.node["init"], context)
if self.node["id"]["type"] == "Identifier":
name = self.node["id"]["name"]
context[-1][name] = value
else:
raise NotImplementedError
class Literal:
def __init__(self, node):
self.node = node
def eval(self, context):
return self.node["value"]
node_index = {cls.__name__: cls for cls in [
Program, ExpressionStatement, CallExpression, MemberExpression, EmptyStatement, BinaryExpression,
VariableDeclaration, VariableDeclarator, Literal
]}
def interpret(parse_tree):
return evaluate(parse_tree, [stdlib])
|