aboutsummaryrefslogtreecommitdiff
path: root/src/lux/optimizer.clj
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lux/optimizer.clj231
1 files changed, 194 insertions, 37 deletions
diff --git a/src/lux/optimizer.clj b/src/lux/optimizer.clj
index f996587b5..4b617b591 100644
--- a/src/lux/optimizer.clj
+++ b/src/lux/optimizer.clj
@@ -6,7 +6,8 @@
(ns lux.optimizer
(:require (lux [base :as & :refer [|let |do return fail return* fail* |case defvariant]]
[analyser :as &analyser])
- [lux.analyser.base :as &-base]))
+ (lux.analyser [base :as &-base]
+ [case :as &a-case])))
;; [Tags]
(defvariant
@@ -15,67 +16,223 @@
("real" 1)
("char" 1)
("text" 1)
- ("variant" 1)
+ ("variant" 3)
("tuple" 1)
- ("apply" 1)
- ("case" 1)
- ("lambda" 1)
- ("ann" 1)
+ ("apply" 2)
+ ("case" 2)
+ ("function" 4)
+ ("ann" 3)
("var" 1)
- ("captured" 1)
- ("proc" 2)
+ ("captured" 3)
+ ("proc" 3)
)
+;; [Utils]
+(defn ^:private shift-pattern [pattern]
+ (|case pattern
+ (&a-case/$StoreTestAC idx)
+ (&a-case/$StoreTestAC (inc idx))
+
+ (&a-case/$TupleTestAC sub-tests)
+ (&a-case/$TupleTestAC (&/|map shift-pattern sub-tests))
+
+ (&a-case/$VariantTestAC idx num-options sub-test)
+ (&a-case/$VariantTestAC (&/T [idx num-options (shift-pattern sub-test)]))
+
+ _
+ pattern
+ ))
+
+(defn ^:private drop-scope [source]
+ (|case source
+ [meta ($captured scope idx source*)]
+ (&/T [meta ($captured (&/|but-last scope) idx (drop-scope source*))])
+
+ _
+ source))
+
+(defn ^:private de-scope [scope]
+ "(-> Scope Scope)"
+ (|case scope
+ (&/$Cons _module (&/$Cons _def (&/$Cons _level-to-remove _levels-to-keep)))
+ (&/$Cons _module (&/$Cons _def _levels-to-keep))))
+
+(defn ^:private de-meta [body]
+ "(-> Optimized Optimized)"
+ (|case body
+ [meta ($variant idx is-last? value)]
+ ($variant idx is-last? (de-meta value))
+
+ [meta ($tuple elems)]
+ ($tuple (&/|map de-meta elems))
+
+ [meta ($apply func args)]
+ ($apply (de-meta func)
+ (&/|map de-meta args))
+
+ [meta ($case value branches)]
+ ($case (de-meta value)
+ (&/|map (fn [branch]
+ (|let [[_pattern _body] branch]
+ (&/T [_pattern (de-meta _body)])))
+ branches))
+
+ [meta ($function level scope captured body*)]
+ ($function level
+ scope
+ (&/|map (fn [capture]
+ (|let [[_name _captured] capture]
+ (&/T [_name (de-meta _captured)]))
+ )
+ captured)
+ (de-meta body*))
+
+ [meta ($ann value-expr type-expr type-type)]
+ ($ann (de-meta value-expr) nil nil)
+
+ [meta ($var var-kind)]
+ ($var var-kind)
+
+ [meta ($captured scope idx source)]
+ ($captured scope idx (de-meta source))
+
+ [meta ($proc proc-ident args special-args)]
+ (&/T ($proc proc-ident (&/|map de-meta args) special-args))
+
+ [meta not-interesting]
+ not-interesting
+ ))
+
+(defn ^:private shift-function-body [own-body? body]
+ "(-> Optimized Optimized)"
+ (|case body
+ [meta ($variant idx is-last? value)]
+ (&/T [meta ($variant idx is-last? (shift-function-body own-body? value))])
+
+ [meta ($tuple elems)]
+ (&/T [meta ($tuple (&/|map (partial shift-function-body own-body?) elems))])
+
+ [meta ($apply func args)]
+ (&/T [meta ($apply (shift-function-body own-body? func)
+ (&/|map (partial shift-function-body own-body?) args))])
+
+ [meta ($case value branches)]
+ (&/T [meta ($case (shift-function-body own-body? value)
+ (&/|map (fn [branch]
+ (|let [[_pattern _body] branch]
+ (&/T [(if own-body?
+ (shift-pattern _pattern)
+ _pattern)
+ (shift-function-body own-body? _body)])))
+ branches))])
+
+ [meta ($function level scope captured body*)]
+ (&/T [meta ($function level
+ (de-scope scope)
+ (&/|map (fn [capture]
+ (|let [[_name [_meta ($captured _scope _idx _source)]] capture]
+ (&/T [_name (&/T [_meta ($captured (de-scope _scope) _idx (shift-function-body own-body? _source))])])))
+ captured)
+ (shift-function-body false body*))])
+
+ [meta ($ann value-expr type-expr type-type)]
+ (&/T [meta ($ann (shift-function-body own-body? value-expr)
+ type-expr
+ type-type)])
+
+ [meta ($var var-kind)]
+ (if own-body?
+ (|case var-kind
+ (&/$Local 0)
+ (&/T [meta ($apply body
+ (&/|list [meta ($var (&/$Local 1))]))])
+
+ (&/$Local idx)
+ (&/T [meta ($var (&/$Local (inc idx)))])
+
+ (&/$Global ?module ?name)
+ body)
+ body)
+
+ [meta ($captured scope idx source)]
+ (if own-body?
+ source
+ (|case scope
+ (&/$Cons _ (&/$Cons _ (&/$Nil)))
+ source
+
+ _
+ (&/T [meta ($captured (de-scope scope) idx (shift-function-body own-body? source))]))
+ )
+
+ [meta ($proc proc-ident args special-args)]
+ (&/T [meta ($proc proc-ident (&/|map (partial shift-function-body own-body?) args) special-args)])
+
+ not-interesting
+ not-interesting
+ ))
+
+(defn ^:private optimize-closure [optimize closure]
+ (&/|map (fn [capture]
+ (|let [[_name _analysis] capture]
+ (&/T [_name (optimize _analysis)])))
+ closure))
+
;; [Exports]
-(defn optimize-token [analysis]
+(defn optimize [analysis]
"(-> Analysis Optimized)"
(|case analysis
[meta (&-base/$bool value)]
- (return (&/T [meta ($bool value)]))
+ (&/T [meta ($bool value)])
[meta (&-base/$int value)]
- (return (&/T [meta ($int value)]))
+ (&/T [meta ($int value)])
[meta (&-base/$real value)]
- (return (&/T [meta ($real value)]))
+ (&/T [meta ($real value)])
[meta (&-base/$char value)]
- (return (&/T [meta ($char value)]))
+ (&/T [meta ($char value)])
[meta (&-base/$text value)]
- (return (&/T [meta ($text value)]))
+ (&/T [meta ($text value)])
- [meta (&-base/$variant value)]
- (return (&/T [meta ($variant value)]))
+ [meta (&-base/$variant idx is-last? value)]
+ (&/T [meta ($variant idx is-last? (optimize value))])
- [meta (&-base/$tuple value)]
- (return (&/T [meta ($tuple value)]))
+ [meta (&-base/$tuple elems)]
+ (&/T [meta ($tuple (&/|map optimize elems))])
- [meta (&-base/$apply value)]
- (return (&/T [meta ($apply value)]))
+ [meta (&-base/$apply func args)]
+ (&/T [meta ($apply (optimize func) (&/|map optimize args))])
- [meta (&-base/$case value)]
- (return (&/T [meta ($case value)]))
+ [meta (&-base/$case value branches)]
+ (&/T [meta ($case (optimize value)
+ (&/|map (fn [branch]
+ (|let [[_pattern _body] branch]
+ (&/T [_pattern (optimize _body)])))
+ branches))])
- [meta (&-base/$lambda value)]
- (return (&/T [meta ($lambda value)]))
+ [meta (&-base/$lambda scope captured body)]
+ (|case (optimize body)
+ [_ ($function _level _scope _captured _body)]
+ (&/T [meta ($function (inc _level) scope (optimize-closure optimize captured) (shift-function-body true _body))])
+
+ =body
+ (&/T [meta ($function 1 scope (optimize-closure optimize captured) =body)]))
- [meta (&-base/$ann value)]
- (return (&/T [meta ($ann value)]))
+ [meta (&-base/$ann value-expr type-expr type-type)]
+ (&/T [meta ($ann (optimize value-expr) type-expr type-type)])
- [meta (&-base/$var value)]
- (return (&/T [meta ($var value)]))
+ [meta (&-base/$var var-kind)]
+ (&/T [meta ($var var-kind)])
- [meta (&-base/$captured value)]
- (return (&/T [meta ($captured value)]))
+ [meta (&-base/$captured scope idx source)]
+ (&/T [meta ($captured scope idx (optimize source))])
- [meta (&-base/$proc ?proc-ident ?args)]
- (return (&/T [meta ($proc ?proc-ident ?args)]))
+ [meta (&-base/$proc proc-ident args special-args)]
+ (&/T [meta ($proc proc-ident (&/|map optimize args) special-args)])
_
- (assert false (prn-str 'optimize-token (&/adt->text analysis)))
+ (assert false (prn-str 'optimize (&/adt->text analysis)))
))
-
-(defn optimize [eval! compile-module compilers]
- (|do [analyses (&analyser/analyse eval! compile-module compilers)]
- (&/map% optimize-token analyses)))