diff options
-rw-r--r-- | src/lux/base.clj | 4 | ||||
-rw-r--r-- | src/lux/compiler.clj | 3 | ||||
-rw-r--r-- | src/lux/compiler/lux.clj | 7 | ||||
-rw-r--r-- | src/lux/optimizer.clj | 23 |
4 files changed, 30 insertions, 7 deletions
diff --git a/src/lux/base.clj b/src/lux/base.clj index 2dc684144..be66632c5 100644 --- a/src/lux/base.clj +++ b/src/lux/base.clj @@ -1061,7 +1061,7 @@ (return init) [_ _] - (fail "Lists don't match in size."))) + (assert false "Lists don't match in size."))) (defn map2% [f xs ys] (|case [xs ys] @@ -1074,7 +1074,7 @@ (return $Nil) [_ _] - (fail "Lists don't match in size."))) + (assert false "Lists don't match in size."))) (defn map2 [f xs ys] (|case [xs ys] diff --git a/src/lux/compiler.clj b/src/lux/compiler.clj index ef7fe9b1a..4548e71ab 100644 --- a/src/lux/compiler.clj +++ b/src/lux/compiler.clj @@ -88,6 +88,9 @@ (&o/$case ?value [?pm ?bodies]) (&&case/compile-case (partial compile-expression $begin) ?value ?pm ?bodies) + (&o/$let _value _register _body) + (&&lux/compile-let (partial compile-expression $begin) _value _register _body) + (&o/$function ?arity ?scope ?env ?body) (&&lambda/compile-function compile-expression &/$None ?arity ?scope ?env ?body) diff --git a/src/lux/compiler/lux.clj b/src/lux/compiler/lux.clj index a9cd3756f..af20a3365 100644 --- a/src/lux/compiler/lux.clj +++ b/src/lux/compiler/lux.clj @@ -180,6 +180,13 @@ :let [_ (.visitJumpInsn *writer* Opcodes/GOTO $begin)]] (return nil))) +(defn compile-let [compile _value _register _body] + (|do [^MethodVisitor *writer* &/get-writer + _ (compile _value) + :let [_ (.visitVarInsn *writer* Opcodes/ASTORE _register)] + _ (compile _body)] + (return nil))) + (defn ^:private compile-def-type [compile ?body] (|do [:let [?def-type (|case ?body [[?def-type ?def-cursor] (&a/$ann ?def-value ?type-expr ?def-value-type)] diff --git a/src/lux/optimizer.clj b/src/lux/optimizer.clj index 3e739d511..4788536fe 100644 --- a/src/lux/optimizer.clj +++ b/src/lux/optimizer.clj @@ -26,6 +26,7 @@ ;; Purely for optimizations ("loop" 1) + ("let" 3) ) ;; For pattern-matching @@ -321,6 +322,13 @@ ($loop args) (&/T [meta ($loop (&/|map (partial shift-function-body old-scope new-scope own-body?) args))]) + + ($let _value _register _body) + (&/T [meta ($let (shift-function-body old-scope new-scope own-body? _value) + (if own-body? + (inc _register) + _register) + (shift-function-body old-scope new-scope own-body? _body))]) _ body @@ -395,11 +403,16 @@ (&/T [meta ($apply (pass-0 func) (&/|map pass-0 args))]) (&a/$case value branches) - (&/T [meta ($case (pass-0 value) - (optimize-pm (&/|map (fn [branch] - (|let [[_pattern _body] branch] - (&/T [_pattern (pass-0 _body)]))) - branches)))]) + (|case branches + (&/$Cons [(&a-case/$StoreTestAC _register) _body] (&/$Nil)) + (&/T [meta ($let (pass-0 value) _register (pass-0 _body))]) + + _ + (&/T [meta ($case (pass-0 value) + (optimize-pm (&/|map (fn [branch] + (|let [[_pattern _body] branch] + (&/T [_pattern (pass-0 _body)]))) + branches)))])) (&a/$lambda scope captured body) (|case (pass-0 body) |