diff options
author | Eduardo Julian | 2017-05-07 02:36:32 -0400 |
---|---|---|
committer | Eduardo Julian | 2017-05-07 02:36:32 -0400 |
commit | 42848dd5a3b2e1d02752201343e18f075a733645 (patch) | |
tree | 83ed869a644adfa5b14137da07073df080abfce1 /luxc/src | |
parent | dda9e7b3f998e7649104d478469b8a27c3c981ba (diff) |
- Fully implemented Deg encoding/decoding in pure Lux.
- No longer relying in LuxRT-supported implementations.
Diffstat (limited to 'luxc/src')
-rw-r--r-- | luxc/src/lux/analyser/proc/common.clj | 3 | ||||
-rw-r--r-- | luxc/src/lux/compiler/js/proc/common.clj | 5 | ||||
-rw-r--r-- | luxc/src/lux/compiler/js/rt.clj | 112 | ||||
-rw-r--r-- | luxc/src/lux/compiler/jvm/proc/common.clj | 25 | ||||
-rw-r--r-- | luxc/src/lux/compiler/jvm/rt.clj | 518 |
5 files changed, 1 insertions, 662 deletions
diff --git a/luxc/src/lux/analyser/proc/common.clj b/luxc/src/lux/analyser/proc/common.clj index 842efc9c5..b6727ff53 100644 --- a/luxc/src/lux/analyser/proc/common.clj +++ b/luxc/src/lux/analyser/proc/common.clj @@ -254,7 +254,6 @@ (return (&/|list (&&/|meta exo-type _cursor (&&/$proc (&/T <decode-op>) (&/|list =x) (&/|list))))))))) - ^:private analyse-deg-encode ["deg" "encode"] ^:private analyse-deg-decode ["deg" "decode"] &type/Deg ^:private analyse-real-encode ["real" "encode"] ^:private analyse-real-decode ["real" "decode"] &type/Real ) @@ -572,8 +571,6 @@ "%" (analyse-deg-rem analyse exo-type ?values) "=" (analyse-deg-eq analyse exo-type ?values) "<" (analyse-deg-lt analyse exo-type ?values) - "encode" (analyse-deg-encode analyse exo-type ?values) - "decode" (analyse-deg-decode analyse exo-type ?values) "min-value" (analyse-deg-min-value analyse exo-type ?values) "max-value" (analyse-deg-max-value analyse exo-type ?values) "to-real" (analyse-deg-to-real analyse exo-type ?values) diff --git a/luxc/src/lux/compiler/js/proc/common.clj b/luxc/src/lux/compiler/js/proc/common.clj index eb4e27857..2f872676e 100644 --- a/luxc/src/lux/compiler/js/proc/common.clj +++ b/luxc/src/lux/compiler/js/proc/common.clj @@ -148,9 +148,6 @@ (return (str "LuxRT$" <method> "(" =x ")")) )) - ^:private compile-deg-encode "encodeD64" - ^:private compile-deg-decode "decodeD64" - ^:private compile-real-decode "decodeReal" ) @@ -526,8 +523,6 @@ "%" (compile-deg-rem compile ?values special-args) "=" (compile-deg-eq compile ?values special-args) "<" (compile-deg-lt compile ?values special-args) - "encode" (compile-deg-encode compile ?values special-args) - "decode" (compile-deg-decode compile ?values special-args) "max-value" (compile-deg-max-value compile ?values special-args) "min-value" (compile-deg-min-value compile ?values special-args) "to-real" (compile-deg-to-real compile ?values special-args) diff --git a/luxc/src/lux/compiler/js/rt.clj b/luxc/src/lux/compiler/js/rt.clj index d5f503f01..838598bbb 100644 --- a/luxc/src/lux/compiler/js/rt.clj +++ b/luxc/src/lux/compiler/js/rt.clj @@ -650,118 +650,6 @@ "var high = shifted | 0;" "return LuxRT$makeI64(high,low);" "})") - "_add_deg_digit_powers" (str "(function LuxRT$_add_deg_digit_powers(left,right) {" - "var output = new Array(64);" - "var carry = 0;" - (str "for(var idx = 63; idx >= 0; idx--) {" - "var raw = left[idx] + right[idx] + carry;" - "output[idx] = raw % 10;" - "raw = (raw / 10)|0;" - "}") - "return output;" - "})") - "_times5" (str "(function LuxRT$_times5(exp,digits) {" - "var carry = 0;" - (str "for(var idx = exp; idx >= 0; idx--) {" - "var raw = (digits[exp] * 5) + carry;" - "digits[exp] = raw % 10;" - "carry = (raw / 10)|0;" - "}") - "return digits;" - "})") - "_deg_digit_power" (str "(function LuxRT$_deg_digit_power(exp) {" - "var digits = new Array(64);" - "digits[exp] = 1;" - (str "for(var idx = exp; idx >= 0; idx--) {" - "digits = LuxRT$_times5(exp,digits);" - "}") - "return digits;" - "})") - "_bitIsSet" (str "(function LuxRT$_bitIsSet(input,idx) {" - "idx &= 63;" - (str "if(idx < 32) {" - "return (input.L & (1 << idx)) !== 0;" - "}") - (str "else {" - "return (input.H & (1 << (idx - 32))) !== 0;" - "}") - "})") - "encodeD64" (str "(function LuxRT$encodeD64(input) {" - (str "if(LuxRT$eqI64(input,LuxRT$ZERO)) {" - "return '.0';" - "}") - "var digits = new Array(64);" - (str "for(var idx = 63; idx >= 0; idx--) {" - (str "if(LuxRT$_bitIsSet(input,idx)) {" - "var power = LuxRT$_deg_digit_power(63 - idx);" - "digits = LuxRT$_add_deg_digit_powers(digits,power);" - "}") - "}") - "var raw = '.'.concat(digits.join(''));" - "return raw.split(/0*$/)[0];" - "})") - "deg_text_to_digits" (str "(function LuxRT$deg_text_to_digits(input) {" - "var output = new Array(64);" - (str "for(var idx = input.length-1; idx >= 0; idx--) {" - "output[idx] = parseInt(input.substring(idx, idx+1));" - "}") - "return output;" - "})") - "deg_digits_lt" (str "(function LuxRT$deg_digits_lt(l,r) {" - (str "for(var idx = 0; idx < 64; idx++) {" - (str "if(l[idx] < r[idx]) {" - "return true;" - "}" - "else if(l[idx] > r[idx]) {" - "return false;" - "}") - "}") - "return false;" - "})") - "deg_digits_sub_once" (str "(function LuxRT$deg_digits_sub_once(target,digit,idx) {" - (str "while(true) {" - (str "if(target[idx] > digit) {" - (str "target[idx] = target[idx] - digit;" - "return target;") - "}" - "else {" - (str "target[idx] = 10 - (digit - target[idx]);" - "idx--;" - "digit=1;") - "}") - "}") - "})") - "deg_digits_sub" (str "(function LuxRT$deg_digits_sub(l,r) {" - (str "for(var idx = 63; idx >= 0; idx--) {" - "l = LuxRT$deg_digits_sub_once(l,r[idx],idx);" - "}") - "return l;" - "})") - "decodeD64" (let [failure (str "return " const-none ";")] - (str "(function LuxRT$decodeD64(input) {" - "input = LuxRT$clean_separators(input);" - (str "if(/^\\.\\d+$/.exec(input) && input.length <= 65) {" - (str "try {" - (str "var digits = LuxRT$deg_text_to_digits(input.substring(1));") - "var output = LuxRT$makeI64(0,0);" - (str "for(var idx = 0; idx < 64; idx++) {" - "var power = LuxRT$deg_text_to_digits(idx);" - (str "if(LuxRT$deg_digits_lt(power,digits)) {" - (str "digits = LuxRT$deg_digits_sub(digits,power);" - "var powerBit = LuxRT$shlI64(LuxRT$makeI64(0,1),(63-idx));" - "output = LuxRT$orI64(output,powerBit);") - "}") - "}") - (str "return " (make-some "output") ";") - "}" - "catch(ex) {" - failure - "}") - "}" - "else {" - failure - "}") - "})")) }) (def ^:private io-methods diff --git a/luxc/src/lux/compiler/jvm/proc/common.clj b/luxc/src/lux/compiler/jvm/proc/common.clj index b616f4bdf..1fe49d227 100644 --- a/luxc/src/lux/compiler/jvm/proc/common.clj +++ b/luxc/src/lux/compiler/jvm/proc/common.clj @@ -387,29 +387,6 @@ ^:private compile-real-negative-infinity (.visitLdcInsn Double/NEGATIVE_INFINITY) &&/wrap-double ) -(do-template [<encode-name> <encode-method> <decode-name> <decode-method>] - (do (defn <encode-name> [compile ?values special-args] - (|do [:let [(&/$Cons ?x (&/$Nil)) ?values] - ^MethodVisitor *writer* &/get-writer - _ (compile ?x) - :let [_ (doto *writer* - &&/unwrap-long - (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" <encode-method> "(J)Ljava/lang/String;"))]] - (return nil))) - - (let [+wrapper-class+ (&host-generics/->bytecode-class-name "java.lang.String")] - (defn <decode-name> [compile ?values special-args] - (|do [:let [(&/$Cons ?x (&/$Nil)) ?values] - ^MethodVisitor *writer* &/get-writer - _ (compile ?x) - :let [_ (doto *writer* - (.visitTypeInsn Opcodes/CHECKCAST +wrapper-class+) - (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" <decode-method> "(Ljava/lang/String;)Ljava/lang/Object;"))]] - (return nil))))) - - ^:private compile-deg-encode "encode_deg" ^:private compile-deg-decode "decode_deg" - ) - (do-template [<name> <class> <signature> <unwrap>] (defn <name> [compile ?values special-args] (|do [:let [(&/$Cons ?input (&/$Nil)) ?values] @@ -958,8 +935,6 @@ "%" (compile-deg-rem compile ?values special-args) "=" (compile-deg-eq compile ?values special-args) "<" (compile-deg-lt compile ?values special-args) - "encode" (compile-deg-encode compile ?values special-args) - "decode" (compile-deg-decode compile ?values special-args) "max-value" (compile-deg-max-value compile ?values special-args) "min-value" (compile-deg-min-value compile ?values special-args) "to-real" (compile-deg-to-real compile ?values special-args) diff --git a/luxc/src/lux/compiler/jvm/rt.clj b/luxc/src/lux/compiler/jvm/rt.clj index aa0c881d0..31a2c800c 100644 --- a/luxc/src/lux/compiler/jvm/rt.clj +++ b/luxc/src/lux/compiler/jvm/rt.clj @@ -461,523 +461,7 @@ ;; FINISH (.visitInsn Opcodes/LRETURN) (.visitMaxs 0 0) - (.visitEnd)) - _ (let [$loop-start (new Label) - $do-a-round (new Label)] - (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "times5" "(I[B)[B" nil nil) - (.visitCode) - (.visitLdcInsn (int 0)) ;; {carry} - (.visitLabel $loop-start) - (.visitVarInsn Opcodes/ILOAD 0) - (.visitJumpInsn Opcodes/IFGE $do-a-round) - (.visitVarInsn Opcodes/ALOAD 1) - (.visitInsn Opcodes/ARETURN) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; {carry} - (.visitLabel $do-a-round) - (.visitVarInsn Opcodes/ALOAD 1) - (.visitVarInsn Opcodes/ILOAD 0) - (.visitInsn Opcodes/BALOAD) ;; {carry, current-digit} - (.visitLdcInsn (int 5)) - (.visitInsn Opcodes/IMUL) - (.visitInsn Opcodes/IADD) ;; {next-raw-digit} - (.visitInsn Opcodes/DUP) - (.visitLdcInsn (int 10)) - (.visitInsn Opcodes/IREM) ;; {next-raw-digit, next-digit} - (.visitVarInsn Opcodes/ALOAD 1) - (.visitVarInsn Opcodes/ILOAD 0) - swap2x1 - (.visitInsn Opcodes/BASTORE) ;; {next-raw-digit} - (.visitLdcInsn (int 10)) - (.visitInsn Opcodes/IDIV) ;; {next-carry} - ;; Decrement index - (.visitVarInsn Opcodes/ILOAD 0) - (.visitLdcInsn (int 1)) - (.visitInsn Opcodes/ISUB) - (.visitVarInsn Opcodes/ISTORE 0) - ;; Iterate - (.visitJumpInsn Opcodes/GOTO $loop-start) - (.visitMaxs 0 0) - (.visitEnd))) - _ (let [$loop-start (new Label) - $do-a-round (new Label)] - (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "deg_digit_power" "(I)[B" nil nil) - (.visitCode) - ;; Initialize digits array. - (.visitLdcInsn (int deg-bits)) - (.visitIntInsn Opcodes/NEWARRAY Opcodes/T_BYTE) ;; {digits} - (.visitInsn Opcodes/DUP) - (.visitVarInsn Opcodes/ILOAD 0) - (.visitLdcInsn (int 1)) - (.visitInsn Opcodes/BASTORE) ;; digits = 5^0 - (.visitVarInsn Opcodes/ASTORE 1) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - (.visitVarInsn Opcodes/ILOAD 0) ;; {times} - (.visitLabel $loop-start) - (.visitInsn Opcodes/DUP) - (.visitJumpInsn Opcodes/IFGE $do-a-round) - (.visitVarInsn Opcodes/ALOAD 1) - (.visitInsn Opcodes/ARETURN) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - (.visitLabel $do-a-round) - ;; {times} - (.visitVarInsn Opcodes/ILOAD 0) - (.visitVarInsn Opcodes/ALOAD 1) - (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "times5" "(I[B)[B") ;; {digits*5, times} - (.visitVarInsn Opcodes/ASTORE 1) ;; {times} - ;; Decrement index - (.visitLdcInsn (int 1)) - (.visitInsn Opcodes/ISUB) - ;; {times-1} - (.visitJumpInsn Opcodes/GOTO $loop-start) - (.visitMaxs 0 0) - (.visitEnd))) - _ (let [$loop-start (new Label) - $do-a-round (new Label)] - (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "add_deg_digit_powers" "([B[B)[B" nil nil) - (.visitCode) - (.visitLdcInsn (int (dec deg-bits))) - (.visitVarInsn Opcodes/ISTORE 2) ;; Index - (.visitLdcInsn (int deg-bits)) - (.visitIntInsn Opcodes/NEWARRAY Opcodes/T_BYTE) - (.visitVarInsn Opcodes/ASTORE 3) ;; added_digits - (.visitLdcInsn (int 0)) ;; {carry} - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; {carry} - (.visitLabel $loop-start) - (.visitVarInsn Opcodes/ILOAD 2) - (.visitJumpInsn Opcodes/IFGE $do-a-round) - ;; {carry} - (.visitVarInsn Opcodes/ALOAD 3) - (.visitInsn Opcodes/ARETURN) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; {carry} - (.visitLabel $do-a-round) - (.visitVarInsn Opcodes/ALOAD 0) - (.visitVarInsn Opcodes/ILOAD 2) - (.visitInsn Opcodes/BALOAD) ;; {carry, dL} - (.visitVarInsn Opcodes/ALOAD 1) - (.visitVarInsn Opcodes/ILOAD 2) - (.visitInsn Opcodes/BALOAD) ;; {carry, dL, dR} - (.visitInsn Opcodes/IADD) - (.visitInsn Opcodes/IADD) ;; {raw-next-digit} - (.visitInsn Opcodes/DUP) - (.visitLdcInsn (int 10)) - (.visitInsn Opcodes/IREM) ;; {raw-next-digit, next-digit} - (.visitVarInsn Opcodes/ALOAD 3) - (.visitVarInsn Opcodes/ILOAD 2) - swap2x1 - (.visitInsn Opcodes/BASTORE) ;; {raw-next-digit} - (.visitLdcInsn (int 10)) - (.visitInsn Opcodes/IDIV) ;; {next-carry} - ;; Decrement index - (.visitVarInsn Opcodes/ILOAD 2) - (.visitLdcInsn (int 1)) - (.visitInsn Opcodes/ISUB) - (.visitVarInsn Opcodes/ISTORE 2) - ;; Iterate - (.visitJumpInsn Opcodes/GOTO $loop-start) - (.visitMaxs 0 0) - (.visitEnd))) - _ (let [$loop-start (new Label) - $do-a-round (new Label)] - (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "deg_digits_to_text" "([B)Ljava/lang/String;" nil nil) - (.visitCode) - (.visitLdcInsn (int (dec deg-bits))) - (.visitVarInsn Opcodes/ISTORE 1) ;; Index - (.visitLdcInsn "") ;; {text} - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - (.visitLabel $loop-start) - (.visitVarInsn Opcodes/ILOAD 1) - (.visitJumpInsn Opcodes/IFGE $do-a-round) - (.visitInsn Opcodes/ARETURN) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - (.visitLabel $do-a-round) - (.visitVarInsn Opcodes/ALOAD 0) - (.visitVarInsn Opcodes/ILOAD 1) - (.visitInsn Opcodes/BALOAD) ;; {text, digit} - (.visitLdcInsn (int 10)) ;; {text, digit, radix} - (.visitMethodInsn Opcodes/INVOKESTATIC "java/lang/Character" "forDigit" "(II)C") ;; {text, digit-char} - (.visitMethodInsn Opcodes/INVOKESTATIC "java/lang/Character" "toString" "(C)Ljava/lang/String;") ;; {text, digit-char-text} - (.visitInsn Opcodes/SWAP) - (.visitMethodInsn Opcodes/INVOKEVIRTUAL "java/lang/String" "concat" "(Ljava/lang/String;)Ljava/lang/String;") - ;; Decrement index - (.visitVarInsn Opcodes/ILOAD 1) - (.visitLdcInsn (int 1)) - (.visitInsn Opcodes/ISUB) - (.visitVarInsn Opcodes/ISTORE 1) - ;; Iterate - (.visitJumpInsn Opcodes/GOTO $loop-start) - (.visitMaxs 0 0) - (.visitEnd))) - _ (let [$loop-start (new Label) - $do-a-round (new Label) - $not-set (new Label) - $next-iteration (new Label) - $normal-path (new Label)] - (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "encode_deg" "(J)Ljava/lang/String;" nil nil) - (.visitCode) - ;; A quick corner-case to handle. - (.visitVarInsn Opcodes/LLOAD 0) - (.visitLdcInsn (long 0)) - (.visitInsn Opcodes/LCMP) - (.visitJumpInsn Opcodes/IFNE $normal-path) - (.visitLdcInsn ".0") - (.visitInsn Opcodes/ARETURN) - (.visitLabel $normal-path) - ;; Normal case - (.visitLdcInsn (int (dec deg-bits))) - (.visitVarInsn Opcodes/ISTORE 2) ;; Index - (.visitLdcInsn (int deg-bits)) - (.visitIntInsn Opcodes/NEWARRAY Opcodes/T_BYTE) - (.visitVarInsn Opcodes/ASTORE 3) ;; digits - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - (.visitLabel $loop-start) - (.visitVarInsn Opcodes/ILOAD 2) - (.visitJumpInsn Opcodes/IFGE $do-a-round) - ;; Prepare text to return. - (.visitVarInsn Opcodes/ALOAD 3) - (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "deg_digits_to_text" "([B)Ljava/lang/String;") - (.visitLdcInsn ".") - (.visitInsn Opcodes/SWAP) - (.visitMethodInsn Opcodes/INVOKEVIRTUAL "java/lang/String" "concat" "(Ljava/lang/String;)Ljava/lang/String;") - ;; Trim unnecessary 0s at the end... - (.visitLdcInsn "0*$") - (.visitMethodInsn Opcodes/INVOKEVIRTUAL "java/lang/String" "split" "(Ljava/lang/String;)[Ljava/lang/String;") - (.visitLdcInsn (int 0)) - (.visitInsn Opcodes/AALOAD) - (.visitInsn Opcodes/ARETURN) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - (.visitLabel $do-a-round) - (.visitVarInsn Opcodes/LLOAD 0) - (.visitVarInsn Opcodes/ILOAD 2) - bit-set-64? - (.visitJumpInsn Opcodes/IFEQ $next-iteration) - (.visitLdcInsn (int (dec deg-bits))) - (.visitVarInsn Opcodes/ILOAD 2) - (.visitInsn Opcodes/ISUB) - (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "deg_digit_power" "(I)[B") - (.visitVarInsn Opcodes/ALOAD 3) - (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "add_deg_digit_powers" "([B[B)[B") - (.visitVarInsn Opcodes/ASTORE 3) - (.visitJumpInsn Opcodes/GOTO $next-iteration) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - (.visitLabel $next-iteration) - ;; Decrement index - (.visitVarInsn Opcodes/ILOAD 2) - (.visitLdcInsn (int 1)) - (.visitInsn Opcodes/ISUB) - (.visitVarInsn Opcodes/ISTORE 2) - ;; Iterate - (.visitJumpInsn Opcodes/GOTO $loop-start) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - (.visitMaxs 0 0) - (.visitEnd))) - _ (let [$loop-start (new Label) - $do-a-round (new Label) - $not-set (new Label) - $next-iteration (new Label)] - (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "deg_text_to_digits" "(Ljava/lang/String;)[B" nil nil) - (.visitCode) - (.visitVarInsn Opcodes/ALOAD 0) - (.visitMethodInsn Opcodes/INVOKEVIRTUAL "java/lang/String" "length" "()I") - (.visitLdcInsn (int 1)) - (.visitInsn Opcodes/ISUB) - (.visitVarInsn Opcodes/ISTORE 1) ;; Index - (.visitLdcInsn (int deg-bits)) - (.visitIntInsn Opcodes/NEWARRAY Opcodes/T_BYTE) - (.visitVarInsn Opcodes/ASTORE 2) ;; digits - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - (.visitLabel $loop-start) - (.visitVarInsn Opcodes/ILOAD 1) - (.visitJumpInsn Opcodes/IFGE $do-a-round) - (.visitVarInsn Opcodes/ALOAD 2) - (.visitInsn Opcodes/ARETURN) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - (.visitLabel $do-a-round) - (.visitVarInsn Opcodes/ALOAD 0) - (.visitVarInsn Opcodes/ILOAD 1) - (.visitVarInsn Opcodes/ILOAD 1) - (.visitLdcInsn (int 1)) - (.visitInsn Opcodes/IADD) - (.visitMethodInsn Opcodes/INVOKEVIRTUAL "java/lang/String" "substring" "(II)Ljava/lang/String;") - (.visitMethodInsn Opcodes/INVOKESTATIC "java/lang/Byte" "parseByte" "(Ljava/lang/String;)B") - ;; Set digit - (.visitVarInsn Opcodes/ALOAD 2) - (.visitVarInsn Opcodes/ILOAD 1) - swap2x1 - (.visitInsn Opcodes/BASTORE) - ;; Decrement index - (.visitVarInsn Opcodes/ILOAD 1) - (.visitLdcInsn (int 1)) - (.visitInsn Opcodes/ISUB) - (.visitVarInsn Opcodes/ISTORE 1) - ;; Iterate - (.visitJumpInsn Opcodes/GOTO $loop-start) - (.visitMaxs 0 0) - (.visitEnd))) - _ (let [$loop-start (new Label) - $do-a-round (new Label) - $is-less-than (new Label) - $is-equal (new Label)] - ;; [B0 <= [B1 - (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "deg_digits_lt" "([B[B)Z" nil nil) - (.visitCode) - (.visitLdcInsn (int 0)) - (.visitVarInsn Opcodes/ISTORE 2) ;; Index - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - (.visitLabel $loop-start) - (.visitVarInsn Opcodes/ILOAD 2) - (.visitLdcInsn (int deg-bits)) - (.visitJumpInsn Opcodes/IF_ICMPLT $do-a-round) - (.visitLdcInsn false) - (.visitInsn Opcodes/IRETURN) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - (.visitLabel $do-a-round) - (.visitVarInsn Opcodes/ALOAD 0) - (.visitVarInsn Opcodes/ILOAD 2) - (.visitInsn Opcodes/BALOAD) ;; {D0} - (.visitVarInsn Opcodes/ALOAD 1) - (.visitVarInsn Opcodes/ILOAD 2) - (.visitInsn Opcodes/BALOAD) ;; {D0, D1} - (.visitInsn Opcodes/DUP2) - (.visitJumpInsn Opcodes/IF_ICMPLT $is-less-than) - (.visitJumpInsn Opcodes/IF_ICMPEQ $is-equal) - ;; Is greater than... - (.visitLdcInsn false) - (.visitInsn Opcodes/IRETURN) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - (.visitLabel $is-less-than) - (.visitInsn Opcodes/POP2) - (.visitLdcInsn true) - (.visitInsn Opcodes/IRETURN) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - (.visitLabel $is-equal) - ;; Increment index - (.visitVarInsn Opcodes/ILOAD 2) - (.visitLdcInsn (int 1)) - (.visitInsn Opcodes/IADD) - (.visitVarInsn Opcodes/ISTORE 2) - ;; Iterate - (.visitJumpInsn Opcodes/GOTO $loop-start) - (.visitMaxs 0 0) - (.visitEnd))) - _ (let [$loop-start (new Label) - $do-a-round (new Label) - $simple-sub (new Label)] - (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "deg_digits_sub_once" "([BBI)[B" nil nil) - (.visitCode) - (.visitLabel $loop-start) - (.visitVarInsn Opcodes/ALOAD 0) - (.visitVarInsn Opcodes/ILOAD 2) ;; {target-digit} - (.visitInsn Opcodes/BALOAD) - (.visitVarInsn Opcodes/ILOAD 1) ;; {target-digit, param-digit} - (.visitInsn Opcodes/DUP2) - (.visitJumpInsn Opcodes/IF_ICMPGE $simple-sub) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Since $0 < $1 - (.visitInsn Opcodes/SWAP) - (.visitInsn Opcodes/ISUB) ;; $1 - $0 - (.visitLdcInsn (byte 10)) - (.visitInsn Opcodes/SWAP) - (.visitInsn Opcodes/ISUB) ;; 10 - ($1 - $0) - (.visitVarInsn Opcodes/ALOAD 0) - (.visitVarInsn Opcodes/ILOAD 2) - swap2x1 - (.visitInsn Opcodes/BASTORE) - ;; Prepare to iterate... - ;; Decrement index - (.visitVarInsn Opcodes/ILOAD 2) - (.visitLdcInsn (int 1)) - (.visitInsn Opcodes/ISUB) - (.visitVarInsn Opcodes/ISTORE 2) - ;; Subtract 1 from next digit - (.visitLdcInsn (int 1)) - (.visitVarInsn Opcodes/ISTORE 1) - ;; Iterate - (.visitJumpInsn Opcodes/GOTO $loop-start) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - (.visitLabel $simple-sub) - (.visitInsn Opcodes/ISUB) - (.visitVarInsn Opcodes/ALOAD 0) - (.visitVarInsn Opcodes/ILOAD 2) - swap2x1 - (.visitInsn Opcodes/BASTORE) - (.visitVarInsn Opcodes/ALOAD 0) - (.visitInsn Opcodes/ARETURN) - (.visitMaxs 0 0) - (.visitEnd))) - _ (let [$loop-start (new Label) - $do-a-round (new Label)] - (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "deg_digits_sub" "([B[B)[B" nil nil) - (.visitCode) - (.visitLdcInsn (int (dec deg-bits))) - (.visitVarInsn Opcodes/ISTORE 2) ;; Index - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - (.visitLabel $loop-start) - (.visitVarInsn Opcodes/ILOAD 2) - (.visitJumpInsn Opcodes/IFGE $do-a-round) - (.visitVarInsn Opcodes/ALOAD 0) - (.visitInsn Opcodes/ARETURN) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - (.visitLabel $do-a-round) - (.visitVarInsn Opcodes/ALOAD 0) ;; {target-digits} - (.visitVarInsn Opcodes/ALOAD 1) - (.visitVarInsn Opcodes/ILOAD 2) - (.visitInsn Opcodes/BALOAD) ;; {target-digits, param-digit} - (.visitVarInsn Opcodes/ILOAD 2) ;; {target-digits, param-digit, idx} - (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "deg_digits_sub_once" "([BBI)[B") - (.visitVarInsn Opcodes/ASTORE 0) ;; Update target digits - ;; Decrement index - (.visitVarInsn Opcodes/ILOAD 2) - (.visitLdcInsn (int 1)) - (.visitInsn Opcodes/ISUB) - (.visitVarInsn Opcodes/ISTORE 2) - ;; Iterate - (.visitJumpInsn Opcodes/GOTO $loop-start) - (.visitMaxs 0 0) - (.visitEnd))) - _ (let [$from (new Label) - $to (new Label) - $handler (new Label) - $loop-start (new Label) - $do-a-round (new Label) - $skip-power (new Label) - $iterate (new Label) - $bad-format (new Label)] - (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "decode_deg" "(Ljava/lang/String;)Ljava/lang/Object;" nil nil) - (.visitCode) - ;; Check prefix - (.visitVarInsn Opcodes/ALOAD 0) - (.visitLdcInsn ".") - (.visitMethodInsn Opcodes/INVOKEVIRTUAL "java/lang/String" "startsWith" "(Ljava/lang/String;)Z") - (.visitJumpInsn Opcodes/IFEQ $bad-format) - ;; Check if size is valid - (.visitVarInsn Opcodes/ALOAD 0) - (.visitMethodInsn Opcodes/INVOKEVIRTUAL "java/lang/String" "length" "()I") - (.visitLdcInsn (int (inc deg-bits))) ;; It's increased, to account for the prefix . - (.visitJumpInsn Opcodes/IF_ICMPGT $bad-format) - ;; Initialization - (.visitTryCatchBlock $from $to $handler "java/lang/Exception") - (.visitVarInsn Opcodes/ALOAD 0) - (.visitLdcInsn (int 1)) - (.visitMethodInsn Opcodes/INVOKEVIRTUAL "java/lang/String" "substring" "(I)Ljava/lang/String;") - (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "clean_separators" "(Ljava/lang/String;)Ljava/lang/String;") - (.visitLabel $from) - (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "deg_text_to_digits" "(Ljava/lang/String;)[B") - (.visitLabel $to) - (.visitVarInsn Opcodes/ASTORE 0) ;; From test to digits... - (.visitLdcInsn (int 0)) - (.visitVarInsn Opcodes/ISTORE 1) ;; Index - (.visitLdcInsn (long 0)) - (.visitVarInsn Opcodes/LSTORE 2) ;; Output - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - (.visitLabel $loop-start) - (.visitVarInsn Opcodes/ILOAD 1) - (.visitLdcInsn (int deg-bits)) - (.visitJumpInsn Opcodes/IF_ICMPLT $do-a-round) - (.visitVarInsn Opcodes/LLOAD 2) - &&/wrap-long - (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "make_some" "(Ljava/lang/Object;)[Ljava/lang/Object;") - (.visitInsn Opcodes/ARETURN) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - (.visitLabel $do-a-round) - (.visitVarInsn Opcodes/ALOAD 0) - (.visitVarInsn Opcodes/ILOAD 1) - (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "deg_digit_power" "(I)[B") - (.visitInsn Opcodes/DUP2) - (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "deg_digits_lt" "([B[B)Z") - (.visitJumpInsn Opcodes/IFNE $skip-power) - ;; Subtract power - (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "deg_digits_sub" "([B[B)[B") - (.visitVarInsn Opcodes/ASTORE 0) - ;; Set bit on output - (.visitVarInsn Opcodes/LLOAD 2) - (.visitLdcInsn (long 1)) - (.visitVarInsn Opcodes/ILOAD 1) - (.visitLdcInsn (int (dec deg-bits))) - (.visitInsn Opcodes/SWAP) - (.visitInsn Opcodes/ISUB) - (.visitInsn Opcodes/LSHL) - (.visitInsn Opcodes/LOR) - (.visitVarInsn Opcodes/LSTORE 2) - (.visitJumpInsn Opcodes/GOTO $iterate) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - (.visitLabel $skip-power) - (.visitInsn Opcodes/POP2) - ;; (.visitJumpInsn Opcodes/GOTO $iterate) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - (.visitLabel $iterate) - (.visitVarInsn Opcodes/ILOAD 1) - (.visitLdcInsn (int 1)) - (.visitInsn Opcodes/IADD) - (.visitVarInsn Opcodes/ISTORE 1) - ;; Iterate - (.visitJumpInsn Opcodes/GOTO $loop-start) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - (.visitLabel $handler) - (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "make_none" "()Ljava/lang/Object;") - (.visitInsn Opcodes/ARETURN) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - (.visitLabel $bad-format) - (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "make_none" "()Ljava/lang/Object;") - (.visitInsn Opcodes/ARETURN) - (.visitMaxs 0 0) - (.visitEnd)))] + (.visitEnd))] nil)) (let [+wrapper-class+ (&host-generics/->bytecode-class-name "java.lang.Long")] |