[pypy-svn] r45578 - in pypy/dist/pypy/lang/scheme: . test

jlg at codespeak.net jlg at codespeak.net
Thu Aug 9 20:53:31 CEST 2007


Author: jlg
Date: Thu Aug  9 20:53:30 2007
New Revision: 45578

Modified:
   pypy/dist/pypy/lang/scheme/interactive.py
   pypy/dist/pypy/lang/scheme/object.py
   pypy/dist/pypy/lang/scheme/test/test_continuation.py
Log:
W_Eval is base class for objects which are not evaluating to self; eval_cf evals object and create continuation frame for it; interactive interpreter handles ContinuationReturn

Modified: pypy/dist/pypy/lang/scheme/interactive.py
==============================================================================
--- pypy/dist/pypy/lang/scheme/interactive.py	(original)
+++ pypy/dist/pypy/lang/scheme/interactive.py	Thu Aug  9 20:53:30 2007
@@ -3,7 +3,8 @@
 scheme interpreter
 """
 import autopath
-from pypy.lang.scheme.object import SchemeException, SchemeQuit
+from pypy.lang.scheme.object import SchemeException, SchemeQuit,\
+        ContinuationReturn
 from pypy.lang.scheme.execution import ExecutionContext
 from pypy.lang.scheme.ssparser import parse
 from pypy.rlib.parsing.makepackrat import BacktrackException
@@ -34,10 +35,12 @@
                 print parse(to_exec)[0].eval(ctx).to_string()
             except SchemeQuit, e:
                 break
-            except BacktrackException, e:
-                print "syntax error"
+            except ContinuationReturn, e:
+                print e.result.to_string()
             except SchemeException, e:
                 print "error: %s" % e
+            except BacktrackException, e:
+                print "syntax error"
 
             to_exec = ""
             cont = False

Modified: pypy/dist/pypy/lang/scheme/object.py
==============================================================================
--- pypy/dist/pypy/lang/scheme/object.py	(original)
+++ pypy/dist/pypy/lang/scheme/object.py	Thu Aug  9 20:53:30 2007
@@ -40,6 +40,9 @@
     def __repr__(self):
         return "<W_Root " + self.to_string() + ">"
 
+    def eval_cf(self, ctx, caller, cont, elst=[]):
+        return self.eval(ctx)
+
     def eval(self, ctx):
         w_expr = self
         while ctx is not None:
@@ -171,13 +174,37 @@
     def to_float(self):
         return float(self.intval)
 
-class W_List(W_Root):
+class W_Eval(W_Root):
+    #this class is for objects which does more than
+    # evaluate to themselves
+    def eval_cf(self, ctx, caller, cont, elst=[]):
+        #eval with continuation frame!
+        ctx.cont_stack.append(ContinuationFrame(caller, cont, elst))
+        result = self.eval(ctx)
+        ctx.cont_stack.pop()
+        return result
+
+    def continue_tr(self, ctx, lst, elst, cnt=True):
+        raise NotImplementedError
+
+class W_List(W_Eval):
     pass
 
 class W_Nil(W_List):
+    def __repr__(self):
+        return "<W_Nil ()>"
+
     def to_string(self):
         return "()"
 
+    def eval_cf(self, ctx, caller, cont, elst=[]):
+        #XXX not tests here
+        raise SchemeSyntaxError
+
+    def eval_tr(self, ctx):
+        #XXX not tests here
+        raise SchemeSyntaxError
+
 w_nil = W_Nil()
 
 class W_Pair(W_List):
@@ -233,9 +260,7 @@
         return cont.run(ctx, result)
 
     def eval_tr(self, ctx):
-        ctx.cont_stack.append(ContinuationFrame(self, self.cdr))
-        oper = self.car.eval(ctx)
-        ctx.cont_stack.pop()
+        oper = self.car.eval_cf(ctx, self, self.cdr)
         if not isinstance(oper, W_Callable):
             raise NotCallable(oper)
 
@@ -259,7 +284,7 @@
             raise SchemeSyntaxError
         return res
 
-class W_Callable(W_Root):
+class W_Callable(W_Eval):
     def call_tr(self, ctx, lst):
         #usually tail-recursive call is normal call
         # which returns tuple with no further ExecutionContext
@@ -268,7 +293,7 @@
     def call(self, ctx, lst):
         raise NotImplementedError
 
-class Body(W_Root):
+class Body(W_Eval):
     def __init__(self, body):
         self.body = body
 
@@ -294,10 +319,7 @@
                 return cont.run(ctx, result)
 
             else:
-                ctx.cont_stack.append(
-                        ContinuationFrame(self, body_expression.cdr))
-                body_expression.car.eval(ctx)
-                ctx.cont_stack.pop()
+                body_expression.car.eval_cf(ctx, self, body_expression.cdr)
 
             body_expression = body_expression.cdr
 
@@ -324,9 +346,7 @@
             #  - arg (W_Pair) = arg.cdr as a pointer to not evaluated
             #    arguments
             #  - actual context
-            ctx.cont_stack.append(ContinuationFrame(self, arg.cdr, arg_lst))
-            w_obj = arg.car.eval(ctx)
-            ctx.cont_stack.pop()
+            w_obj = arg.car.eval_cf(ctx, self, arg.cdr, arg_lst)
 
             arg_lst.append(w_obj)
             arg = arg.cdr

Modified: pypy/dist/pypy/lang/scheme/test/test_continuation.py
==============================================================================
--- pypy/dist/pypy/lang/scheme/test/test_continuation.py	(original)
+++ pypy/dist/pypy/lang/scheme/test/test_continuation.py	Thu Aug  9 20:53:30 2007
@@ -9,21 +9,6 @@
     except ContinuationReturn, e:
         return e.result
 
-def test_callcc_callcc():
-    ctx = ExecutionContext()
-    w_procedure = eval_(ctx, "(call/cc call/cc)")
-    assert isinstance(w_procedure, W_Procedure)
-    print w_procedure
-
-    eval_(ctx, "(define cont 'none)")
-    w_result = eval_(ctx, """((call/cc call/cc) (lambda (k)
-                                                     (set! cont k)
-                                                     'done))""")
-    assert w_result.to_string() == "done"
-    assert isinstance(eval_(ctx, "cont"), W_Procedure)
-    eval_(ctx, "(cont +)")
-    assert eval_(ctx, "cont") is ctx.get("+")
-
 def test_callcc():
     ctx = ExecutionContext()
 
@@ -41,6 +26,21 @@
     w_result = eval_(ctx, "(+ 1 (cont #t))")
     assert w_result.to_boolean() is True
 
+def test_callcc_callcc():
+    ctx = ExecutionContext()
+    w_procedure = eval_(ctx, "(call/cc call/cc)")
+    assert isinstance(w_procedure, W_Procedure)
+    print w_procedure
+
+    eval_(ctx, "(define cont 'none)")
+    w_result = eval_(ctx, """((call/cc call/cc) (lambda (k)
+                                                     (set! cont k)
+                                                     'done))""")
+    assert w_result.to_string() == "done"
+    assert isinstance(eval_(ctx, "cont"), W_Procedure)
+    eval_(ctx, "(cont +)")
+    assert eval_(ctx, "cont") is ctx.get("+")
+
 def test_simple_multi_shot():
     ctx = ExecutionContext()
 



More information about the Pypy-commit mailing list