diff options
author | Eduardo Julian | 2015-03-12 01:25:06 -0400 |
---|---|---|
committer | Eduardo Julian | 2015-03-12 01:25:06 -0400 |
commit | aecb050cfba1c272274e9737b6c9b5b45309a900 (patch) | |
tree | b18ed566164c79ce45cf905b531e968aea2674df | |
parent | 8e82cb7ab2276c5622af30cf43527aa79c8d36e5 (diff) |
- Added a special form for testing if references are null.
- Added bitwise operators.
- Added synchronization primitives (monitor enter & exit).
- Added exception-handling.
- Added conversions between primitive values.
-rw-r--r-- | src/lux.clj | 6 | ||||
-rw-r--r-- | src/lux/analyser.clj | 110 | ||||
-rw-r--r-- | src/lux/analyser/host.clj | 76 | ||||
-rw-r--r-- | src/lux/compiler.clj | 87 | ||||
-rw-r--r-- | src/lux/compiler/host.clj | 130 |
5 files changed, 399 insertions, 10 deletions
diff --git a/src/lux.clj b/src/lux.clj index a8bdd4f31..f69bdf9dc 100644 --- a/src/lux.clj +++ b/src/lux.clj @@ -6,16 +6,10 @@ ;; TODO: Finish type system. ;; TODO: Re-implement compiler in language. ;; TODO: Adding metadata to global vars. - ;; TODO: throw, try, catch, finally ;; TODO: Allow setting fields. - ;; TODO: monitor enter & monitor exit. ;; TODO: Add column & line numbers for syntactic elements. ;; TODO: Add source-file information to .class files for easier debugging. - ;; TODO: Add conversions between primitives - ;; TODO: Being able to ask if a value is null or not. (null?) ;; TODO: invokespecial & invokeinterface - ;; TODO: bitwise operators - ;; TODO: multianewarray ;; TODO: (time (&compiler/compile-all ["lux"])) diff --git a/src/lux/analyser.clj b/src/lux/analyser.clj index ad21eadd1..41e304521 100644 --- a/src/lux/analyser.clj +++ b/src/lux/analyser.clj @@ -14,6 +14,20 @@ [host :as &&host]))) ;; [Utils] +(defn ^:private parse-handler [[catch+ finally+] token] + (matchv ::M/objects [token] + [["Form" ["Cons" [["Ident" "jvm-catch"] + ["Cons" [["Ident" ?ex-class] + ["Cons" [["Ident" ?ex-arg] + ["Cons" [?catch-body + ["Nil" _]]]]]]]]]]] + [(concat catch+ (list [?ex-class ?ex-arg ?catch-body])) finally+] + + [["Form" ["Cons" [["Ident" "jvm-finally"] + ["Cons" [?finally-body + ["Nil" _]]]]]]] + [catch+ ?finally-body])) + (defn ^:private analyse-basic-ast [analyse-ast token] ;; (prn 'analyse-basic-ast token (&/show-ast token)) (matchv ::M/objects [token] @@ -181,6 +195,9 @@ (&&host/analyse-jvm-dgt analyse-ast ?x ?y) ;; Objects + [["Form" ["Cons" [["Ident" "jvm-null?"] ["Cons" [?object ["Nil" _]]]]]]] + (&&host/analyse-jvm-null? analyse-ast ?object) + [["Form" ["Cons" [["Ident" "jvm-new"] ["Cons" [["Ident" ?class] ["Cons" [["Tuple" ?classes] @@ -219,6 +236,99 @@ ["Nil" _]]]]]]]]]]]]]]] (&&host/analyse-jvm-invokevirtual analyse-ast ?class ?method (&/->seq ?classes) ?object (&/->seq ?args)) + ;; Exceptions + [["Form" ["Cons" [["Ident" "jvm-try"] + ["Cons" [?body + ?handlers]]]]]] + (&&host/analyse-jvm-try analyse-ast ?body (reduce parse-handler [(list) nil] (&/->seq ?handlers))) + + [["Form" ["Cons" [["Ident" "jvm-throw"] + ["Cons" [?ex + ["Nil" _]]]]]]] + (&&host/analyse-jvm-throw analyse-ast ?ex) + + ;; Syncronization/monitos + [["Form" ["Cons" [["Ident" "jvm-monitorenter"] + ["Cons" [?monitor + ["Nil" _]]]]]]] + (&&host/analyse-jvm-monitorenter analyse-ast ?monitor) + + [["Form" ["Cons" [["Ident" "jvm-monitorexit"] + ["Cons" [?monitor + ["Nil" _]]]]]]] + (&&host/analyse-jvm-monitorexit analyse-ast ?monitor) + + ;; Primitive conversions + [["Form" ["Cons" [["Ident" "jvm-d2f"] ["Cons" [?value ["Nil" _]]]]]]] + (&&host/analyse-jvm-d2f analyse-ast ?value) + + [["Form" ["Cons" [["Ident" "jvm-d2i"] ["Cons" [?value ["Nil" _]]]]]]] + (&&host/analyse-jvm-d2i analyse-ast ?value) + + [["Form" ["Cons" [["Ident" "jvm-d2l"] ["Cons" [?value ["Nil" _]]]]]]] + (&&host/analyse-jvm-d2l analyse-ast ?value) + + [["Form" ["Cons" [["Ident" "jvm-f2d"] ["Cons" [?value ["Nil" _]]]]]]] + (&&host/analyse-jvm-f2d analyse-ast ?value) + + [["Form" ["Cons" [["Ident" "jvm-f2i"] ["Cons" [?value ["Nil" _]]]]]]] + (&&host/analyse-jvm-f2i analyse-ast ?value) + + [["Form" ["Cons" [["Ident" "jvm-f2l"] ["Cons" [?value ["Nil" _]]]]]]] + (&&host/analyse-jvm-f2l analyse-ast ?value) + + [["Form" ["Cons" [["Ident" "jvm-i2b"] ["Cons" [?value ["Nil" _]]]]]]] + (&&host/analyse-jvm-i2b analyse-ast ?value) + + [["Form" ["Cons" [["Ident" "jvm-i2c"] ["Cons" [?value ["Nil" _]]]]]]] + (&&host/analyse-jvm-i2c analyse-ast ?value) + + [["Form" ["Cons" [["Ident" "jvm-i2d"] ["Cons" [?value ["Nil" _]]]]]]] + (&&host/analyse-jvm-i2d analyse-ast ?value) + + [["Form" ["Cons" [["Ident" "jvm-i2f"] ["Cons" [?value ["Nil" _]]]]]]] + (&&host/analyse-jvm-i2f analyse-ast ?value) + + [["Form" ["Cons" [["Ident" "jvm-i2l"] ["Cons" [?value ["Nil" _]]]]]]] + (&&host/analyse-jvm-i2l analyse-ast ?value) + + [["Form" ["Cons" [["Ident" "jvm-i2s"] ["Cons" [?value ["Nil" _]]]]]]] + (&&host/analyse-jvm-i2s analyse-ast ?value) + + [["Form" ["Cons" [["Ident" "jvm-l2d"] ["Cons" [?value ["Nil" _]]]]]]] + (&&host/analyse-jvm-l2d analyse-ast ?value) + + [["Form" ["Cons" [["Ident" "jvm-l2f"] ["Cons" [?value ["Nil" _]]]]]]] + (&&host/analyse-jvm-l2f analyse-ast ?value) + + [["Form" ["Cons" [["Ident" "jvm-l2i"] ["Cons" [?value ["Nil" _]]]]]]] + (&&host/analyse-jvm-l2i analyse-ast ?value) + + ;; Bitwise operators + [["Form" ["Cons" [["Ident" "jvm-iand"] ["Cons" [?x ["Cons" [?y ["Nil" _]]]]]]]]] + (&&host/analyse-jvm-iand analyse-ast ?x ?y) + + [["Form" ["Cons" [["Ident" "jvm-ior"] ["Cons" [?x ["Cons" [?y ["Nil" _]]]]]]]]] + (&&host/analyse-jvm-ior analyse-ast ?x ?y) + + [["Form" ["Cons" [["Ident" "jvm-land"] ["Cons" [?x ["Cons" [?y ["Nil" _]]]]]]]]] + (&&host/analyse-jvm-land analyse-ast ?x ?y) + + [["Form" ["Cons" [["Ident" "jvm-lor"] ["Cons" [?x ["Cons" [?y ["Nil" _]]]]]]]]] + (&&host/analyse-jvm-lor analyse-ast ?x ?y) + + [["Form" ["Cons" [["Ident" "jvm-lxor"] ["Cons" [?x ["Cons" [?y ["Nil" _]]]]]]]]] + (&&host/analyse-jvm-lxor analyse-ast ?x ?y) + + [["Form" ["Cons" [["Ident" "jvm-lshl"] ["Cons" [?x ["Cons" [?y ["Nil" _]]]]]]]]] + (&&host/analyse-jvm-lshl analyse-ast ?x ?y) + + [["Form" ["Cons" [["Ident" "jvm-lshr"] ["Cons" [?x ["Cons" [?y ["Nil" _]]]]]]]]] + (&&host/analyse-jvm-lshr analyse-ast ?x ?y) + + [["Form" ["Cons" [["Ident" "jvm-lushr"] ["Cons" [?x ["Cons" [?y ["Nil" _]]]]]]]]] + (&&host/analyse-jvm-lushr analyse-ast ?x ?y) + ;; Arrays [["Form" ["Cons" [["Ident" "jvm-new-array"] ["Cons" [["Ident" ?class] ["Cons" [["Int" ?length] ["Nil" _]]]]]]]]] (&&host/analyse-jvm-new-array analyse-ast ?class ?length) diff --git a/src/lux/analyser/host.clj b/src/lux/analyser/host.clj index f6f20d695..fd4244178 100644 --- a/src/lux/analyser/host.clj +++ b/src/lux/analyser/host.clj @@ -8,7 +8,8 @@ [parser :as &parser] [type :as &type] [host :as &host]) - (lux.analyser [base :as &&]))) + (lux.analyser [base :as &&] + [env :as &&env]))) ;; [Utils] (defn ^:private ->seq [xs] @@ -127,6 +128,10 @@ ] (return (list [::&&/Expression [::&&/jvm-invokevirtual =class ?method =classes =object =args] =return])))) +(defn analyse-jvm-null? [analyse ?object] + (exec [=object (&&/analyse-1 analyse ?object)] + (return (list [::&&/Expression [::&&/jvm-null? =object] [::&type/Data "java.lang.Boolean"]])))) + (defn analyse-jvm-new [analyse ?class ?classes ?args] (exec [=class (&host/full-class-name ?class) =classes (map-m &host/extract-jvm-param ?classes) @@ -175,8 +180,8 @@ ["Nil" _]]]]]]]] ["Nil" _]]]]]]]]] (do ;; (prn 'analyse-jvm-interface ?member-name ?inputs ?output) - (exec [?inputs (map-m extract-ident (&/->seq ?inputs))] - (return [?member-name [?inputs ?output]]))) + (exec [?inputs (map-m extract-ident (&/->seq ?inputs))] + (return [?member-name [?inputs ?output]]))) [_] (fail "[Analyser Error] Invalid method signature!"))) @@ -192,3 +197,68 @@ =exprs (mapcat-m analyse ?exprs) =exprs-types (map-m &&/expr-type =exprs)] (return (list [::&&/Expression [::&&/exec =exprs] (last =exprs-types)])))) + +(defn analyse-jvm-try [analyse ?body [?catches ?finally]] + (exec [=body (&&/analyse-1 analyse ?body) + =catches (map-m (fn [[?ex-class ?ex-arg ?catch-body]] + (&&env/with-local ?ex-arg [::&type/Data ?ex-class] + (exec [=catch-body (&&/analyse-1 analyse ?catch-body)] + (return [?ex-class ?ex-arg =catch-body])))) + ?catches) + =finally (&&/analyse-1 analyse ?finally) + =body-type (&&/expr-type =body)] + (return (list [::&&/Expression [::&&/jvm-try =body =catches =finally] =body-type])))) + +(defn analyse-jvm-throw [analyse ?ex] + (exec [=ex (&&/analyse-1 analyse ?ex)] + (return (list [::&&/Expression [::&&/jvm-throw =ex] [::&type/Nothing]])))) + +(defn analyse-jvm-monitorenter [analyse ?monitor] + (exec [=monitor (&&/analyse-1 analyse ?monitor)] + (return (list [::&&/Expression [::&&/jvm-monitorenter =monitor] [::&type/Any]])))) + +(defn analyse-jvm-monitorexit [analyse ?monitor] + (exec [=monitor (&&/analyse-1 analyse ?monitor)] + (return (list [::&&/Expression [::&&/jvm-monitorexit =monitor] [::&type/Any]])))) + +(do-template [<name> <tag> <from-class> <to-class>] + (defn <name> [analyse ?value] + (exec [=value (&&/analyse-1 analyse ?value)] + (return (list [::&&/Expression [<tag> =value] [::&type/Data <to-class>]])))) + + analyse-jvm-d2f ::&&/jvm-d2f "java.lang.Double" "java.lang.Float" + analyse-jvm-d2i ::&&/jvm-d2i "java.lang.Double" "java.lang.Integer" + analyse-jvm-d2l ::&&/jvm-d2l "java.lang.Double" "java.lang.Long" + + analyse-jvm-f2d ::&&/jvm-f2d "java.lang.Float" "java.lang.Double" + analyse-jvm-f2i ::&&/jvm-f2i "java.lang.Float" "java.lang.Integer" + analyse-jvm-f2l ::&&/jvm-f2l "java.lang.Float" "java.lang.Long" + + analyse-jvm-i2b ::&&/jvm-i2b "java.lang.Integer" "java.lang.Byte" + analyse-jvm-i2c ::&&/jvm-i2c "java.lang.Integer" "java.lang.Character" + analyse-jvm-i2d ::&&/jvm-i2d "java.lang.Integer" "java.lang.Double" + analyse-jvm-i2f ::&&/jvm-i2f "java.lang.Integer" "java.lang.Float" + analyse-jvm-i2l ::&&/jvm-i2l "java.lang.Integer" "java.lang.Long" + analyse-jvm-i2s ::&&/jvm-i2s "java.lang.Integer" "java.lang.Short" + + analyse-jvm-l2d ::&&/jvm-l2d "java.lang.Long" "java.lang.Double" + analyse-jvm-l2f ::&&/jvm-l2f "java.lang.Long" "java.lang.Float" + analyse-jvm-l2i ::&&/jvm-l2i "java.lang.Long" "java.lang.Integer" + ) + +(do-template [<name> <tag> <from-class> <to-class>] + (defn <name> [analyse ?value] + (exec [=value (&&/analyse-1 analyse ?value)] + (return (list [::&&/Expression [<tag> =value] [::&type/Data <to-class>]])))) + + analyse-jvm-iand ::&&/jvm-iand "java.lang.Integer" "java.lang.Integer" + analyse-jvm-ior ::&&/jvm-ior "java.lang.Integer" "java.lang.Integer" + + analyse-jvm-land ::&&/jvm-land "java.lang.Long" "java.lang.Long" + analyse-jvm-lor ::&&/jvm-lor "java.lang.Long" "java.lang.Long" + analyse-jvm-lxor ::&&/jvm-lxor "java.lang.Long" "java.lang.Long" + + analyse-jvm-lshl ::&&/jvm-lshl "java.lang.Long" "java.lang.Integer" + analyse-jvm-lshr ::&&/jvm-lshr "java.lang.Long" "java.lang.Integer" + analyse-jvm-lushr ::&&/jvm-lushr "java.lang.Long" "java.lang.Integer" + ) diff --git a/src/lux/compiler.clj b/src/lux/compiler.clj index 2fa180aea..62a11868d 100644 --- a/src/lux/compiler.clj +++ b/src/lux/compiler.clj @@ -186,6 +186,9 @@ [::&a/jvm-null] (&&host/compile-jvm-null compile-expression ?type) + + [::&a/jvm-null? ?object] + (&&host/compile-jvm-null? compile-expression ?type ?object) [::&a/jvm-new ?class ?classes ?args] (&&host/compile-jvm-new compile-expression ?type ?class ?classes ?args) @@ -209,7 +212,89 @@ (&&host/compile-jvm-aastore compile-expression ?type ?array ?idx ?elem) [::&a/jvm-aaload ?array ?idx] - (&&host/compile-jvm-aaload compile-expression ?type ?array ?idx)) + (&&host/compile-jvm-aaload compile-expression ?type ?array ?idx) + + [::&a/jvm-try ?body ?catches ?finally] + (&&host/compile-jvm-try compile-expression ?type ?body ?catches ?finally) + + [::&a/jvm-throw ?ex] + (&&host/compile-jvm-throw compile-expression ?type ?ex) + + [::&a/jvm-monitorenter ?monitor] + (&&host/compile-jvm-monitorenter compile-expression ?type ?monitor) + + [::&a/jvm-monitorexit ?monitor] + (&&host/compile-jvm-monitorexit compile-expression ?type ?monitor) + + [::&a/jvm-d2f ?value] + (&&host/compile-jvm-d2f compile-expression ?type ?value) + + [::&a/jvm-d2i ?value] + (&&host/compile-jvm-d2i compile-expression ?type ?value) + + [::&a/jvm-d2l ?value] + (&&host/compile-jvm-d2l compile-expression ?type ?value) + + [::&a/jvm-f2d ?value] + (&&host/compile-jvm-f2d compile-expression ?type ?value) + + [::&a/jvm-f2i ?value] + (&&host/compile-jvm-f2i compile-expression ?type ?value) + + [::&a/jvm-f2l ?value] + (&&host/compile-jvm-f2l compile-expression ?type ?value) + + [::&a/jvm-i2b ?value] + (&&host/compile-jvm-i2b compile-expression ?type ?value) + + [::&a/jvm-i2c ?value] + (&&host/compile-jvm-i2c compile-expression ?type ?value) + + [::&a/jvm-i2d ?value] + (&&host/compile-jvm-i2d compile-expression ?type ?value) + + [::&a/jvm-i2f ?value] + (&&host/compile-jvm-i2f compile-expression ?type ?value) + + [::&a/jvm-i2l ?value] + (&&host/compile-jvm-i2l compile-expression ?type ?value) + + [::&a/jvm-i2s ?value] + (&&host/compile-jvm-i2s compile-expression ?type ?value) + + [::&a/jvm-l2d ?value] + (&&host/compile-jvm-l2d compile-expression ?type ?value) + + [::&a/jvm-l2f ?value] + (&&host/compile-jvm-l2f compile-expression ?type ?value) + + [::&a/jvm-l2i ?value] + (&&host/compile-jvm-l2i compile-expression ?type ?value) + + [::&a/jvm-iand ?x y] + (&&host/compile-jvm-iand compile-expression ?type ?x y) + + [::&a/jvm-ior ?x y] + (&&host/compile-jvm-ior compile-expression ?type ?x y) + + [::&a/jvm-land ?x y] + (&&host/compile-jvm-land compile-expression ?type ?x y) + + [::&a/jvm-lor ?x y] + (&&host/compile-jvm-lor compile-expression ?type ?x y) + + [::&a/jvm-lxor ?x y] + (&&host/compile-jvm-lxor compile-expression ?type ?x y) + + [::&a/jvm-lshl ?x y] + (&&host/compile-jvm-lshl compile-expression ?type ?x y) + + [::&a/jvm-lshr ?x y] + (&&host/compile-jvm-lshr compile-expression ?type ?x y) + + [::&a/jvm-lushr ?x y] + (&&host/compile-jvm-lushr compile-expression ?type ?x y) + ) _ (fail "[Compiler Error] Can't compile statements as expressions."))) diff --git a/src/lux/compiler/host.clj b/src/lux/compiler/host.clj index 9805d2c70..18695522d 100644 --- a/src/lux/compiler/host.clj +++ b/src/lux/compiler/host.clj @@ -204,6 +204,20 @@ :let [_ (.visitInsn *writer* Opcodes/ACONST_NULL)]] (return nil))) +(defn compile-jvm-null? [compile *type* ?object] + (exec [*writer* &/get-writer + _ (compile ?object) + :let [$then (new Label) + $end (new Label) + _ (doto *writer* + (.visitJumpInsn Opcodes/IFNULL $then) + (.visitFieldInsn Opcodes/GETSTATIC (&host/->class "java.lang.Boolean") "FALSE" (&host/->type-signature "java.lang.Boolean")) + (.visitJumpInsn Opcodes/GOTO $end) + (.visitLabel $then) + (.visitFieldInsn Opcodes/GETSTATIC (&host/->class "java.lang.Boolean") "TRUE" (&host/->type-signature "java.lang.Boolean")) + (.visitLabel $end))]] + (return nil))) + (defn compile-jvm-new [compile *type* ?class ?classes ?args] (exec [*writer* &/get-writer :let [init-sig (str "(" (reduce str "" (map &host/->type-signature ?classes)) ")V") @@ -301,3 +315,119 @@ (butlast ?exprs)) _ (compile (last ?exprs))] (return nil))) + +(defn compile-jvm-try [compile *type* ?body ?catches ?finally] + (exec [*writer* &/get-writer + :let [$from (new Label) + $to (new Label) + $end (new Label) + $catch-finally (new Label) + compile-finally (if ?finally + (exec [_ (return nil) + _ (compile ?finally) + :let [_ (doto *writer* + (.visitInsn Opcodes/POP) + (.visitJumpInsn Opcodes/GOTO $end))]] + (return nil)) + (exec [_ (return nil) + :let [_ (.visitJumpInsn *writer* Opcodes/GOTO $end)]] + (return nil))) + _ (.visitLabel *writer* $from)] + _ (compile ?body) + :let [_ (.visitLabel *writer* $to)] + _ compile-finally + handlers (map-m (fn [[?ex-class ?ex-arg ?catch-body]] + (exec [:let [$handler-start (new Label) + $handler-end (new Label)] + _ (compile ?catch-body) + :let [_ (.visitLabel *writer* $handler-end)] + _ compile-finally] + (return [?ex-class $handler-start $handler-end]))) + ?catches) + :let [_ (.visitLabel *writer* $catch-finally)] + _ (if ?finally + (exec [_ (compile ?finally) + :let [_ (doto *writer* + (.visitInsn Opcodes/POP) + (.visitInsn Opcodes/ATHROW))]] + (return nil)) + (exec [_ (return nil) + :let [_ (.visitInsn *writer* Opcodes/ATHROW)]] + (return nil))) + :let [_ (.visitJumpInsn *writer* Opcodes/GOTO $end)] + :let [_ (.visitLabel *writer* $end)] + :let [_ (doseq [[?ex-class $handler-start $handler-end] handlers] + (doto *writer* + (.visitTryCatchBlock $from $to $handler-start ?ex-class) + (.visitTryCatchBlock $handler-start $handler-end $catch-finally nil)) + ) + _ (.visitTryCatchBlock *writer* $from $to $catch-finally nil)]] + (return nil))) + +(defn compile-jvm-throw [compile *type* ?ex] + (exec [*writer* &/get-writer + _ (compile ?ex) + :let [_ (.visitInsn *writer* Opcodes/ATHROW)]] + (return nil))) + +(do-template [<name> <op>] + (defn <name> [compile *type* ?monitor] + (exec [*writer* &/get-writer + _ (compile ?monitor) + :let [_ (doto *writer* + (.visitInsn <op>) + (.visitInsn Opcodes/ACONST_NULL))]] + (return nil))) + + compile-jvm-monitorenter Opcodes/MONITORENTER + compile-jvm-monitorexit Opcodes/MONITOREXIT + ) + +(do-template [<name> <op> <from-class> <to-class>] + (defn <name> [compile *type* ?value] + (exec [*writer* &/get-writer + _ (compile ?value) + :let [_ (doto *writer* + (.visitInsn <op>))]] + (return nil))) + + compile-jvm-d2f Opcodes/D2F "java.lang.Double" "java.lang.Float" + compile-jvm-d2i Opcodes/D2I "java.lang.Double" "java.lang.Integer" + compile-jvm-d2l Opcodes/D2L "java.lang.Double" "java.lang.Long" + + compile-jvm-f2d Opcodes/F2D "java.lang.Float" "java.lang.Double" + compile-jvm-f2i Opcodes/F2I "java.lang.Float" "java.lang.Integer" + compile-jvm-f2l Opcodes/F2L "java.lang.Float" "java.lang.Long" + + compile-jvm-i2b Opcodes/I2B "java.lang.Integer" "java.lang.Byte" + compile-jvm-i2c Opcodes/I2C "java.lang.Integer" "java.lang.Character" + compile-jvm-i2d Opcodes/I2D "java.lang.Integer" "java.lang.Double" + compile-jvm-i2f Opcodes/I2F "java.lang.Integer" "java.lang.Float" + compile-jvm-i2l Opcodes/I2L "java.lang.Integer" "java.lang.Long" + compile-jvm-i2s Opcodes/I2S "java.lang.Integer" "java.lang.Short" + + compile-jvm-l2d Opcodes/L2D "java.lang.Long" "java.lang.Double" + compile-jvm-l2f Opcodes/L2F "java.lang.Long" "java.lang.Float" + compile-jvm-l2i Opcodes/L2I "java.lang.Long" "java.lang.Integer" + ) + +(do-template [<name> <op> <from-class> <to-class>] + (defn <name> [compile *type* ?x ?y] + (exec [*writer* &/get-writer + _ (compile ?x) + _ (compile ?y) + :let [_ (doto *writer* + (.visitInsn <op>))]] + (return nil))) + + compile-jvm-iand Opcodes/IAND "java.lang.Integer" "java.lang.Integer" + compile-jvm-ior Opcodes/IOR "java.lang.Integer" "java.lang.Integer" + + compile-jvm-land Opcodes/LAND "java.lang.Long" "java.lang.Long" + compile-jvm-lor Opcodes/LOR "java.lang.Long" "java.lang.Long" + compile-jvm-lxor Opcodes/LXOR "java.lang.Long" "java.lang.Long" + + compile-jvm-lshl Opcodes/LSHL "java.lang.Long" "java.lang.Integer" + compile-jvm-lshr Opcodes/LSHR "java.lang.Long" "java.lang.Integer" + compile-jvm-lushr Opcodes/LUSHR "java.lang.Long" "java.lang.Integer" + ) |