Files @ c296b5584a9d
Branch filter:

Location: Jasinta/src/jasinta.py - annotation

Laman
basic variable declaration and arithmetic addition
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
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])