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

jlg at codespeak.net jlg at codespeak.net
Thu Jul 5 13:59:35 CEST 2007


Author: jlg
Date: Thu Jul  5 13:59:34 2007
New Revision: 44738

Modified:
   pypy/dist/pypy/lang/scheme/object.py
   pypy/dist/pypy/lang/scheme/test/test_eval.py
Log:
lambdas body can be multiple expressions; (set! ...) added

Modified: pypy/dist/pypy/lang/scheme/object.py
==============================================================================
--- pypy/dist/pypy/lang/scheme/object.py	(original)
+++ pypy/dist/pypy/lang/scheme/object.py	Thu Jul  5 13:59:34 2007
@@ -188,7 +188,13 @@
         for (name, val) in vars:
             local_ctx.put(name, val)
 
-        return self.body.eval(local_ctx)
+        body_expression = self.body
+        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 # self.body.eval(local_ctx)
 
 ##
 # operations
@@ -234,6 +240,15 @@
         ctx.gset(w_identifier.name, w_val)
         return w_val
 
+class Sete(W_Macro):
+    def eval(self, ctx, lst):
+        w_identifier = lst.car
+        assert isinstance(w_identifier, W_Identifier)
+
+        w_val = lst.cdr.car.eval(ctx)
+        ctx.sete(w_identifier.name, w_val)
+        return w_val
+
 class MacroIf(W_Macro):
     def eval(self, ctx, lst):
         w_condition = lst.car
@@ -275,7 +290,7 @@
 class Lambda(W_Macro):
     def eval(self, ctx, lst):
         w_args = lst.car
-        w_body = lst.cdr.car
+        w_body = lst.cdr #.car
         return W_Lambda(w_args, w_body, ctx.copy())
 
 ##
@@ -305,6 +320,7 @@
         '=': Equal,
             #macros
         'define': Define,
+        'set!': Sete,
         'if': MacroIf,
         'lambda': Lambda,
     }
@@ -353,6 +369,21 @@
         else:
             self.put(name, obj)
 
+    def sete(self, name, obj):
+        """update existing location or raise"""
+        loc = self.scope.get(name, None)
+        if loc is not None:
+            loc.obj = obj
+            return obj
+
+        loc = self.globalscope.get(name, None)
+        if loc is not None:
+            loc.obj = obj
+            return obj
+
+        raise "Unbound"
+
+
     def gset(self, name, obj):
         """update existing location or create new location new"""
         loc = self.globalscope.get(name, None)

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	Thu Jul  5 13:59:34 2007
@@ -71,6 +71,13 @@
     w_num = eval_expr(ctx, "(+ 1 v1 v2)")
     assert w_num.to_number() == 46.1
 
+def test_sete():
+    ctx = ExecutionContext()
+    eval_expr(ctx, "(define x 42)")
+    eval_expr(ctx, "(set! x 43)")
+    assert ctx.get("x").to_number() == 43
+    py.test.raises("Unbound", eval_expr, ctx, "(set! y 42)")
+
 def test_func():
     ctx = ExecutionContext()
     w_func = eval_expr(ctx, "+")
@@ -215,3 +222,9 @@
     assert isinstance(w_result, W_Fixnum)
     assert w_result.to_number() == 11
 
+def test_lambda_long_body():
+    ctx = ExecutionContext()
+    eval_expr(ctx, """(define long_body (lambda () (define x 42) (+ x 1)))""")
+    w_result = eval_expr(ctx, "(long_body)")
+    assert w_result.to_number() == 43
+    #assert ctx.get("x") is None


More information about the pypy-svn mailing list