[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