aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lux/compiler.clj3
-rw-r--r--src/lux/compiler/lux.clj16
-rw-r--r--src/lux/optimizer.clj12
3 files changed, 31 insertions, 0 deletions
diff --git a/src/lux/compiler.clj b/src/lux/compiler.clj
index fe3a24c32..294f2dc63 100644
--- a/src/lux/compiler.clj
+++ b/src/lux/compiler.clj
@@ -97,6 +97,9 @@
(&o/$record-get _value _path)
(&&lux/compile-record-get (partial compile-expression $begin) _value _path)
+ (&o/$if _test _then _else)
+ (&&lux/compile-if (partial compile-expression $begin) _test _then _else)
+
(&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 6b5ec6a19..ba031eda7 100644
--- a/src/lux/compiler/lux.clj
+++ b/src/lux/compiler/lux.clj
@@ -203,6 +203,22 @@
_path)]]
(return nil)))
+(defn compile-if [compile _test _then _else]
+ (|do [^MethodVisitor *writer* &/get-writer
+ _ (compile _test)
+ :let [$else (new Label)
+ $end (new Label)
+ _ (doto *writer*
+ &&/unwrap-boolean
+ (.visitJumpInsn Opcodes/IFEQ $else))]
+ _ (compile _then)
+ :let [_ (.visitJumpInsn *writer* Opcodes/GOTO $end)]
+ :let [_ (.visitLabel *writer* $else)]
+ _ (compile _else)
+ :let [_ (.visitJumpInsn *writer* Opcodes/GOTO $end)
+ _ (.visitLabel *writer* $end)]]
+ (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 e7af21664..56a73060c 100644
--- a/src/lux/optimizer.clj
+++ b/src/lux/optimizer.clj
@@ -42,6 +42,8 @@
;; e.g. record.l1.l2.l3
;; The record-get token stores the path, for simpler compilation.
("record-get" 2)
+ ;; Regular, run-of-the-mill if expressions.
+ ("if" 3)
)
;; [Utils]
@@ -423,6 +425,11 @@
($record-get _value _path)
(&/T [meta ($record-get (shift-function-body old-scope new-scope own-body? _value)
_path)])
+
+ ($if _test _then _else)
+ (&/T [meta ($if (shift-function-body old-scope new-scope own-body? _test)
+ (shift-function-body old-scope new-scope own-body? _then)
+ (shift-function-body old-scope new-scope own-body? _else))])
_
body
@@ -552,6 +559,11 @@
(&/$Cons [(&a-case/$StoreTestAC _register) _body] (&/$Nil))
(&/T [meta ($let (pass-0 value) _register (pass-0 _body))])
+ (&/$Cons [(&a-case/$BoolTestAC false) _else]
+ (&/$Cons [(&a-case/$BoolTestAC true) _then]
+ (&/$Nil)))
+ (&/T [meta ($if (pass-0 value) (pass-0 _then) (pass-0 _else))])
+
;; The pattern for a record-get is a single branch, with a
;; tuple pattern and a body corresponding to a
;; local-variable extracted from the tuple.