summaryrefslogtreecommitdiffstats
path: root/share
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2018-04-14 23:18:29 -0700
committerKaz Kylheku <kaz@kylheku.com>2018-04-14 23:18:29 -0700
commita9cf6dcdda37230356d39ffaa3754aea4334f8ae (patch)
treeec67466e7904f21784dec812a77cf9a9f5a62c27 /share
parentce51feaa6f783cea151bdc0b542a8733cce2c245 (diff)
downloadtxr-a9cf6dcdda37230356d39ffaa3754aea4334f8ae.tar.gz
txr-a9cf6dcdda37230356d39ffaa3754aea4334f8ae.tar.bz2
txr-a9cf6dcdda37230356d39ffaa3754aea4334f8ae.zip
compiler: move lambda param parsing into struct.
* share/txr/stdlib/compiler.tl (param-parser-base, fun-param-parser, mac-param-parser): New structs. (compiler comp-lambda): Construct a fun-param-parser object using parameter syntax. Then just extract the parsed pieces for further processing.
Diffstat (limited to 'share')
-rw-r--r--share/txr/stdlib/compiler.tl201
1 files changed, 116 insertions, 85 deletions
diff --git a/share/txr/stdlib/compiler.tl b/share/txr/stdlib/compiler.tl
index ab65f46a..c4a1a849 100644
--- a/share/txr/stdlib/compiler.tl
+++ b/share/txr/stdlib/compiler.tl
@@ -117,6 +117,44 @@
(ftab (hash :eql-based))
last-form))
+(compile-only
+ (defstruct param-parser-base nil
+ syntax form
+ rest req opt key
+ nreq nopt nfix
+
+ (:postinit (me)
+ (let* ((rest (nthlast 0 me.syntax))
+ (fixed (ldiff me.syntax rest))
+ nonkey key)
+ (cond
+ (me.mac-param-p
+ (while fixed
+ (let ((pp (pop fixed)))
+ (caseq pp
+ ((:env :whole :form)
+ (unless fixed
+ (compile-error me.form "~s requires argument" pp))
+ (push (cons pp (pop fixed)) key))
+ (t (push pp nonkey)))))
+ (set nonkey (nreverse nonkey)
+ key (nreverse key)))
+ (t (set nonkey fixed)))
+ (tree-bind (: rp opt) (split* nonkey (op where (op eq :)))
+ (set me.rest rest
+ me.req rp
+ me.opt (mapcar [iffi atom list] opt)
+ me.key key
+ me.nreq (len rp)
+ me.nopt (len opt)
+ me.nfix (+ me.nreq me.nopt))))))
+
+ (defstruct (fun-param-parser syntax form) param-parser-base
+ (mac-param-p nil))
+
+ (defstruct (mac-param-parser syntax form) param-parser-base
+ (mac-param-p t)))
+
(defvarl %gcall-op% (relate '(apply usr:apply call) '(gapply gapply gcall)))
(defvarl %call-op% (relate '(apply usr:apply call) '(apply apply call)))
@@ -672,93 +710,86 @@
(uni (diff bfrag.ffuns lexfuns) bfrag.ffuns)))))))
(defmeth compiler comp-lambda (me oreg env form)
- (mac-param-bind form (op pars . body) form
- (let* ((rest-par (nthlast 0 pars))
- (fixed-pars (ldiff pars rest-par))
+ (mac-param-bind form (op par-syntax . body) form
+ (let* ((pars (new (fun-param-parser par-syntax form)))
+ (need-frame (or (plusp pars.nfix) pars.rest))
+ (nenv (if need-frame (new env up env co me) env))
lexsyms specials)
- (tree-bind (: req-pars raw-opt-pars) (split* fixed-pars
- (op where (op eq :)))
- (let* ((opt-pars (mapcar [iffi atom list] raw-opt-pars))
- (nreq (len req-pars))
- (nfixed (+ nreq (len opt-pars)))
- (need-frame (or (plusp nfixed) rest-par))
- (nenv (if need-frame (new env up env co me) env)))
- (flet ((spec-sub (sym)
- (cond
- ((special-var-p sym)
- (let ((sub (gensym)))
- (push (cons sym sub) specials)
- nenv.(extend-var sub)
- sub))
- (t
- (push sym lexsyms)
- nenv.(extend-var sym)
- sym))))
- (set req-pars (collect-each ((rp req-pars))
- (spec-sub rp)))
- (set opt-pars (collect-each ((op opt-pars))
- (tree-bind (var-sym : init-form have-sym) op
- (list (spec-sub var-sym)
- init-form
- (if have-sym (spec-sub have-sym))))))
- (when rest-par
- (set rest-par (spec-sub rest-par)))
- (upd specials nreverse)
- (let* ((col-reg (if opt-pars me.(get-dreg :)))
- (tee-reg (if opt-pars me.(get-dreg t)))
- (ifrags (collect-each ((op opt-pars))
+ (flet ((spec-sub (sym)
+ (cond
+ ((special-var-p sym)
+ (let ((sub (gensym)))
+ (push (cons sym sub) specials)
+ nenv.(extend-var sub)
+ sub))
+ (t
+ (push sym lexsyms)
+ nenv.(extend-var sym)
+ sym))))
+ (let* ((req-pars (collect-each ((rp pars.req))
+ (spec-sub rp)))
+ (opt-pars (collect-each ((op pars.opt))
+ (tree-bind (var-sym : init-form have-sym) op
+ (list (spec-sub var-sym)
+ init-form
+ (if have-sym (spec-sub have-sym))))))
+ (rest-par (when pars.rest (spec-sub pars.rest))))
+ (upd specials nreverse)
+ (let* ((col-reg (if opt-pars me.(get-dreg :)))
+ (tee-reg (if opt-pars me.(get-dreg t)))
+ (ifrags (collect-each ((op opt-pars))
+ (tree-bind (var-sym : init-form have-sym) op
+ (let ((vbind nenv.(lookup-var var-sym)))
+ me.(compile vbind.loc nenv init-form)))))
+ (opt-code (append-each ((op opt-pars)
+ (ifrg ifrags))
(tree-bind (var-sym : init-form have-sym) op
- (let ((vbind nenv.(lookup-var var-sym)))
- me.(compile vbind.loc nenv init-form)))))
- (opt-code (append-each ((op opt-pars)
- (ifrg ifrags))
- (tree-bind (var-sym : init-form have-sym) op
- (let ((vbind nenv.(lookup-var var-sym))
- (have-bind nenv.(lookup-var have-sym))
- (lskip (gensym "l")))
- ^(,*(if have-sym
- ^((mov ,have-bind.loc ,tee-reg)))
- (ifq ,vbind.loc ,col-reg ,lskip)
- ,*(if have-sym
- ^((mov ,have-bind.loc nil)))
- ,*ifrg.code
- ,*(maybe-mov vbind.loc ifrg.oreg)
- ,lskip)))))
- (benv (if specials (new env up nenv co me) nenv))
- (btreg me.(alloc-treg))
- (bfrag me.(comp-progn btreg benv body))
- (boreg (if env.(out-of-scope bfrag.oreg) btreg bfrag.oreg))
- (lskip (gensym "l-"))
- (frsize (if need-frame nenv.v-cntr 0)))
- me.(free-treg btreg)
- (new (frag oreg
- ^((close ,oreg ,frsize ,lskip ,nfixed ,nreq
- ,(if rest-par t nil)
- ,*(collect-each ((rp req-pars))
- nenv.(lookup-var rp).loc)
- ,*(collect-each ((op opt-pars))
- nenv.(lookup-var (car op)).loc)
- ,*(if rest-par
- (list nenv.(lookup-var rest-par).loc)))
- ,*opt-code
- ,*(if specials
- ^((dframe ,benv.lev 0)))
- ,*(if specials
- (collect-each ((vs specials))
- (tree-bind (special . gensym) vs
- (let ((sub-bind nenv.(lookup-var gensym))
- (dreg me.(get-dreg special)))
- ^(bindv ,sub-bind.loc ,dreg)))))
- ,*bfrag.code
- ,*(if specials
- ^((end ,boreg)))
- ,*(maybe-mov boreg bfrag.oreg)
- (end ,boreg)
- ,lskip)
- (uni [reduce-left uni ifrags nil .fvars]
- (diff bfrag.fvars lexsyms))
- (uni [reduce-left uni ifrags nil .ffuns]
- bfrag.ffuns))))))))))
+ (let ((vbind nenv.(lookup-var var-sym))
+ (have-bind nenv.(lookup-var have-sym))
+ (lskip (gensym "l")))
+ ^(,*(if have-sym
+ ^((mov ,have-bind.loc ,tee-reg)))
+ (ifq ,vbind.loc ,col-reg ,lskip)
+ ,*(if have-sym
+ ^((mov ,have-bind.loc nil)))
+ ,*ifrg.code
+ ,*(maybe-mov vbind.loc ifrg.oreg)
+ ,lskip)))))
+ (benv (if specials (new env up nenv co me) nenv))
+ (btreg me.(alloc-treg))
+ (bfrag me.(comp-progn btreg benv body))
+ (boreg (if env.(out-of-scope bfrag.oreg) btreg bfrag.oreg))
+ (lskip (gensym "l-"))
+ (frsize (if need-frame nenv.v-cntr 0)))
+ me.(free-treg btreg)
+ (new (frag oreg
+ ^((close ,oreg ,frsize ,lskip ,pars.nfix ,pars.nreq
+ ,(if rest-par t nil)
+ ,*(collect-each ((rp req-pars))
+ nenv.(lookup-var rp).loc)
+ ,*(collect-each ((op opt-pars))
+ nenv.(lookup-var (car op)).loc)
+ ,*(if rest-par
+ (list nenv.(lookup-var rest-par).loc)))
+ ,*opt-code
+ ,*(if specials
+ ^((dframe ,benv.lev 0)))
+ ,*(if specials
+ (collect-each ((vs specials))
+ (tree-bind (special . gensym) vs
+ (let ((sub-bind nenv.(lookup-var gensym))
+ (dreg me.(get-dreg special)))
+ ^(bindv ,sub-bind.loc ,dreg)))))
+ ,*bfrag.code
+ ,*(if specials
+ ^((end ,boreg)))
+ ,*(maybe-mov boreg bfrag.oreg)
+ (end ,boreg)
+ ,lskip)
+ (uni [reduce-left uni ifrags nil .fvars]
+ (diff bfrag.fvars lexsyms))
+ (uni [reduce-left uni ifrags nil .ffuns]
+ bfrag.ffuns)))))))))
(defmeth compiler comp-fun (me oreg env form)
(mac-param-bind form (op sym) form