summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2018-03-20 06:16:32 -0700
committerKaz Kylheku <kaz@kylheku.com>2018-03-20 06:16:32 -0700
commit46c773ac117c9d2502160b929c87d1611c65c718 (patch)
tree4f2a568c9f9086e59b506ee950203190cd4ecb67
parent61dbc3f0a55029a10720d2affe049d13f3147da2 (diff)
downloadtxr-46c773ac117c9d2502160b929c87d1611c65c718.tar.gz
txr-46c773ac117c9d2502160b929c87d1611c65c718.tar.bz2
txr-46c773ac117c9d2502160b929c87d1611c65c718.zip
compiler: handle if special form
* share/txr/stdlib/compiler.tl (compiler compile): Handle if case via comp-if method. (compiler comp-if): New method.
-rw-r--r--share/txr/stdlib/compiler.tl52
1 files changed, 52 insertions, 0 deletions
diff --git a/share/txr/stdlib/compiler.tl b/share/txr/stdlib/compiler.tl
index 9ec9e10b..b74d2b84 100644
--- a/share/txr/stdlib/compiler.tl
+++ b/share/txr/stdlib/compiler.tl
@@ -145,6 +145,7 @@
(quote me.(comp-atom oreg (cadr form)))
(sys:setq me.(comp-setq oreg env form))
(cond me.(comp-cond oreg env form))
+ (if me.(comp-if oreg env form))
(block me.(comp-block oreg env form))
((let let*) me.(comp-let oreg env form))
(lambda me.(comp-lambda oreg env form))
@@ -251,6 +252,57 @@
[reduce-left uni frags nil .fvars]
[reduce-left uni frags nil .ffuns]))))
+(defmeth compiler comp-if (me oreg env form)
+ (tree-case form
+ ((op test then else)
+ (let* ((te-oreg me.(alloc-treg))
+ (lelse (gensym "l"))
+ (lskip (gensym "l"))
+ (te-frag me.(compile te-oreg env test))
+ (th-frag me.(compile oreg env then))
+ (el-frag me.(compile oreg env else)))
+ me.(free-treg te-oreg)
+ (new (frag oreg
+ ^(,*te-frag.code
+ (if ,te-frag.oreg ,lelse)
+ ,*th-frag.code
+ ,*(if (nequal oreg th-frag.oreg)
+ ^((mov ,oreg ,th-frag.oreg)))
+ (jmp ,lskip)
+ ,lelse
+ ,*el-frag.code
+ ,*(if (nequal oreg el-frag.oreg)
+ ^((mov ,oreg ,el-frag.oreg)))
+ ,lskip
+ ,*(if (nequal te-oreg te-frag.oreg)
+ ^((mov ,te-oreg ,te-frag.oreg))))
+ (uni te-frag.fvars (uni th-frag.fvars el-frag.fvars))
+ (uni te-frag.ffuns (uni th-frag.ffuns el-frag.ffuns))))))
+ ((op test then)
+ (let ((lskip (gensym "l"))
+ (te-frag me.(compile oreg env test))
+ (th-frag me.(compile oreg env then)))
+ (new (frag oreg
+ ^(,*te-frag.code
+ ,*(if (nequal oreg te-frag.oreg)
+ ^((mov ,oreg ,te-frag.oreg)))
+ (if ,oreg ,lskip)
+ ,*th-frag.code
+ ,*(if (nequal oreg th-frag.oreg)
+ ^((mov ,oreg ,th-frag.oreg)))
+ ,lskip)
+ (uni te-frag.fvars th-frag.fvars)
+ (uni te-frag.ffuns th-frag.ffuns)))))
+ ((op test)
+ (let ((te-frag me.(compile oreg env test)))
+ (new (frag oreg
+ ^(,*te-frag.code
+ (mov ,oreg nil))
+ te-frag.fvars
+ te-frag.ffuns))))
+ ((op) me.(compile oreg env nil))
+ (form (compile-error form "excess argument forms"))))
+
(defmeth compiler comp-block (me oreg env form)
(mac-param-bind form (op name . body) form
(let* ((nreg (if name me.(get-dreg name) '(t 0)))