[pypy-svn] r45459 - in pypy/dist/pypy/lang/scheme: . test
jlg at codespeak.net
jlg at codespeak.net
Thu Aug 2 17:30:48 CEST 2007
Author: jlg
Date: Thu Aug 2 17:30:47 2007
New Revision: 45459
Modified:
pypy/dist/pypy/lang/scheme/object.py
pypy/dist/pypy/lang/scheme/test/test_macro.py
Log:
more on macros and ellipses; W_Transformer.substitute changes
Modified: pypy/dist/pypy/lang/scheme/object.py
==============================================================================
--- pypy/dist/pypy/lang/scheme/object.py (original)
+++ pypy/dist/pypy/lang/scheme/object.py Thu Aug 2 17:30:47 2007
@@ -866,8 +866,8 @@
self.mdict_lst = mdict_lst
class EllipsisException(SchemeException):
- def __init__(self, ellipsis):
- self.mdict_lst = ellipsis.mdict_lst
+ def __init__(self, length):
+ self.length = length
class EllipsisPattern(SchemeException):
pass
@@ -897,8 +897,8 @@
mdict_car = self.matchr(ctx, w_pattcar, w_expr.car)
try:
- #we catch EllipsisPattern here because in car
- # we dont know how to deal with it
+ #we catch EllipsisPattern here because in car
+ # we dont know how to deal with it
mdict_cdr = self.matchr(ctx, w_patt.cdr, w_expr.cdr)
except EllipsisPattern:
print "ellipsis matched", w_patt, w_expr
@@ -1007,13 +1007,22 @@
return self.substitute(ctx, template, match_dict)
- def substitute(self, ctx, sexpr, match_dict):
+ def substitute(self, ctx, sexpr, match_dict, ellipsis_cnt=-1):
if isinstance(sexpr, W_Symbol):
w_sub = match_dict.get(sexpr.name, None)
if w_sub is not None:
# Hygenic macros close their input forms in the syntactic
# enviroment at the point of use
+ if isinstance(w_sub, Ellipsis):
+ if ellipsis_cnt < 0:
+ raise EllipsisException(len(w_sub.mdict_lst))
+ else:
+ mdict = w_sub.mdict_lst[ellipsis_cnt]
+ w_sub = mdict[sexpr.name]
+ #for nested ellipsis we should probably raise
+ # here if w_sub is still Ellipsis
+
#not always needed, because w_sub can have no W_Symbol inside
if isinstance(w_sub, W_Symbol) and \
not isinstance(w_sub, SymbolClosure):
@@ -1023,30 +1032,24 @@
not isinstance(w_sub, PairClosure):
return PairClosure(ctx, w_sub)
- if isinstance(w_sub, Ellipsis):
- raise EllipsisException(w_sub)
-
return w_sub
return sexpr
elif isinstance(sexpr, W_Pair):
try:
- w_pair = W_Pair(self.substitute(ctx, sexpr.car, match_dict),
- self.substitute(ctx, sexpr.cdr, match_dict))
+ w_pair = W_Pair(
+ self.substitute(ctx, sexpr.car, match_dict, ellipsis_cnt),
+ self.substitute(ctx, sexpr.cdr, match_dict, ellipsis_cnt))
except EllipsisException, e:
scdr = sexpr.cdr
- print ">", sexpr, e.mdict_lst
if isinstance(scdr, W_Pair) and scdr.car is w_ellipsis:
- print ">>", sexpr, e.mdict_lst
-
plst = []
- for mdict in e.mdict_lst:
- zzz = self.substitute(ctx, sexpr.car, mdict)
+ for i in range(e.length):
+ zzz = self.substitute(ctx, sexpr.car, match_dict, i)
plst.append(zzz)
ellipsis = plst2lst(plst)
- print ellipsis
return ellipsis
else:
raise e
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 Thu Aug 2 17:30:47 2007
@@ -353,3 +353,50 @@
(set! z 1)
(+ x y z))""").to_number() == 3
+def test_ellipsis_mixed():
+ ctx = ExecutionContext()
+ eval_(ctx, """(define-syntax set-if-true
+ (syntax-rules ()
+ ((_ (sym val) ...)
+ (begin
+ (if sym (set! sym val)) ...))))""")
+
+ eval_(ctx, "(define x #t)")
+ eval_(ctx, "(define y #f)")
+ eval_(ctx, "(define z #t)")
+ eval_(ctx, "(set-if-true (x 1) (y 2) (z 3))")
+ assert eval_(ctx, "x").to_number() == 1
+ assert eval_(ctx, "y").to_boolean() is False
+ assert eval_(ctx, "z").to_number() == 3
+
+def test_ellipsis_wo_ellipsis():
+ ctx = ExecutionContext()
+ eval_(ctx, """(define-syntax let-default
+ (syntax-rules ()
+ ((_ (sym ...) val body ...)
+ (let ((sym val) ...) body ...))))""")
+
+ assert eval_(ctx, "(let-default (x y z) 1 (+ x y z))").to_number() == 3
+
+def test_different_ellipsis():
+ ctx = ExecutionContext()
+ eval_(ctx, """(define-syntax let2
+ (syntax-rules ()
+ ((_ (sym ...) (val ...) body ...)
+ (let ((sym val) ...) body ...))))""")
+
+ assert eval_(ctx, "(let2 (x y z) (1 2 3) (+ x y z))").to_number() == 6
+
+def test_nested_ellipsis():
+ py.test.skip("in progress")
+ ctx = ExecutionContext()
+ eval_(ctx, """(define-syntax quote-append
+ (syntax-rules ()
+ ((_ (obj ...) ...)
+ (quote (obj ... ...)))))""")
+
+ assert eval_(ctx, """(quote-append (x y)
+ (1 2 3 4)
+ (+))""").to_string() == \
+ "(x y 1 2 3 4 +)"
+
More information about the pypy-svn
mailing list