Author: Juergen Boemmels <[email protected]>
Branch:
Changeset: r30:62cfba56990c
Date: 2011-12-09 01:54 +0100
http://bitbucket.org/pypy/lang-scheme/changeset/62cfba56990c/
Log: Implement "append" & "append!"
diff --git a/scheme/procedure.py b/scheme/procedure.py
--- a/scheme/procedure.py
+++ b/scheme/procedure.py
@@ -172,6 +172,66 @@
w_pair.cdr = w_obj
return w_undefined
+class Append(W_Procedure):
+ _symbol_name = "append"
+
+ def procedure(self, ctx, lst):
+ w_lol = plst2lst(lst)
+ w_lol = Reverse().procedure(ctx,[w_lol])
+
+ w_result = w_nil
+ while w_lol is not w_nil:
+ assert isinstance(w_lol, W_Pair)
+ w_list = w_lol.car
+ w_lol = w_lol.cdr
+ if w_list is w_nil:
+ continue
+ if not isinstance(w_list, W_Pair):
+ raise WrongArgType(w_list, "List")
+ w_head = W_Pair(w_list.car, w_undefined)
+ w_tail = w_head
+ w_list = w_list.cdr
+ while w_list is not w_nil:
+ if not isinstance (w_list, W_Pair):
+ raise WrongArgType(w_list, "List")
+ assert isinstance(w_tail, W_Pair)
+ w_tail.cdr = W_Pair(w_list.car, w_undefined)
+ w_tail = w_tail.cdr
+ w_list = w_list.cdr
+
+ assert isinstance(w_tail, W_Pair)
+ w_tail.cdr = w_result
+ w_result = w_head
+
+ return w_result
+
+class AppendE(W_Procedure):
+ _symbol_name = "append!"
+
+ def procedure(self, ctx, lst):
+ if len(lst) == 0:
+ return w_nil
+
+ w_head = w_nil
+ w_prev_tail = w_nil
+ for w_list in lst:
+ if w_list is w_nil:
+ continue
+ if w_head is w_nil:
+ w_head = w_list
+ if w_prev_tail is not w_nil:
+ assert isinstance(w_prev_tail, W_Pair)
+ w_prev_tail.cdr = w_list
+ if not isinstance(w_list, W_Pair):
+ raise WrongArgType(w_list, "List")
+ while w_list.cdr is not w_nil:
+ w_list = w_list.cdr
+ if not isinstance(w_list, W_Pair):
+ raise WrongArgType(w_list, "List")
+ w_prev_tail = w_list
+
+ return w_head
+
class Apply(W_Procedure):
_symbol_name = "apply"
diff --git a/scheme/test/test_eval.py b/scheme/test/test_eval.py
--- a/scheme/test/test_eval.py
+++ b/scheme/test/test_eval.py
@@ -14,6 +14,9 @@
def eval_noctx(expr):
return parse(expr)[0].eval(ExecutionContext())
+def parse_(expr):
+ return parse(expr)[0]
+
def test_numerical():
w_num = eval_noctx("(+)")
assert w_num.to_number() == 0
@@ -802,3 +805,38 @@
py.test.raises(WrongArgsNumber, eval_, ctx, "(apply 1)")
py.test.raises(WrongArgType, eval_, ctx, "(apply 1 '(1))")
py.test.raises(WrongArgType, eval_, ctx, "(apply + 42)")
+
+def test_append():
+ ctx = ExecutionContext()
+ eval_(ctx, "(define lst-a (list 'a 'b 'c))")
+
+ w_res = eval_(ctx, "(append '(1 2 3) lst-a)")
+ assert w_res.equal(parse_("(1 2 3 a b c)"))
+
+ w_res = eval_(ctx, "(append lst-a lst-a '() '(1 2 3))")
+ w_lst_a = eval_(ctx, "lst-a")
+ assert w_res.equal(parse_("(a b c a b c 1 2 3)"))
+ assert w_lst_a.equal(parse_("(a b c)"))
+
+ w_res = eval_(ctx, "(append '(1 2 3) '(4 (5 6) 7) '(8) '((9)))")
+ assert w_res.equal(parse_("(1 2 3 4 (5 6) 7 8 (9))"))
+
+ w_res = eval_(ctx, "(append)")
+ assert w_res.eq(w_nil)
+
+ w_res = eval_(ctx, "(append!)")
+ assert w_res.eq(w_nil)
+
+ w_res = eval_(ctx, "(append! (list 1 2 3) lst-a)")
+ w_lst_a = eval_(ctx, "lst-a")
+ assert w_res.equal(parse_("(1 2 3 a b c)"))
+ assert w_lst_a.equal(parse_("(a b c)"))
+
+ w_res = eval_(ctx, "(append! lst-a '(1 2 3))")
+ w_lst_a = eval_(ctx, "lst-a")
+ assert w_res.equal(parse_("(a b c 1 2 3)"))
+ assert w_lst_a.equal(parse_("(a b c 1 2 3)"))
+
+ py.test.raises(WrongArgType, eval_, ctx, "(append 'a '())")
+ py.test.raises(WrongArgType, eval_, ctx, "(append 1 2 3)")
+ py.test.raises(WrongArgType, eval_, ctx, "(append! (cons 1 2) '(3 4))")
\ No newline at end of file
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit