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

jlg at codespeak.net jlg at codespeak.net
Mon Jul 30 17:13:13 CEST 2007


Author: jlg
Date: Mon Jul 30 17:13:13 2007
New Revision: 45439

Modified:
   pypy/dist/pypy/lang/scheme/execution.py
   pypy/dist/pypy/lang/scheme/object.py
   pypy/dist/pypy/lang/scheme/test/test_macro.py
Log:
Letrec, Sete, Define more macro friendly

Modified: pypy/dist/pypy/lang/scheme/execution.py
==============================================================================
--- pypy/dist/pypy/lang/scheme/execution.py	(original)
+++ pypy/dist/pypy/lang/scheme/execution.py	Mon Jul 30 17:13:13 2007
@@ -111,6 +111,10 @@
 
         raise UnboundVariable(name)
 
+    def ssete(self, symb, obj):
+        (ctx, name) = self._dispatch(symb)
+        ctx.sete(name, obj)
+
     def sete(self, name, obj):
         """update existing location or raise
         directly used by (set! <var> <expr>) macro
@@ -153,6 +157,10 @@
         else:
             self.globalscope[name] = Location(obj)
 
+    def sbind(self, symb):
+        (ctx, name) = self._dispatch(symb)
+        ctx.bind(name)
+
     def bind(self, name):
         """create new empty binding (location)"""
         if self.closure:

Modified: pypy/dist/pypy/lang/scheme/object.py
==============================================================================
--- pypy/dist/pypy/lang/scheme/object.py	(original)
+++ pypy/dist/pypy/lang/scheme/object.py	Mon Jul 30 17:13:13 2007
@@ -605,18 +605,16 @@
             ctx.set(w_name.name, w_lambda)
             return w_lambda #undefined
         else:
-            raise WrongArgType(w_first, "Identifier")
+            raise SchemeSyntaxError
 
 class Sete(W_Macro):
     def call(self, ctx, lst):
         if not isinstance(lst, W_Pair):
             raise SchemeSyntaxError
         w_identifier = lst.car
-        if not isinstance(w_identifier, W_Symbol):
-            raise WrongArgType(w_identifier, "Identifier")
 
         w_val = lst.get_cdr_as_pair().car.eval(ctx)
-        ctx.sete(w_identifier.name, w_val)
+        ctx.ssete(w_identifier, w_val)
         return w_val #undefined
 
 class MacroIf(W_Macro):
@@ -690,12 +688,14 @@
             raise SchemeSyntaxError
         local_ctx = ctx.copy()
         map_name_expr = {}
+        map_name_symb = {}
         w_formal = lst.car
         while isinstance(w_formal, W_Pair):
             w_def = w_formal.get_car_as_pair()
             name = w_def.car.to_string()
             map_name_expr[name] = w_def.get_cdr_as_pair().car
-            local_ctx.bind(name)
+            map_name_symb[name] = w_def.car
+            local_ctx.sbind(w_def.car)
             w_formal = w_formal.cdr
 
         map_name_val = {}
@@ -703,7 +703,7 @@
             map_name_val[name] = expr.eval(local_ctx)
 
         for (name, w_val) in map_name_val.items():
-            local_ctx.sete(name, w_val)
+            local_ctx.ssete(map_name_symb[name], w_val)
 
         return self.eval_body(local_ctx, lst.cdr)
 
@@ -1001,6 +1001,21 @@
     def procedure(self, ctx, lst):
         return self.expand_eval(ctx, lst[0])
 
+class W_DerivedMacro(W_Macro):
+    def __init__(self, name, transformer):
+        self.name = name
+        self.transformer = transformer
+
+    def to_string(self):
+        return "#<derived-macro %s>" % (self.name,)
+
+    def call(self, ctx, lst):
+        return self.transformer.expand_eval(ctx,
+                W_Pair(W_Symbol(self.name), lst))
+
+    def expand(self, ctx, lst):
+        return self.transformer.expand(ctx, lst)
+
 class DefineSyntax(W_Macro):
     def call(self, ctx, lst):
         if not isinstance(lst, W_Pair):
@@ -1019,21 +1034,6 @@
         ctx.set(w_def.name, w_macro)
         return w_macro #undefined
  
-class W_DerivedMacro(W_Macro):
-    def __init__(self, name, transformer):
-        self.name = name
-        self.transformer = transformer
-
-    def to_string(self):
-        return "#<derived-macro %s>" % (self.name,)
-
-    def call(self, ctx, lst):
-        return self.transformer.expand_eval(ctx,
-                W_Pair(W_Symbol(self.name), lst))
-
-    def expand(self, ctx, lst):
-        return self.transformer.expand(ctx, lst)
-
 class LetSyntax(W_Macro):
     def call_tr(self, ctx, lst):
         #let uses eval_body, so it is tail-recursive aware

Modified: pypy/dist/pypy/lang/scheme/test/test_macro.py
==============================================================================
--- pypy/dist/pypy/lang/scheme/test/test_macro.py	(original)
+++ pypy/dist/pypy/lang/scheme/test/test_macro.py	Mon Jul 30 17:13:13 2007
@@ -178,6 +178,16 @@
     eval_(ctx, "(define test 7)")
     assert w_transformer.expand_eval(ctx, w_expr).to_number() == 5
 
+    w_transformer = eval_(ctx, """(syntax-rules ()
+                                     ((shadow used-arg body)
+                                      (letrec ((used-arg 5)) body)))""")
+
+    w_expr = parse("(shadow test test)")[0]
+    assert w_transformer.expand_eval(ctx, w_expr).to_number() == 5
+
+    eval_(ctx, "(define test 7)")
+    assert w_transformer.expand_eval(ctx, w_expr).to_number() == 5
+
 def test_transformer_eval():
     ctx = ExecutionContext()
     eval_(ctx, """(define foo (syntax-rules ()
@@ -241,3 +251,12 @@
     py.test.raises(UnboundVariable, ctx.get, "foo")
     py.test.raises(UnboundVariable, ctx.get, "bar")
 
+def test_sete():
+    ctx = ExecutionContext()
+    eval_(ctx, "(define a 42)")
+    eval_(ctx, """(let-syntax ((foo (syntax-rules ()
+                                      ((foo var val) (set! var val)))))
+                      (foo a 0))""")
+
+    assert eval_(ctx, "a").to_number() == 0
+



More information about the Pypy-commit mailing list