diff --git a/module/language/tree-il/peval.scm b/module/language/tree-il/peval.scm index 937a797f0..1eb928f07 100644 --- a/module/language/tree-il/peval.scm +++ b/module/language/tree-il/peval.scm @@ -1350,6 +1350,35 @@ top-level bindings from ENV and return the resulting expression." (make-primcall src 'apply (cons (for-value proc) args)))))))) + (($ src 'append (x z)) + (let ((x (for-value x))) + (match x + ((or ($ _ ()) + ($ _ 'list ())) + (for-value z)) + ((or ($ _ (_ . _)) + ($ _ 'cons) + ($ _ 'list)) + (for-tail + (let lp ((x x)) + (match x + ((or ($ csrc ()) + ($ csrc 'list ())) + ;; Defer visiting z in value context to for-tail. + z) + (($ csrc (x . y)) + (let ((x (make-const csrc x)) + (y (make-const csrc y))) + (make-primcall src 'cons (list x (lp y))))) + (($ csrc 'cons (x y)) + (make-primcall src 'cons (list x (lp y)))) + (($ csrc 'list (x . y)) + (let ((y (make-primcall csrc 'list y))) + (make-primcall src 'cons (list x (lp y))))) + (x (make-primcall src 'append (list x z))))))) + (else + (make-primcall src 'append (list x (for-value z))))))) + (($ src (? constructor-primitive? name) args) (cond ((and (memq ctx '(effect test)) diff --git a/module/language/tree-il/primitives.scm b/module/language/tree-il/primitives.scm index 153c602b2..dd5592a41 100644 --- a/module/language/tree-il/primitives.scm +++ b/module/language/tree-il/primitives.scm @@ -69,7 +69,7 @@ integer->char char->integer number->string string->number - acons cons cons* + acons cons cons* append list vector @@ -147,7 +147,7 @@ (define *primitive-constructors* ;; Primitives that return a fresh object. - '(acons cons cons* list vector make-vector + '(acons cons cons* append list vector make-vector make-struct/simple make-prompt-tag make-variable)) @@ -563,6 +563,12 @@ (x y) (cons x y) (x y . rest) (cons x (cons* y . rest))) +(define-primitive-expander append + () '() + (x) (values x) + (x y) (append x y) + (x y . rest) (append x (append y . rest))) + (define-primitive-expander acons (x y z) (cons (cons x y) z)) diff --git a/test-suite/tests/peval.test b/test-suite/tests/peval.test index bed2e2dc4..c96cfac21 100644 --- a/test-suite/tests/peval.test +++ b/test-suite/tests/peval.test @@ -1588,5 +1588,26 @@ (pass-if-peval (begin (cons 1 (values)) #f) (seq (primcall values (primcall values)) (const #f))) + (pass-if-peval (begin 1 (values) #f) (const #f))) + +(with-test-prefix "append" + (pass-if-peval (append '() 42) + (const 42)) + + (pass-if-peval (append '(1 2) 42) + (primcall cons (const 1) + (primcall cons (const 2) (const 42)))) + + (pass-if-peval (append (list 1 2) 42) + (primcall cons (const 1) + (primcall cons (const 2) (const 42)))) + + (pass-if-peval (append (cons* 1 2 '()) 42) + (primcall cons (const 1) + (primcall cons (const 2) (const 42)))) + + (pass-if-peval (append (cons 1 2) 42) + (primcall cons (const 1) + (primcall append (const 2) (const 42)))))