aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTeddy <[email protected]>2013-07-30 15:53:39 +0800
committerTeddy <[email protected]>2013-07-30 15:53:39 +0800
commit7365292725c5a3130561ed03e3a53e878935daaf (patch)
tree48a4af9857407160b9159f66848614a2dda8c5ea
parent392710b213c30b6e14e6a26e5d199350209aeef9 (diff)
added if-statement
-rw-r--r--sketch.py143
1 files changed, 120 insertions, 23 deletions
diff --git a/sketch.py b/sketch.py
index a1c2a07..32cc60f 100644
--- a/sketch.py
+++ b/sketch.py
@@ -31,17 +31,73 @@ class StringObj(ValObj):
def __str__(self):
return "#<String>"
+class BoolObj(ValObj):
+ def __init__(self, b):
+ self.val = b
+ def __str__(self):
+ return "#<Boolean>"
class OptObj(EvalObj):
pass
+
class ProcObj(OptObj):
def __init__(self, prog, env = None):
self.prog = prog
self.env = env
-
def __str__(self):
return "#<Procedure>"
+class SpecialOptObj(OptObj):
+ def prepare(self, pc):
+ pass
+ def call(self, arg_list, pc, envt, cont):
+ pass
+
+class BuiltinProcObj():
+ def __init__(self, f, ext_name):
+ self.handler = f
+ self.ext_name = ext_name
+ def __str__(self):
+ return self.ext_name
+ def call(self, arg_list):
+ return self.handler(arg_list)
+
+def to_bool(obj):
+ if obj.val == False:
+ return BoolObj(False)
+ else:
+ return BoolObj(True)
+
+class _builtin_if(SpecialOptObj):
+ def prepare(self, pc):
+ self.state = 0 # prepare
+ # TODO: check number of arguments
+ return (True, False, False)
+ # Delay the calculation
+ def pre_call(self, arg_list, pc, envt, cont):
+ self.state = 1 # calling
+ print "Received if signal: " + str(arg_list[0].val)
+ print "And it is regared as: " + str(to_bool(arg_list[0]).val)
+ if (to_bool(arg_list[0])).val:
+ return ((False, True, False), True) # Re-eval
+ else:
+ return ((False, False, True), True) # Re-eval
+ def post_call(self, arg_list, pc, envt, cont):
+ return (arg_list[0], False)
+
+ def call(self, arg_list, pc, envt, cont):
+ if self.state == 0:
+ return self.pre_call(arg_list, pc, envt, cont)
+ else:
+ return self.post_call(arg_list, pc, envt, cont)
+ def __str__(self):
+ return "#<builtint opt if>"
+
+class _builtin_lambda(SpecialOptObj):
+ def prepare(self, pc):
+ # TODO: check number of arguments
+ return [ False, False ]
+
class IdObj(SyntaxObj):
def __init__(self, string):
self.name = string
@@ -82,7 +138,7 @@ class Node(object):
self.obj = syn_obj
self.sib = sib
self.chd = chd
- self.typ = None # operator operand if-macro if-clause
+ self.skip = None # delay calcuation
def __str__(self):
return "#<AST Node>"
def print_(self):
@@ -129,10 +185,14 @@ class AbsSynTree(EvalObj):
def is_identifier(string):
return isinstance(string, IdObj)
-def is_val(node):
+def is_leaf(node):
return node.chd is None
def is_ret_addr(val):
return isinstance(val, Node)
+def is_builtin_proc(val):
+ return isinstance(val, BuiltinProcObj)
+def is_special_opt(val):
+ return isinstance(val, SpecialOptObj)
class Environment(object):
def __init__(self):
@@ -179,11 +239,26 @@ def _builtin_div(arg_list):
res /= i.val
return IntObj(res)
+def _builtin_lt(arg_list):
+ #TODO: need support to multiple operands
+ return BoolObj(arg_list[0].val < arg_list[1].val)
+
+def _builtin_gt(arg_list):
+ return BoolObj(arg_list[0].val > arg_list[1].val)
+
+def _builtin_eq(arg_list):
+ return BoolObj(arg_list[0].val == arg_list[1].val)
+
_default_mapping = {
- "+" : _builtin_plus,
- "-" : _builtin_minus,
- "*" : _builtin_times,
- "/" : _builtin_div}
+ "+" : BuiltinProcObj(_builtin_plus, "builtin proc +"),
+ "-" : BuiltinProcObj(_builtin_minus, "builtin proc -"),
+ "*" : BuiltinProcObj(_builtin_times, "builtin proc *"),
+ "/" : BuiltinProcObj(_builtin_div, "builtin proc /"),
+ "<" : BuiltinProcObj(_builtin_lt, "builtin proc <"),
+ ">" : BuiltinProcObj(_builtin_gt, "builtin proc >"),
+ "=" : BuiltinProcObj(_builtin_eq, "builtin proc ="),
+ "if" : _builtin_if()
+ }
class Evaluator(object):
@@ -208,20 +283,31 @@ class Evaluator(object):
print stack[i]
print '----------STACK--------'
+ def mask_eval(pc, mask):
+ pc = pc.chd
+ for i in mask:
+ print i
+ print pc
+ pc.skip = not i
+ pc = pc.sib
+
def push(pc, top):
ntop = top
- if is_val(pc):
+ if is_leaf(pc):
ntop += 1
stack[ntop] = envt.get_obj(pc.obj)
npc = pc.sib
print "first"
- print "this val is: " + str(pc.obj)
+ print "this val is: " + str(stack[ntop].val)
else:
ntop += 1
stack[ntop] = pc # Return address
ntop += 1
stack[ntop] = envt.get_obj(pc.obj)
npc = pc.chd
+ if is_special_opt(stack[ntop]):
+ mask = stack[ntop].prepare(pc)
+ mask_eval(pc, mask)
print "second"
return (npc, ntop)
@@ -230,28 +316,38 @@ class Evaluator(object):
(pc, top) = push(pc, top)
print_stack()
print " Done...\n"
- while is_ret_addr(stack[0]): # Still need to evaluate
+ while is_ret_addr(stack[0]): # Still need to evaluate
print "- Top: " + str(stack[top])
print "- Pc at: " + str(pc)
+ while pc and pc.skip:
+ print "skipping masked branch: " + str(pc)
+ pc = pc.sib # Skip the masked branches
+
if pc is None:
print "Poping..."
arg_list = list()
while not is_ret_addr(stack[top]):
arg_list = [stack[top]] + arg_list
top -= 1
- if is_identifier(arg_list[0]):
- arg_list[0] = envt.get_obj(arg_list[0])
- pc = stack[top].sib
- stack[top] = arg_list[0](arg_list[1:])
- print_stack()
- print "RET to: "
- if pc:
- pc.print_()
- if is_identifier(pc.obj):
- print pc.obj.name
+ # Top is now pointing to the return address
+
+ opt = arg_list[0]
+ ret_addr = stack[top]
+ if is_builtin_proc(opt):
+ stack[top] = opt.call(arg_list[1:])
+ pc = ret_addr.sib
+ elif is_special_opt(opt):
+ (res, flag) = opt.call(arg_list[1:], pc, envt, cont)
+ if flag: # Need to call again
+ print "AGAIN with the mask: " + str(res)
+ mask_eval(ret_addr, res)
+ top += 1
+ pc = ret_addr.chd # Again
else:
- print pc.obj.val
- else: print "NULL"
+ stack[top] = res # Done
+ pc = ret_addr.sib
+
+ print_stack()
else:
print " Pushing..."
print_stack()
@@ -262,7 +358,8 @@ class Evaluator(object):
t = Tokenizor()
-t.feed("(+ (- (* 10 2) (+ x 4)) (+ 1 2) (/ 25 5))")
+t.feed("(if (> 2 1) 0 1)")
+#t.feed("(+ (- (* 10 2) (+ x 4)) (+ 1 2) (/ 25 5))")
#t.feed("((lambda (x) (x * x)) 2)")
a = AbsSynTree(t)
e = Evaluator()