diff options
Diffstat (limited to 'sketch.py')
-rw-r--r-- | sketch.py | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/sketch.py b/sketch.py new file mode 100644 index 0000000..edd866c --- /dev/null +++ b/sketch.py @@ -0,0 +1,157 @@ +class SyntaxObj(object): + pass + +class EvalObj(SyntaxObj): + def __str__(self): + return "#<Object>" + +class ValObj(EvalObj): + def __str__(self): + return "#<Value>" + +class NumberObj(ValObj): + def __str__(): + return "#<Number>" + +class IntObj(NumberObj): + def __init__(self, num): + self.val = int(num) + def __str__(): + return "#<Integer>" + +class FloatObj(NumberObj): + def __init__(self, num): + self.val = float(num) + def __str__(): + return "#<Float>" + +class StringObj(ValObj): + def __init__(self, string): + self.val = string + + def __str__(): + return "#<String>" + +class ProcObj(ValObj): + def __init__(self, env, prog): + self.val = proc + + def __str__(): + return "#<Procedure>" + +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__() |