summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--share/txr/stdlib/compiler.tl27
1 files changed, 23 insertions, 4 deletions
diff --git a/share/txr/stdlib/compiler.tl b/share/txr/stdlib/compiler.tl
index 47f32152..7f49e56c 100644
--- a/share/txr/stdlib/compiler.tl
+++ b/share/txr/stdlib/compiler.tl
@@ -81,11 +81,14 @@
(defstruct compiler nil
(dreg-cntr 0)
+ (fidx-cntr 0)
(nlev 2)
(nreg 1)
(tregs (mapcar (op list t) (range 1 255)))
(dreg (hash :eql-based))
(data (hash :eql-based))
+ (fidx (hash :eql-based))
+ (ftab (hash :eql-based))
last-form)
(defmeth compiler get-dreg (me atom)
@@ -95,9 +98,19 @@
(set [me.data (cadr dreg)] atom)
(set [me.dreg atom] dreg))))
+(defmeth compiler get-fidx (me atom)
+ (iflet ((fidx [me.fidx atom]))
+ fidx
+ (let* ((fidx (pinc me.fidx-cntr)))
+ (set [me.ftab fidx] atom)
+ (set [me.fidx atom] fidx))))
+
(defmeth compiler get-datavec (me)
(vec-list [mapcar me.data (range* 0 me.dreg-cntr)]))
+(defmeth compiler get-funvec (me)
+ (vec-list [mapcar me.ftab (range* 0 me.fidx-cntr)]))
+
(defmeth compiler alloc-treg (me)
(let ((treg (pop me.tregs)))
(unless treg
@@ -365,14 +378,20 @@
me.(compile oreg env (expand qexp))))
(defmeth compiler comp-call (me oreg env sym args)
- (let* ((dreg me.(get-dreg sym))
- (sugg-oregs (mapcar (ret me.(alloc-treg)) args))
+ (condlet
+ (((freg env.(lookup-fun sym)))
+ me.(comp-call-impl oreg env 'call freg args))
+ (((fidx me.(get-fidx sym)))
+ me.(comp-call-impl oreg env 'gcall fidx args))))
+
+(defmeth compiler comp-call-impl (me oreg env opcode freg args)
+ (let* ((sugg-oregs (mapcar (ret me.(alloc-treg)) args))
(afrags (mapcar (ret me.(compile @1 env @2))
sugg-oregs args))
(real-oregs (mapcar .oreg afrags)))
me.(free-tregs sugg-oregs)
(new (frag oreg
- ^(,*(mappend .code afrags) (call ,oreg ,dreg ,*real-oregs))
+ ^(,*(mappend .code afrags) (,opcode ,oreg ,freg ,*real-oregs))
[reduce-left uni afrags nil .fvars]
[reduce-left uni afrags nil .ffuns]))))
@@ -486,4 +505,4 @@
(let* ((oreg co.(alloc-treg))
(frag co.(compile oreg (new env) (expand* exp))))
as.(asm ^(,*frag.code (end ,frag.oreg)))
- (vm-make-desc co.nlev co.nreg as.buf co.(get-datavec) #()))))
+ (vm-make-desc co.nlev co.nreg as.buf co.(get-datavec) co.(get-funvec)))))