summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2018-03-21 06:20:32 -0700
committerKaz Kylheku <kaz@kylheku.com>2018-03-21 06:20:32 -0700
commit966624ec3581a75e0dc3d332ee2d5e9a0d4cf9fe (patch)
treef912167c9cd399b8ae1641f8851ea4270d1071b0
parentbea25c5395d1bffc4f671defa558510ce07670ac (diff)
downloadtxr-966624ec3581a75e0dc3d332ee2d5e9a0d4cf9fe.tar.gz
txr-966624ec3581a75e0dc3d332ee2d5e9a0d4cf9fe.tar.bz2
txr-966624ec3581a75e0dc3d332ee2d5e9a0d4cf9fe.zip
compiler: handle sys:each-op special form.
* share/txr/stdlib/compiler.tl (compiler compile): Handle sys:each-op with help of expand-each. (expand-each): New function.
-rw-r--r--share/txr/stdlib/compiler.tl21
1 files changed, 21 insertions, 0 deletions
diff --git a/share/txr/stdlib/compiler.tl b/share/txr/stdlib/compiler.tl
index ad6d886f..5fc71dfc 100644
--- a/share/txr/stdlib/compiler.tl
+++ b/share/txr/stdlib/compiler.tl
@@ -150,6 +150,7 @@
((let let*) me.(comp-let oreg env form))
(lambda me.(comp-lambda oreg env form))
(sys:for-op me.(comp-for oreg env form))
+ (sys:each-op me.(compile oreg env (expand-each form env)))
(progn me.(comp-progn oreg env (cdr form)))
(and me.(comp-and-or oreg env form))
(or me.(comp-and-or oreg env form))
@@ -643,6 +644,26 @@
(sys:setq ,val-var (cdr ,cell-var))
,*body)))))
+(defun expand-each (form env)
+ (mac-param-bind form (op each-type vars . body) form
+ (unless vars
+ (set vars [mapcar car env.vb]))
+ (let* ((gens (mapcar (ret (gensym)) vars))
+ (out (if (member each-type '(collect-each append-each))
+ (gensym)))
+ (accum (if out (gensym))))
+ ^(let* (,*(zip gens vars) ,*(if accum ^((,out (cons nil nil)) (,accum ,out))))
+ (sys:for-op ()
+ ((and ,*gens) ,*(if accum ^((cdr ,out))))
+ (,*(mapcar (ret ^(sys:setq ,@1 (cdr ,@1))) gens))
+ ,*(mapcar (ret ^(sys:setq ,@1 (car ,@2))) vars gens)
+ ,*(caseq each-type
+ (collect-each ^((rplacd ,accum (cons (progn ,*body) nil))
+ (sys:setq ,accum (cdr ,accum))))
+ (append-each ^((rplacd ,accum (progn ,*body))
+ (sys:setq ,accum (last ,accum))))
+ (t body)))))))
+
(defun usr:compile-toplevel (exp)
(let ((co (new compiler))
(as (new assembler)))