[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