diff options
Diffstat (limited to 'luxc/src/lux/compiler/js/rt.clj')
-rw-r--r-- | luxc/src/lux/compiler/js/rt.clj | 173 |
1 files changed, 135 insertions, 38 deletions
diff --git a/luxc/src/lux/compiler/js/rt.clj b/luxc/src/lux/compiler/js/rt.clj index 3c9186a1e..194248f10 100644 --- a/luxc/src/lux/compiler/js/rt.clj +++ b/luxc/src/lux/compiler/js/rt.clj @@ -936,58 +936,155 @@ ;; (.visitEnd)))] ;; nil))) +(def ^:private i64-methods + {"makeI64" (str "(function makeI64(high,low) {" + "return { H: (high|0), L: (low|0)};" + "})") + "notI64" (str "(function notI64(i64) {" + "return LuxRT.makeI64(~i64.H,~i64.L);" + "})") + "negateI64" (str "(function negateI64(i64) {" + "return LuxRT.addI64(LuxRT.notI64(i64),LuxRT.makeI64(0,1));" + "})") + "eqI64" (str "(function eqI64(l,r) {" + "return (l.H === r.H) && (l.L === r.L);" + "})") + "addI64" (str "(function addI64(l,r) {" + "var l48 = l.H >>> 16;" + "var l32 = l.H & 0xFFFF;" + "var l16 = l.L >>> 16;" + "var l00 = l.L & 0xFFFF;" + + "var r48 = r.H >>> 16;" + "var r32 = r.H & 0xFFFF;" + "var r16 = r.L >>> 16;" + "var r00 = r.L & 0xFFFF;" + + "var x48 = 0, x32 = 0, x16 = 0, x00 = 0;" + "x00 += l00 + r00;" + "x16 += x00 >>> 16;" + "x00 &= 0xFFFF;" + "x16 += l16 + r16;" + "x32 += x16 >>> 16;" + "x16 &= 0xFFFF;" + "x32 += l32 + r32;" + "x48 += x32 >>> 16;" + "x32 &= 0xFFFF;" + "x48 += l48 + r48;" + "x48 &= 0xFFFF;" + + "return LuxRT.makeI64((x48 << 16) | x32, (x16 << 16) | x00);" + "})") + "subI64" (str "(function subI64(l,r) {" + "return LuxRT.addI64(l,LuxRT.negateI64(r));" + "})") + "mulI64" (str "(function mulI64(l,r) {" + "if (l.H < 0) {" + (str "if (r.H < 0) {" + ;; Both are negative + "return mulI64(LuxRT.negateI64(l),LuxRT.negateI64(r));" + "}" + "else {" + ;; Left is negative + "return LuxRT.negateI64(mulI64(LuxRT.negateI64(l),r));" + "}") + "}" + "else if (r.H < 0) {" + ;; Right is negative + "return LuxRT.negateI64(mulI64(l,LuxRT.negateI64(r)));" + "}" + ;; Both are positive + "else {" + "var l48 = l.H >>> 16;" + "var l32 = l.H & 0xFFFF;" + "var l16 = l.L >>> 16;" + "var l00 = l.L & 0xFFFF;" + + "var r48 = r.H >>> 16;" + "var r32 = r.H & 0xFFFF;" + "var r16 = r.L >>> 16;" + "var r00 = r.L & 0xFFFF;" + + "var x48 = 0, x32 = 0, x16 = 0, x00 = 0;" + "x00 += l00 * r00;" + "x16 += x00 >>> 16;" + "x00 &= 0xFFFF;" + "x16 += l16 * r00;" + "x32 += x16 >>> 16;" + "x16 &= 0xFFFF;" + "x16 += l00 * r16;" + "x32 += x16 >>> 16;" + "x16 &= 0xFFFF;" + "x32 += l32 * r00;" + "x48 += x32 >>> 16;" + "x32 &= 0xFFFF;" + "x32 += l16 * r16;" + "x48 += x32 >>> 16;" + "x32 &= 0xFFFF;" + "x32 += l00 * r32;" + "x48 += x32 >>> 16;" + "x32 &= 0xFFFF;" + "x48 += (l48 * r00) + (l32 * r16) + (l16 * r32) + (l00 * r48);" + "x48 &= 0xFFFF;" + + "return LuxRT.makeI64((x48 << 16) | x32, (x16 << 16) | x00);" + "}" + "})") + }) + (def ^:private adt-methods - {:product_getLeft (str "(function product_getLeft(product,index) {" - "var index_min_length = (index+1);" - "if(product.length > index_min_length) {" - ;; No need for recursion - "return product[index];" - "}" - "else {" - ;; Needs recursion - "return product_getLeft(product[product.length - 1], (index_min_length - product.length));" - "}" - "})") - :product_getRight (str "(function product_getRight(product,index) {" + {"product_getLeft" (str "(function product_getLeft(product,index) {" "var index_min_length = (index+1);" - "if(product.length === index_min_length) {" - ;; Last element. + "if(product.length > index_min_length) {" + ;; No need for recursion "return product[index];" "}" - "else if(product.length < index_min_length) {" - ;; Needs recursion - "return product_getRight(product[product.length - 1], (index_min_length - product.length));" - "}" "else {" - ;; Must slice - "return product.slice(index);" + ;; Needs recursion + "return product_getLeft(product[product.length - 1], (index_min_length - product.length));" "}" "})") - :sum_get (str "(function sum_get(sum,wantedTag,wantsLast) {" - "if(sum[0] === wantedTag && sum[1] === wantsLast) {" - ;; Exact match. - "return sum[2];" - "}" - "else if(sum[0] < wantedTag || sum[1] !== wantsLast) {" - "if(sum[1]) {" - ;; Must recurse. - "return sum_get(sum[2], (wantedTag - sum[0]), wantsLast);" - "}" - ;; No match. - "else { return null; }" - "}" - ;; No match. - "else { return null; }" - "})") + "product_getRight" (str "(function product_getRight(product,index) {" + "var index_min_length = (index+1);" + "if(product.length === index_min_length) {" + ;; Last element. + "return product[index];" + "}" + "else if(product.length < index_min_length) {" + ;; Needs recursion + "return product_getRight(product[product.length - 1], (index_min_length - product.length));" + "}" + "else {" + ;; Must slice + "return product.slice(index);" + "}" + "})") + "sum_get" (str "(function sum_get(sum,wantedTag,wantsLast) {" + "if(sum[0] === wantedTag && sum[1] === wantsLast) {" + ;; Exact match. + "return sum[2];" + "}" + "else if(sum[0] < wantedTag || sum[1] !== wantsLast) {" + "if(sum[1]) {" + ;; Must recurse. + "return sum_get(sum[2], (wantedTag - sum[0]), wantsLast);" + "}" + ;; No match. + "else { return null; }" + "}" + ;; No match. + "else { return null; }" + "})") }) (def LuxRT "LuxRT") (def compile-LuxRT (|do [_ (return nil) - :let [rt-object (str "{" (->> adt-methods + :let [rt-object (str "{" (->> (merge adt-methods + i64-methods) (map (fn [[key val]] - (str (name key) ":" val))) + (str key ":" val))) (interpose ",") (reduce str "")) "}")]] |