Changeset - c296b5584a9d
[Not reviewed]
default
0 0 2
Laman - 2 years ago 2023-01-01 13:25:39

basic variable declaration and arithmetic addition
2 files changed with 126 insertions and 0 deletions:
0 comments (0 inline, 0 general)
src/jasinta.py
Show inline comments
 
new file 100644
 
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])
src/std.py
Show inline comments
 
new file 100644
 
lib = {
 
	"document": {"write": print}
 
}
0 comments (0 inline, 0 general)