[pypy-commit] lang-scheme default: Implement map & reverse

boemmels noreply at buildbot.pypy.org
Mon Nov 28 00:38:31 CET 2011


Author: Juergen Boemmels <boemmels at web.de>
Branch: 
Changeset: r19:e51d0791d96d
Date: 2011-11-27 22:49 +0100
http://bitbucket.org/pypy/lang-scheme/changeset/e51d0791d96d/

Log:	Implement map & reverse

diff --git a/scheme/procedure.py b/scheme/procedure.py
--- a/scheme/procedure.py
+++ b/scheme/procedure.py
@@ -207,6 +207,61 @@
 
         return w_promise.force(ctx)
 
+class Reverse(W_Procedure):
+    _symbol_name = "reverse"
+
+    def procedure(self, ctx, lst):
+        if len(lst) != 1:
+            raise WrongArgsNumber
+        w_inlist = lst[0]
+        w_outlist = w_nil
+        while w_inlist is not w_nil:
+            if not isinstance(w_inlist, W_Pair):
+                raise WrongArgType(lst[0], "List")
+            w_outlist = W_Pair(w_inlist.car, w_outlist)
+            w_inlist = w_inlist.cdr
+
+        return w_outlist
+
+class Map(W_Procedure):
+    _symbol_name = "map"
+
+    def procedure_tr(self, ctx, lst):
+        if len(lst) < 2:
+            raise WrongArgsNumber
+
+        w_proc = lst[0]
+        if not isinstance(w_proc, W_Procedure):
+            raise WrongArgType(w_proc, "Procedure")
+        
+        args_pending = lst[1:]
+        args_len = len(args_pending)
+        args_current = [None] * args_len
+        w_rev_result = w_nil
+        finished = False
+        while True:
+            for i in range(args_len):
+                w_item = args_pending[i]
+                if w_item is w_nil:
+                    finished = True
+                    break
+                elif not isinstance(w_item, W_Pair):
+                    raise WrongArgType(lst[i+1], "List")
+                args_current[i]= w_item.car
+                args_pending[i]= w_item.cdr
+
+            if finished:
+                break
+
+            (w_call_res, iter_ctx) = w_proc.procedure_tr(ctx, args_current)
+            while iter_ctx is not None:
+                (w_call_res, iter_ctx) = w_call_res.eval_tr(iter_ctx)
+
+            w_rev_result = W_Pair(w_call_res, w_rev_result)
+
+        # XXX need to find out how to do this tailrecusive
+        return (Reverse().procedure(ctx,[w_rev_result]), None)
+
 ##
 # Equivalnece Predicates
 ##
diff --git a/scheme/test/test_scheme_level.py b/scheme/test/test_scheme_level.py
--- a/scheme/test/test_scheme_level.py
+++ b/scheme/test/test_scheme_level.py
@@ -53,10 +53,6 @@
 )
 (assert (eqv? (fac 1) 1))
 (assert (eqv? (fac 5) 120))
-""")
-
-def test_fac_with_acc():
-    run_with_assert(r"""
 (define (fac n)
   (define (fac-acc n acc)
     (if (eqv? n 0)
@@ -69,3 +65,23 @@
 (assert (eqv? (fac 1) 1))
 (assert (eqv? (fac 5) 120))
 """)
+
+def test_map():
+    run_with_assert(r"""
+(assert (equal?
+  (map + '(1 2 3) '(4 5 6))
+  '(5 7 9)
+))
+(assert (equal?
+  (map (lambda (n) (+ n 1)) '(1 2 3 4))
+  '(2 3 4 5)
+))
+(assert (equal?
+  (map * '(1 2 3 4 5) '(1 2 3))
+  '(1 4 9)
+))
+(assert (eq?
+  (map (lambda (n) (assert #f "should not be reached")) '())
+  '()
+))
+""")


More information about the pypy-commit mailing list