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

jlg at codespeak.net jlg at codespeak.net
Wed Jul 11 12:35:36 CEST 2007


Author: jlg
Date: Wed Jul 11 12:35:35 2007
New Revision: 44922

Modified:
   pypy/dist/pypy/lang/scheme/interactive.py
   pypy/dist/pypy/lang/scheme/object.py
   pypy/dist/pypy/lang/scheme/test/test_eval.py
   pypy/dist/pypy/lang/scheme/test/test_interactive.py
Log:


Modified: pypy/dist/pypy/lang/scheme/interactive.py
==============================================================================
--- pypy/dist/pypy/lang/scheme/interactive.py	(original)
+++ pypy/dist/pypy/lang/scheme/interactive.py	Wed Jul 11 12:35:35 2007
@@ -5,6 +5,7 @@
 import autopath
 from pypy.lang.scheme.object import ExecutionContext, SchemeException
 from pypy.lang.scheme.ssparser import parse
+from pypy.rlib.parsing.makepackrat import BacktrackException
 import os, sys
 
 def check_parens(s):
@@ -27,6 +28,9 @@
                 print parse(to_exec).eval(ctx)
             except SchemeException, e:
                 print "error: %s" % e
+            except BacktrackException, e:
+                print "syntax error"
+
             to_exec = ""
             cont = False
         else:

Modified: pypy/dist/pypy/lang/scheme/object.py
==============================================================================
--- pypy/dist/pypy/lang/scheme/object.py	(original)
+++ pypy/dist/pypy/lang/scheme/object.py	Wed Jul 11 12:35:35 2007
@@ -6,7 +6,7 @@
 class UnboundVariable(SchemeException):
     def __str__(self):
         return "Unbound variable %s" % self.args[0]
-        
+
 class W_Root(object):
     def to_string(self):
         return ''
@@ -15,7 +15,7 @@
         return True
 
     def __str__(self):
-        return self.to_string() + "W"
+        return self.to_string()
 
     def __repr__(self):
         return "<W_Root " + self.to_string() + ">"
@@ -319,7 +319,7 @@
         return W_Lambda(w_args, w_body, ctx.copy())
 
 class Let(W_Macro):
-    def eval(slef, ctx, lst):
+    def eval(self, ctx, lst):
         local_ctx = ctx.copy()
         w_formal = lst.car
         while not isinstance(w_formal, W_Nil):
@@ -337,6 +337,32 @@
 
         return body_result
 
+class Letrec(W_Macro):
+    def eval(self, ctx, lst):
+        local_ctx = ctx.copy()
+
+        #bound variables
+        w_formal = lst.car
+        while not isinstance(w_formal, W_Nil):
+            name = w_formal.car.car.to_string()
+            local_ctx.put(name, W_Nil())
+            w_formal = w_formal.cdr
+
+        #eval in local_ctx and assign values 
+        w_formal = lst.car
+        while not isinstance(w_formal, W_Nil):
+            name = w_formal.car.car.to_string()
+            val = w_formal.car.cdr.car.eval(local_ctx)
+            local_ctx.set(name, val)
+            w_formal = w_formal.cdr
+
+        body_expression = lst.cdr
+        body_result = None
+        while not isinstance(body_expression, W_Nil):
+            body_result = body_expression.car.eval(local_ctx)
+            body_expression = body_expression.cdr
+
+        return body_result
 
 def Literal(sexpr):
     return W_Pair(W_Identifier('quote'), W_Pair(sexpr, W_Nil()))
@@ -377,6 +403,7 @@
         'if': MacroIf,
         'lambda': Lambda,
         'let': Let,
+        'letrec': Letrec,
         'quote': Quote,
     }
 

Modified: pypy/dist/pypy/lang/scheme/test/test_eval.py
==============================================================================
--- pypy/dist/pypy/lang/scheme/test/test_eval.py	(original)
+++ pypy/dist/pypy/lang/scheme/test/test_eval.py	Wed Jul 11 12:35:35 2007
@@ -68,6 +68,10 @@
     w_num = eval_expr(ctx, "(+ 1 v1 v2)")
     assert w_num.to_number() == 46.1
 
+def text_unbound():
+    ctx = ExecutionContext()
+    py.test.raises(UnboundVariable, eval_expr, ctx, "y")
+
 def test_sete():
     ctx = ExecutionContext()
     eval_expr(ctx, "(define x 42)")
@@ -323,3 +327,18 @@
     assert w_result.to_number() == 44
     assert ctx.get("var") is w_global
 
+def test_letrec():
+    ctx = ExecutionContext()
+    w_result = eval_expr(ctx, """
+        (letrec ((even?
+                    (lambda (n)
+                        (if (= n 0)
+                            #t
+                            (odd? (- n 1)))))
+                 (odd?
+                    (lambda (n)
+                        (if (= n 0)
+                            #f
+                            (even? (- n 1))))))
+                (even? 12))""")
+    assert w_result.to_boolean() is True

Modified: pypy/dist/pypy/lang/scheme/test/test_interactive.py
==============================================================================
--- pypy/dist/pypy/lang/scheme/test/test_interactive.py	(original)
+++ pypy/dist/pypy/lang/scheme/test/test_interactive.py	Wed Jul 11 12:35:35 2007
@@ -1,4 +1,3 @@
-
 from pypy.lang.scheme.interactive import check_parens
 import py
 import re
@@ -44,3 +43,11 @@
         child.sendline("x")
         child.expect("Unbound variable x")
         child.expect("-> ")
+
+    def test_syntax_error(self):
+        clild = self.spawn()
+        child.expect("-> ")
+        child.sendline("))((")
+        child.expect("syntax error")
+        child.expect("-> ")
+



More information about the Pypy-commit mailing list