diff options
-rw-r--r-- | src/lux/compiler.clj | 3 | ||||
-rw-r--r-- | src/lux/compiler/lux.clj | 16 | ||||
-rw-r--r-- | src/lux/optimizer.clj | 12 |
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. |