summaryrefslogtreecommitdiffstats
path: root/share
diff options
context:
space:
mode:
Diffstat (limited to 'share')
-rw-r--r--share/txr/stdlib/compiler.tl46
1 files changed, 46 insertions, 0 deletions
diff --git a/share/txr/stdlib/compiler.tl b/share/txr/stdlib/compiler.tl
index 4b71b572..774a1616 100644
--- a/share/txr/stdlib/compiler.tl
+++ b/share/txr/stdlib/compiler.tl
@@ -258,6 +258,8 @@
(defvarl %bin-op% (relate %nary-ops% %bin-ops% nil))
+(defvarl %const-foldable-funs% '(+ - * / b- b+ b* b/ car cdr cadr caddr first second))
+
(defvarl assumed-fun)
(defvar *dedup*)
@@ -432,6 +434,8 @@
sys:qquote sys:unquote sys:splice)
(compile-error form "unexpanded quasiquote encountered"))
;; function call
+ ((+ *) me.(comp-arith-form oreg env form))
+ ((- /) me.(comp-arith-neg-form oreg env form))
(t me.(comp-fun-form oreg env form))))
((and (consp sym)
(eq (car sym) 'lambda)) me.(compile oreg env ^(call ,*form)))
@@ -1154,6 +1158,32 @@
(let ((qexp (expand-quasi form)))
me.(compile oreg env (expand qexp))))
+(defmeth compiler comp-arith-form (me oreg env form)
+ (let ((rform (reduce-constant form)))
+ (tree-case rform
+ ((op . args)
+ (let* ((pargs [partition-by constantp args])
+ (fargs (append-each ((pa pargs))
+ (if (and (constantp (car pa))
+ (all pa [chain eval integerp]))
+ (list (eval ^(,op ,*pa)))
+ pa))))
+ me.(comp-fun-form oreg env ^(,op ,*fargs))))
+ (else me.(compile oreg env rform)))))
+
+(defmeth compiler comp-arith-neg-form (me oreg env form)
+ (if (> (len form) 3)
+ (tree-bind (nop . args) form
+ (let ((op (caseq nop (- '+) (/ '*)))
+ (a1 (car args)))
+ (if (and (eq nop '-)
+ (constantp a1))
+ me.(comp-arith-form oreg env
+ ^(,op (- ,a1) ,*(cdr args)))
+ me.(comp-fun-form oreg env
+ ^(,nop ,(car args) (,op ,*(cdr args)))))))
+ me.(comp-fun-form oreg env form)))
+
(defmeth compiler comp-fun-form (me oreg env form)
(match-case form
((equal @a @b)
@@ -1176,6 +1206,11 @@
((@(or identity + * min max) @a)
(return-from comp-fun-form me.(compile oreg env a))))
+ (tree-case form
+ ((sym . args)
+ (if (member sym %const-foldable-funs%)
+ (set form (reduce-constant form)))))
+
(when (or (atom form) (special-operator-p (car form)))
(return-from comp-fun-form me.(compile oreg env form)))
@@ -1505,6 +1540,17 @@
^(,op ,a ,*args))
(@else else))))
+(defun reduce-constant (form)
+ (if (consp form)
+ (tree-bind (op . args) form
+ (if (member op %const-foldable-funs%)
+ (let ((cargs [mapcar reduce-constant args]))
+ (if [all cargs constantp]
+ ^(quote ,(eval ^(,op ,*cargs)))
+ ^(,op ,*cargs)))
+ form))
+ form))
+
(defun expand-quasi-mods (obj mods : form)
(let (plist num sep rng-ix scalar-ix-p flex gens)
(flet ((get-sym (exp)