From 00cf2f245faf3ef3148bd58aa3503339be17f80d Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Sun, 26 Feb 2017 14:27:10 -0400 Subject: - Implemented bitwise operations in JS. --- luxc/src/lux/compiler/js/proc/common.clj | 90 +++++++++++++------------------- luxc/src/lux/compiler/js/rt.clj | 72 +++++++++++++++++++++++++ 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 [ ] -;; (defn [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 ) -;; &&/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 [ ] + (defn [compile ?values special-args] + (|do [:let [(&/$Cons ?input (&/$Cons ?param (&/$Nil))) ?values] + =input (compile ?input) + =param (compile ?param)] + (return (str "LuxRT." "(" =input "," =param ")")))) + + ^:private compile-bit-and "andI64" + ^:private compile-bit-or "orI64" + ^:private compile-bit-xor "xorI64" + ) -;; (do-template [ ] -;; (defn [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 ) -;; &&/wrap-long)]] -;; (return nil))) +(do-template [ ] + (defn [compile ?values special-args] + (|do [:let [(&/$Cons ?input (&/$Cons ?param (&/$Nil))) ?values] + =input (compile ?input) + =param (compile ?param)] + (return (str "LuxRT." "(" =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))) -- cgit v1.2.3