aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEduardo Julian2016-07-30 14:23:05 -0400
committerEduardo Julian2016-07-30 14:23:05 -0400
commit4337829fd4b0e2766e95233f1ba4f11af5163452 (patch)
tree30e348fb0cc174ffa2123dcd69de31c07c1f01fe
parent390a892a6b6a32728bd5f829509e079816f8bde7 (diff)
- Now streamlining simple "let" expressions when doing pattern-matching.
-rw-r--r--src/lux/base.clj4
-rw-r--r--src/lux/compiler.clj3
-rw-r--r--src/lux/compiler/lux.clj7
-rw-r--r--src/lux/optimizer.clj23
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)