class SyntaxObj(object): pass class EvalObj(SyntaxObj): def __str__(self): return "#" class ValObj(EvalObj): def __str__(self): return "#" class NumberObj(ValObj): def __str__(): return "#" class IntObj(NumberObj): def __init__(self, num): self.val = int(num) def __str__(): return "#" class FloatObj(NumberObj): def __init__(self, num): self.val = float(num) def __str__(): return "#" class StringObj(ValObj): def __init__(self, string): self.val = string def __str__(): return "#" class ProcObj(ValObj): def __init__(self, env, prog): self.val = proc def __str__(): return "#" class IdObj(SyntaxObj): def __init__(self, string): self.name = string def get_name(): return self.name class Tokenizor(): def __init__(self): self.data = "" self.tokenized = list() self.extended_chars = "!$%&*+-./:<=>?@^_~" def is_identifier(self, string): if string[0].isdigit(): return False for i in string[1:]: if not (i.isalnum() or i in self.extended_chars): return False return True def feed(self, data): self.data = data def read(self): if len(self.tokenized) == 0: if len(self.data) == 0: return None self.tokenized = self.data.replace('(', '( ')\ .replace(')', ' )')\ .split() self.data = "" return self.tokenized.pop(0) class AST(EvalObj): class Node(object): def __init__(self, syn_obj, sib = None, chd = None): self.obj = syn_obj self.sib = sib self.chd = chd def __str__(self): return \ "Obj: " + str(self.obj) + " " + \ "Sib: " + str(self.sib) + " " + \ "Chd: " + str(self.chd) def to_node(self, obj): if isinstance(obj, self.Node): return obj # else the obj is a string try: return self.Node(IntObj(obj)) except ValueError: try: return self.Node(FloatObj(obj)) except ValueError: return self.Node(IdObj(obj)) def __init__(self, stream): stack = list() while True: token = stream.read() if token is None: break if token == '(': stack.append(token) elif token == ')': lst = list() while stack[-1] != '(': lst = stack[-1:] + lst del stack[-1] root = self.to_node(lst[0]) if len(lst) > 1: root.chd = self.to_node(lst[1]) ref = root.chd for i in lst[2:]: ref.sib = self.to_node(i) ref = ref.sib stack[-1] = root else: stack.append(token) self.tree = stack class Environment(object): def __init__(self): self.binding = dict() def add_entry(id_obj, eval_obj): self.binding[id_obj] = eval_obj def get_obj(id_obj): return self.binding[id_obj] class Continuation(object): def __init__(self, envt, pc, old_cont): self.envt = envt self.pc = pc self.old_cont = old_cont def get_envt(self): return self.envt def get_cont(self): return self.cont class Evaluator(object): def __init__(self): self.envt = Environment() self.cont = None self.pc = None def run(self, prog): self.stack = list() # object stack self.flag = list() # call flag True for call False for value self.pc = prog # Set to the root self.top = 0 # Stack top while self.flag[0]: # Still need to evaluate pass t = Tokenizor() t.feed("(lambda (x) (x * x))") a = AST(t) root = a.tree print root.__str__()