Files @ 41be60d4fd30
Branch filter:

Location: Jasinta/src/jasinta.py

Laman
a test for the basic case
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])