aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTeddy <ted.sybil@gmail.com>2013-07-30 21:58:22 +0800
committerTeddy <ted.sybil@gmail.com>2013-07-30 21:58:22 +0800
commit4df0b2a8c8e04b6d6006e7becbb7027e387ba00a (patch)
tree987fdeb2571edeac972e506ad095d98de7316b73
parent508d9a6b5fc4143d160ecd9cb5c47ff543bb14f0 (diff)
added lambda-statement
-rw-r--r--sketch.py68
1 files changed, 47 insertions, 21 deletions
diff --git a/sketch.py b/sketch.py
index a1d03cf..e733e9e 100644
--- a/sketch.py
+++ b/sketch.py
@@ -109,6 +109,7 @@ class _builtin_lambda(SpecialOptObj):
para_list.append(par.obj)
par = par.sib
body = pc.chd.sib
+ pc.chd.skip = body.skip = False
return (ProcObj(body, envt, para_list), False)
def __str__(self):
return "#<builtin opt lambda>"
@@ -218,6 +219,8 @@ class AbsSynTree(EvalObj):
self.tree = stack[0]
+def is_obj(string):
+ return isinstance(string, SyntaxObj)
def is_identifier(string):
return isinstance(string, IdObj)
def is_leaf(node):
@@ -239,7 +242,16 @@ class Environment(object):
self.binding[name] = eval_obj
def get_obj(self, id_obj):
if is_identifier(id_obj):
- return self.binding[id_obj.name]
+ ptr = self
+ while ptr:
+ try:
+ t = ptr.binding[id_obj.name]
+ except KeyError:
+ t = None
+ if t: return t
+ ptr = ptr.prev_envt
+ raise KeyError
+
else:
print "Not an id: " + str(id_obj)
return id_obj
@@ -313,7 +325,7 @@ class Evaluator(object):
stack = [0] * 100 # Stack
ostack = [0] * 100 # Pending operators
pc = prog.tree # Set to the root
- cont = None
+ cont = Continuation(None, pc, None)
envt = self.envt
top = -1 # Stack top
otop = -1
@@ -333,6 +345,17 @@ class Evaluator(object):
pc.skip = not i
pc = pc.sib
+ def nxt_addr(ret_addr, otop):
+ notop = otop
+ if otop > -1 and ret_addr is ostack[notop]:
+ notop -= 1
+ res = ostack[notop].chd
+ notop -= 1
+ else:
+ res = ret_addr.sib
+ return (res, notop)
+
+
def push(pc, top, otop):
ntop = top
notop = otop
@@ -357,7 +380,7 @@ class Evaluator(object):
pc.obj.print_() # Step in to resolve operator
npc = pc.obj
else:
- print "Getting operand: "
+ print "Getting operand: " + str(pc.obj.name)
ntop += 1
stack[ntop] = envt.get_obj(pc.obj)
if is_special_opt(stack[ntop]):
@@ -379,7 +402,17 @@ class Evaluator(object):
pc = pc.sib # Skip the masked branches
if pc is None:
- if is_ret_addr(stack[top]):
+
+ if top > 0 and is_ret_addr(stack[top - 1]) and \
+ stack[top - 1].get_addr() is False:
+ stack[top - 1] = stack[top]
+ top -= 1
+ envt = cont.envt
+ (pc, otop) = nxt_addr(cont.pc, otop)
+ cont = cont.old_cont
+ # Revert to the original cont.
+ else:
+
print "Poping..."
arg_list = list()
while not is_ret_addr(stack[top]):
@@ -389,19 +422,12 @@ class Evaluator(object):
print "Arg List: " + str(arg_list)
opt = arg_list[0]
ret_addr = stack[top].get_addr()
- if ret_addr is ostack[otop]:
- print "yay!"
- otop -= 1
- nxt_addr = ostack[otop].chd
- otop -= 1
- else:
- nxt_addr = ret_addr.sib
-
+
if is_builtin_proc(opt): # Built-in Procedures
print "builtin"
stack[top] = opt.call(arg_list[1:])
- pc = nxt_addr
-
+ (pc, otop) = nxt_addr(ret_addr, otop)
+
elif is_special_opt(opt): # Sepecial Operations
print "specialopt"
(res, flag) = opt.call(arg_list[1:], ret_addr, envt, cont)
@@ -412,16 +438,16 @@ class Evaluator(object):
pc = ret_addr.chd # Again
else:
stack[top] = res # Done
- pc = nxt_addr
+ (pc, otop) = nxt_addr(ret_addr, otop)
elif is_user_defined_proc(opt): # User-defined Procedures
- print "body:" + str(opt.body.sib)
- ncont = Continuation(evnt, ret_addr, cont) # Create a new continuation
+ ncont = Continuation(envt, ret_addr, cont) # Create a new continuation
cont = ncont # Make chain
envt = Environment(opt.envt) # New ENV and recover the closure
#TODO: Compare the arguments to the parameters
for i in xrange(1, len(arg_list)):
- envt.add_binding(para_list[i - 1].name,
+ envt.add_binding(opt.para_list[i - 1].name,
arg_list[i]) # Create bindings
+ stack[top] = RetAddr(False) # Mark the exit of the continuation
pc = opt.body # Get to the entry point
print_stack()
@@ -434,14 +460,14 @@ class Evaluator(object):
print " Done...\n"
return stack[0]
-
+import pdb
t = Tokenizor()
e = Evaluator()
e.envt.add_binding("x", IntObj(100))
#t.feed("(+ (- (* 10 2) (+ x 4)) (+ 1 2) (/ 25 5))")
#t.feed("(if (> 2 2) (if (> 2 1) 1 2) 3)")
-t.feed("((lambda (x) (* x x)) 2)")
-#t.feed("(lambda (x) (* x x))")
+t.feed("((lambda (x y) ((lambda (z) (+ z (* x y))) 10)) ((lambda (x y) (+ x y)) 3 2) 4)")
+#t.feed("(lambda (x y) (* x x))")
a = AbsSynTree(t)
#a.tree.print_()
#a.tree.obj.print_()