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

jlg at codespeak.net jlg at codespeak.net
Wed Jul 18 14:50:05 CEST 2007


Author: jlg
Date: Wed Jul 18 14:50:04 2007
New Revision: 45182

Modified:
   pypy/dist/pypy/lang/scheme/execution.py
   pypy/dist/pypy/lang/scheme/object.py
   pypy/dist/pypy/lang/scheme/test/test_eval.py
Log:
quasiquote and unqoute take 1

Modified: pypy/dist/pypy/lang/scheme/execution.py
==============================================================================
--- pypy/dist/pypy/lang/scheme/execution.py	(original)
+++ pypy/dist/pypy/lang/scheme/execution.py	Wed Jul 18 14:50:04 2007
@@ -50,6 +50,7 @@
         'let*': LetStar,
         'letrec': Letrec,
         'quote': Quote,
+        'quasiquote': QuasiQuote,
     }
 
 OPERATION_MAP = {}

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 18 14:50:04 2007
@@ -698,6 +698,43 @@
 
         return lst.car
 
+class QuasiQuote(W_Macro):
+    def call(self, ctx, lst):
+        if not isinstance(lst, W_Pair):
+            raise SchemeSyntaxError
+
+        w_lst = self.unquote(ctx, lst.car, 1)
+        return w_lst
+
+    def unquote(self, ctx, w_lst, deep):
+        if deep < 1:
+            raise SchemeSyntaxError
+
+        if isinstance(w_lst, W_Pair):
+            w_car = w_lst.car
+            if isinstance(w_car, W_Identifier):
+                if w_car.to_string() == "unquote":
+                    if deep == 1:
+                        return w_lst.get_cdr_as_pair().car.eval(ctx)
+
+                    if deep > 1:
+                        w_unq = self.unquote(ctx,
+                                w_lst.get_cdr_as_pair().car,
+                                deep-1)
+
+                        return W_Pair(w_car, W_Pair(w_unq, W_Nil()))
+
+                if w_car.to_string() == "quasiquote":
+                    w_unq = self.unquote(ctx,
+                            w_lst.get_cdr_as_pair().car,
+                            deep+1)
+                    return W_Pair(w_car, W_Pair(w_unq, W_Nil()))
+
+            return W_Pair(self.unquote(ctx, w_car, deep),
+                    self.unquote(ctx, w_lst.cdr, deep))
+
+        return w_lst
+
 class Delay(W_Macro):
     def call(self, ctx, lst):
         if not isinstance(lst, W_Pair):

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 18 14:50:04 2007
@@ -570,3 +570,38 @@
     w_lst = eval_expr(ctx, "lst")
     assert w_lst is eval_expr(ctx, "(cdr (cdr (cdr lst)))")
 
+def test_quasiquote():
+    w_res = eval_noctx("(quasiquote (list (unquote (+ 1 2)) 4))")
+    assert w_res.to_string() == "(list 3 4)"
+
+    w_res = eval_noctx("""
+                (let ((name 'a))
+                    (quasiquote (list (unquote name)
+                                      (quote (unquote name)))))""")
+    assert w_res.to_string() == "(list a (quote a))"
+
+def test_quasiquote_nested():
+    w_res = eval_noctx("""
+                (quasiquote
+                    (a (quasiquote
+                           (b (unquote (+ 1 2))
+                              (unquote (foo
+                                       (unquote (+ 1 3))
+                                       d))
+                                e))
+                            f))""")
+    assert w_res.to_string() == \
+            "(a (quasiquote (b (unquote (+ 1 2)) (unquote (foo 4 d)) e)) f)"
+
+    w_res = eval_noctx("""
+                (let ((name1 'x)
+                      (name2 'y))
+                    (quasiquote (a
+                                (quasiquote (b
+                                             (unquote (unquote name1))
+                                             (unquote (quote
+                                                        (unquote name2)))
+                                             d))
+                                 e)))""")
+    assert w_res.to_string() == "(a (quasiquote (b (unquote x) (unquote (quote y)) d)) e)"
+



More information about the Pypy-commit mailing list