aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEduardo Julian2017-02-26 14:27:10 -0400
committerEduardo Julian2017-02-26 14:27:10 -0400
commit00cf2f245faf3ef3148bd58aa3503339be17f80d (patch)
tree85af71581bf1eef5fac55cb4d2bb79906520521a
parentc8dc7ef9af9873fa64e8a97ef0d78a0725399bab (diff)
- Implemented bitwise operations in JS.
-rw-r--r--luxc/src/lux/compiler/js/proc/common.clj90
-rw-r--r--luxc/src/lux/compiler/js/rt.clj72
2 files changed, 107 insertions, 55 deletions
diff --git a/luxc/src/lux/compiler/js/proc/common.clj b/luxc/src/lux/compiler/js/proc/common.clj
index 1522cf4ca..60ade9300 100644
--- a/luxc/src/lux/compiler/js/proc/common.clj
+++ b/luxc/src/lux/compiler/js/proc/common.clj
@@ -14,54 +14,34 @@
[lux :as &&lux])))
;; [Resources]
-;; (do-template [<name> <op>]
-;; (defn <name> [compile ?values special-args]
-;; (|do [:let [(&/$Cons ?input (&/$Cons ?mask (&/$Nil))) ?values]
-;; ^MethodVisitor *writer* &/get-writer
-;; _ (compile ?input)
-;; :let [_ (&&/unwrap-long *writer*)]
-;; _ (compile ?mask)
-;; :let [_ (&&/unwrap-long *writer*)]
-;; :let [_ (doto *writer*
-;; (.visitInsn <op>)
-;; &&/wrap-long)]]
-;; (return nil)))
-
-;; ^:private compile-bit-and Opcodes/LAND
-;; ^:private compile-bit-or Opcodes/LOR
-;; ^:private compile-bit-xor Opcodes/LXOR
-;; )
-
-;; (defn ^:private compile-bit-count [compile ?values special-args]
-;; (|do [:let [(&/$Cons ?input (&/$Nil)) ?values]
-;; ^MethodVisitor *writer* &/get-writer
-;; _ (compile ?input)
-;; :let [_ (&&/unwrap-long *writer*)]
-;; :let [_ (doto *writer*
-;; (.visitMethodInsn Opcodes/INVOKESTATIC "java/lang/Long" "bitCount" "(J)I")
-;; (.visitInsn Opcodes/I2L)
-;; &&/wrap-long)]]
-;; (return nil)))
+(do-template [<name> <op>]
+ (defn <name> [compile ?values special-args]
+ (|do [:let [(&/$Cons ?input (&/$Cons ?param (&/$Nil))) ?values]
+ =input (compile ?input)
+ =param (compile ?param)]
+ (return (str "LuxRT." <op> "(" =input "," =param ")"))))
+
+ ^:private compile-bit-and "andI64"
+ ^:private compile-bit-or "orI64"
+ ^:private compile-bit-xor "xorI64"
+ )
-;; (do-template [<name> <op>]
-;; (defn <name> [compile ?values special-args]
-;; (|do [:let [(&/$Cons ?input (&/$Cons ?shift (&/$Nil))) ?values]
-;; ^MethodVisitor *writer* &/get-writer
-;; _ (compile ?input)
-;; :let [_ (&&/unwrap-long *writer*)]
-;; _ (compile ?shift)
-;; :let [_ (doto *writer*
-;; &&/unwrap-long
-;; (.visitInsn Opcodes/L2I))]
-;; :let [_ (doto *writer*
-;; (.visitInsn <op>)
-;; &&/wrap-long)]]
-;; (return nil)))
+(do-template [<name> <op>]
+ (defn <name> [compile ?values special-args]
+ (|do [:let [(&/$Cons ?input (&/$Cons ?param (&/$Nil))) ?values]
+ =input (compile ?input)
+ =param (compile ?param)]
+ (return (str "LuxRT." <op> "(" =input "," =param ".L)"))))
+
+ ^:private compile-bit-shift-left "shlI64"
+ ^:private compile-bit-shift-right "shrI64"
+ ^:private compile-bit-unsigned-shift-right "ushlI64"
+ )
-;; ^:private compile-bit-shift-left Opcodes/LSHL
-;; ^:private compile-bit-shift-right Opcodes/LSHR
-;; ^:private compile-bit-unsigned-shift-right Opcodes/LUSHR
-;; )
+(defn ^:private compile-bit-count [compile ?values special-args]
+ (|do [:let [(&/$Cons ?input (&/$Nil)) ?values]
+ =input (compile ?input)]
+ (return (str "LuxRT.countI64(" =input ")"))))
(defn ^:private compile-lux-is [compile ?values special-args]
(|do [:let [(&/$Cons ?left (&/$Cons ?right (&/$Nil))) ?values]
@@ -488,15 +468,15 @@
"contains?" (compile-text-contains? compile ?values special-args)
)
- ;; "bit"
- ;; (case proc
- ;; "count" (compile-bit-count compile ?values special-args)
- ;; "and" (compile-bit-and compile ?values special-args)
- ;; "or" (compile-bit-or compile ?values special-args)
- ;; "xor" (compile-bit-xor compile ?values special-args)
- ;; "shift-left" (compile-bit-shift-left compile ?values special-args)
- ;; "shift-right" (compile-bit-shift-right compile ?values special-args)
- ;; "unsigned-shift-right" (compile-bit-unsigned-shift-right compile ?values special-args))
+ "bit"
+ (case proc
+ "count" (compile-bit-count compile ?values special-args)
+ "and" (compile-bit-and compile ?values special-args)
+ "or" (compile-bit-or compile ?values special-args)
+ "xor" (compile-bit-xor compile ?values special-args)
+ "shift-left" (compile-bit-shift-left compile ?values special-args)
+ "shift-right" (compile-bit-shift-right compile ?values special-args)
+ "unsigned-shift-right" (compile-bit-unsigned-shift-right compile ?values special-args))
"array"
(case proc
diff --git a/luxc/src/lux/compiler/js/rt.clj b/luxc/src/lux/compiler/js/rt.clj
index cc00e2908..2416445e5 100644
--- a/luxc/src/lux/compiler/js/rt.clj
+++ b/luxc/src/lux/compiler/js/rt.clj
@@ -1304,6 +1304,77 @@
"})")
})
+(def ^:private bit-methods
+ (let [make-basic-op (fn [op]
+ (str "(function andI64(input,mask) {"
+ "return LuxRT.makeI64(input.H " op " mask.H, input.L " op " mask.L);"
+ "})"))]
+ {"andI64" (make-basic-op "&")
+ "orI64" (make-basic-op "|")
+ "xorI64" (make-basic-op "^")
+ "countI64" (str "(function countI64(input) {"
+ "var hs = (input.H).toString(2);"
+ "var ls = (input.L).toString(2);"
+ "var num1s = hs.concat(ls).replace('0','').length;"
+ "return LuxRT.fromNumberI64(num1s);"
+ "})")
+ "shlI64" (str "(function shlI64(input,shift) {"
+ "shift &= 63;"
+ (str "if(shift === 0) {"
+ "return input;"
+ "}"
+ "else {"
+ (str "if (shift < 32) {"
+ "var high = (input.H << shift) | (input.L >>> (32 - shift));"
+ "var low = input.L << shift;"
+ "return LuxRT.makeI64(high, low);"
+ "}"
+ "else {"
+ "var high = (input.L << (shift - 32));"
+ "return LuxRT.makeI64(high, 0);"
+ "}")
+ "}")
+ "})")
+ "shrI64" (str "(function shrI64(input,shift) {"
+ "shift &= 63;"
+ (str "if(shift === 0) {"
+ "return input;"
+ "}"
+ "else {"
+ (str "if (shift < 32) {"
+ "var high = input.H >> shift;"
+ "var low = (input.L >>> shift) | (input.H << (32 - shift));"
+ "return LuxRT.makeI64(high, low);"
+ "}"
+ "else {"
+ "var low = (input.H >> (shift - 32));"
+ "var high = input.H >= 0 ? 0 : -1;"
+ "return LuxRT.makeI64(high, low);"
+ "}")
+ "}")
+ "})")
+ "ushrI64" (str "(function ushrI64(input,shift) {"
+ "shift &= 63;"
+ (str "if(shift === 0) {"
+ "return input;"
+ "}"
+ "else {"
+ (str "if (shift < 32) {"
+ "var high = input.H >>> shift;"
+ "var low = (input.L >>> shift) | (input.H << (32 - shift));"
+ "return LuxRT.makeI64(high, low);"
+ "}"
+ "else if(shift === 32) {"
+ "return LuxRT.makeI64(0, input.H);"
+ "}"
+ "else {"
+ "var low = (input.H >>> (shift - 32));"
+ "return LuxRT.makeI64(0, low);"
+ "}")
+ "}")
+ "})")
+ }))
+
(def LuxRT "LuxRT")
(def compile-LuxRT
@@ -1313,6 +1384,7 @@
n64-methods
text-methods
array-methods
+ bit-methods
io-methods)
(map (fn [[key val]]
(str key ":" val)))