Files @ e658f59d183b
Branch filter:

Location: Jasinta/src/jasinta.py - annotation

Laman
added LICENSE
18037ac0f6b4
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
18037ac0f6b4
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
18037ac0f6b4
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
2dc5ec5e11be
2dc5ec5e11be
2dc5ec5e11be
2dc5ec5e11be
2dc5ec5e11be
2dc5ec5e11be
2dc5ec5e11be
2dc5ec5e11be
2dc5ec5e11be
2dc5ec5e11be
2dc5ec5e11be
2dc5ec5e11be
2dc5ec5e11be
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
18037ac0f6b4
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
18037ac0f6b4
18037ac0f6b4
18037ac0f6b4
18037ac0f6b4
18037ac0f6b4
18037ac0f6b4
18037ac0f6b4
18037ac0f6b4
18037ac0f6b4
c296b5584a9d
c296b5584a9d
c296b5584a9d
2dc5ec5e11be
2dc5ec5e11be
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
c296b5584a9d
from std import lib as stdlib, Number


class Undefined:
	pass


def evaluate(node, context):
	if node is None:
		return None

	node_type = node["type"]
	# retrieve an already existing object from the context
	if node_type == "Identifier":
		for ctx in reversed(context):
			if node["name"] in ctx:
				return ctx[node["name"]]
		return Undefined

	# create a new object
	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 AssignmentExpression:
	def __init__(self, node):
		self.node = node

	def eval(self, context):
		left = evaluate(self.node["left"], context)
		right = evaluate(self.node["right"], context)
		if self.node["operator"] == "+=":
			left.val += right.val
		else:
			raise NotImplementedError


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 Number(left.val+right.val)
		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):
		val = self.node["value"]

		if isinstance(val, float):
			if int(val) == val:
				return Number(int(val))
			else:
				return Number(val)
		else:
			raise NotImplementedError


node_index = {cls.__name__: cls for cls in [
	Program, ExpressionStatement, CallExpression, MemberExpression, EmptyStatement, AssignmentExpression,
	BinaryExpression, VariableDeclaration, VariableDeclarator, Literal
]}


def interpret(parse_tree):
	return evaluate(parse_tree, [stdlib])