aboutsummaryrefslogtreecommitdiff
path: root/src/lux/optimizer.clj
diff options
context:
space:
mode:
Diffstat (limited to 'src/lux/optimizer.clj')
-rw-r--r--src/lux/optimizer.clj158
1 files changed, 101 insertions, 57 deletions
diff --git a/src/lux/optimizer.clj b/src/lux/optimizer.clj
index 9b4dd7548..920fd21bc 100644
--- a/src/lux/optimizer.clj
+++ b/src/lux/optimizer.clj
@@ -2,7 +2,6 @@
;; This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
;; If a copy of the MPL was not distributed with this file,
;; You can obtain one at http://mozilla.org/MPL/2.0/.
-
(ns lux.optimizer
(:require (lux [base :as & :refer [|let |do return fail return* fail* |case defvariant]]
[analyser :as &analyser])
@@ -25,6 +24,9 @@
("var" 1)
("captured" 3)
("proc" 3)
+
+ ;; Purely for optimizations
+ ("loop" 1)
)
;; [Utils]
@@ -131,72 +133,114 @@
($proc proc-ident args special-args)
(&/T [meta ($proc proc-ident (&/|map (partial shift-function-body own-body?) args) special-args)])
+ ($loop args)
+ (&/T [meta ($loop (&/|map (partial shift-function-body own-body?) args))])
+
_
body
)))
-(defn ^:private optimize-closure [optimize closure]
- (&/|map (fn [capture]
- (|let [[_name _analysis] capture]
- (&/T [_name (optimize _analysis)])))
- closure))
+(defn ^:private optimize-loop [arity optim]
+ "(-> Int Optimized [Optimized Bool])"
+ (|let [[meta optim-] optim]
+ (|case optim-
+ ($apply [meta-0 ($var (&/$Local 0))] _args)
+ (if (= arity (&/|length _args))
+ (&/T [meta-0 ($loop (&/|map (partial optimize-loop -1) _args))])
+ optim)
-;; [Exports]
-(defn optimize [analysis]
- "(-> Analysis Optimized)"
- (|let [[meta analysis-] analysis]
- (|case analysis-
- (&-base/$bool value)
- (&/T [meta ($bool value)])
-
- (&-base/$int value)
- (&/T [meta ($int value)])
-
- (&-base/$real value)
- (&/T [meta ($real value)])
-
- (&-base/$char value)
- (&/T [meta ($char value)])
-
- (&-base/$text value)
- (&/T [meta ($text value)])
-
- (&-base/$variant idx is-last? value)
- (&/T [meta ($variant idx is-last? (optimize value))])
-
- (&-base/$tuple elems)
- (&/T [meta ($tuple (&/|map optimize elems))])
-
- (&-base/$apply func args)
- (&/T [meta ($apply (optimize func) (&/|map optimize args))])
-
- (&-base/$case value branches)
- (&/T [meta ($case (optimize value)
+ ($apply func args)
+ (&/T [meta ($apply (optimize-loop -1 func)
+ (&/|map (partial optimize-loop -1) args))])
+
+ ($case _value _branches)
+ (&/T [meta ($case _value
(&/|map (fn [branch]
(|let [[_pattern _body] branch]
- (&/T [_pattern (optimize _body)])))
- branches))])
-
- (&-base/$lambda scope captured body)
- (|case (optimize body)
- [_ ($function _arity _scope _captured _body)]
- (&/T [meta ($function (inc _arity) scope (optimize-closure optimize captured) (shift-function-body true _body))])
+ (&/T [_pattern (optimize-loop arity _body)])))
+ _branches))])
- =body
- (&/T [meta ($function 1 scope (optimize-closure optimize captured) =body)]))
+ ($function _arity _scope _captured _body)
+ (&/T [meta ($function _arity _scope _captured (optimize-loop _arity _body))])
- (&-base/$ann value-expr type-expr type-type)
- (&/T [meta ($ann (optimize value-expr) type-expr type-type)])
-
- (&-base/$var var-kind)
- (&/T [meta ($var var-kind)])
-
- (&-base/$captured scope idx source)
- (&/T [meta ($captured scope idx (optimize source))])
+ ($ann _value-expr _type-expr _type-type)
+ (&/T [meta ($ann (optimize-loop arity _value-expr) _type-expr _type-type)])
+
+ ($variant idx is-last? value)
+ (&/T [meta ($variant idx is-last? (optimize-loop -1 value))])
- (&-base/$proc proc-ident args special-args)
- (&/T [meta ($proc proc-ident (&/|map optimize args) special-args)])
+ ($tuple elems)
+ (&/T [meta ($tuple (&/|map (partial optimize-loop -1) elems))])
_
- (assert false (prn-str 'optimize (&/adt->text analysis)))
+ optim
)))
+
+(let [optimize-closure (fn [optimize closure]
+ (&/|map (fn [capture]
+ (|let [[_name _analysis] capture]
+ (&/T [_name (optimize _analysis)])))
+ closure))]
+ (defn ^:private pass-0 [analysis]
+ "(-> Analysis Optimized)"
+ (|let [[meta analysis-] analysis]
+ (|case analysis-
+ (&-base/$bool value)
+ (&/T [meta ($bool value)])
+
+ (&-base/$int value)
+ (&/T [meta ($int value)])
+
+ (&-base/$real value)
+ (&/T [meta ($real value)])
+
+ (&-base/$char value)
+ (&/T [meta ($char value)])
+
+ (&-base/$text value)
+ (&/T [meta ($text value)])
+
+ (&-base/$variant idx is-last? value)
+ (&/T [meta ($variant idx is-last? (pass-0 value))])
+
+ (&-base/$tuple elems)
+ (&/T [meta ($tuple (&/|map pass-0 elems))])
+
+ (&-base/$apply func args)
+ (&/T [meta ($apply (pass-0 func) (&/|map pass-0 args))])
+
+ (&-base/$case value branches)
+ (&/T [meta ($case (pass-0 value)
+ (&/|map (fn [branch]
+ (|let [[_pattern _body] branch]
+ (&/T [_pattern (pass-0 _body)])))
+ branches))])
+
+ (&-base/$lambda scope captured body)
+ (|case (pass-0 body)
+ [_ ($function _arity _scope _captured _body)]
+ (&/T [meta ($function (inc _arity) scope (optimize-closure pass-0 captured) (shift-function-body true _body))])
+
+ =body
+ (&/T [meta ($function 1 scope (optimize-closure pass-0 captured) =body)]))
+
+ (&-base/$ann value-expr type-expr type-type)
+ (&/T [meta ($ann (pass-0 value-expr) type-expr type-type)])
+
+ (&-base/$var var-kind)
+ (&/T [meta ($var var-kind)])
+
+ (&-base/$captured scope idx source)
+ (&/T [meta ($captured scope idx (pass-0 source))])
+
+ (&-base/$proc proc-ident args special-args)
+ (&/T [meta ($proc proc-ident (&/|map pass-0 args) special-args)])
+
+ _
+ (assert false (prn-str 'pass-0 (&/adt->text analysis)))
+ ))))
+
+;; [Exports]
+(defn optimize [analysis]
+ "(-> Analysis Optimized)"
+ (->> analysis pass-0 (optimize-loop -1)))