From 913062dd2bc8559c44e0f07cdece404cc7f6791c Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Sun, 12 Mar 2017 20:16:34 -0400 Subject: - Implemented natural decoding. - Implemented the _lux_program statement. --- luxc/src/lux/compiler/js/lux.clj | 83 +++-------------------- luxc/src/lux/compiler/js/rt.clj | 138 ++++++++++----------------------------- 2 files changed, 44 insertions(+), 177 deletions(-) (limited to 'luxc/src') diff --git a/luxc/src/lux/compiler/js/lux.clj b/luxc/src/lux/compiler/js/lux.clj index 5c6039d2b..ffb75a3ef 100644 --- a/luxc/src/lux/compiler/js/lux.clj +++ b/luxc/src/lux/compiler/js/lux.clj @@ -381,78 +381,11 @@ ) (defn compile-program [compile ?body] - (assert false "compile-program") - ;; (|do [module-name &/get-module-name - ;; ^ClassWriter *writer* &/get-writer] - ;; (&/with-writer (doto (.visitMethod *writer* (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "main" "([Ljava/lang/String;)V" nil nil) - ;; (.visitCode)) - ;; (|do [^MethodVisitor main-writer &/get-writer - ;; :let [$loop (new Label) - ;; $end (new Label) - ;; _ (doto main-writer - ;; ;; Tail: Begin - ;; (.visitLdcInsn (->> #'&/$Nil meta ::&/idx int)) ;; I - ;; (.visitInsn Opcodes/ACONST_NULL) ;; I? - ;; (.visitLdcInsn &/unit-tag) ;; I?U - ;; (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "sum_make" "(ILjava/lang/Object;Ljava/lang/Object;)[Ljava/lang/Object;") ;; V - ;; ;; Tail: End - ;; ;; Size: Begin - ;; (.visitVarInsn Opcodes/ALOAD 0) ;; VA - ;; (.visitInsn Opcodes/ARRAYLENGTH) ;; VI - ;; ;; Size: End - ;; ;; Loop: Begin - ;; (.visitLabel $loop) - ;; (.visitLdcInsn (int 1)) ;; VII - ;; (.visitInsn Opcodes/ISUB) ;; VI - ;; (.visitInsn Opcodes/DUP) ;; VII - ;; (.visitJumpInsn Opcodes/IFLT $end) ;; VI - ;; ;; Head: Begin - ;; (.visitInsn Opcodes/DUP) ;; VII - ;; (.visitVarInsn Opcodes/ALOAD 0) ;; VIIA - ;; (.visitInsn Opcodes/SWAP) ;; VIAI - ;; (.visitInsn Opcodes/AALOAD) ;; VIO - ;; (.visitInsn Opcodes/SWAP) ;; VOI - ;; (.visitInsn Opcodes/DUP_X2) ;; IVOI - ;; (.visitInsn Opcodes/POP) ;; IVO - ;; ;; Head: End - ;; ;; Tuple: Begin - ;; (.visitLdcInsn (int 2)) ;; IVOS - ;; (.visitTypeInsn Opcodes/ANEWARRAY "java/lang/Object") ;; IVO2 - ;; (.visitInsn Opcodes/DUP_X1) ;; IV2O2 - ;; (.visitInsn Opcodes/SWAP) ;; IV22O - ;; (.visitLdcInsn (int 0)) ;; IV22OI - ;; (.visitInsn Opcodes/SWAP) ;; IV22IO - ;; (.visitInsn Opcodes/AASTORE) ;; IV2 - ;; (.visitInsn Opcodes/DUP_X1) ;; I2V2 - ;; (.visitInsn Opcodes/SWAP) ;; I22V - ;; (.visitLdcInsn (int 1)) ;; I22VI - ;; (.visitInsn Opcodes/SWAP) ;; I22IV - ;; (.visitInsn Opcodes/AASTORE) ;; I2 - ;; ;; Tuple: End - ;; ;; Cons: Begin - ;; (.visitLdcInsn (->> #'&/$Cons meta ::&/idx int)) ;; I2I - ;; (.visitLdcInsn "") ;; I2I? - ;; (.visitInsn Opcodes/DUP2_X1) ;; II?2I? - ;; (.visitInsn Opcodes/POP2) ;; II?2 - ;; (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "sum_make" "(ILjava/lang/Object;Ljava/lang/Object;)[Ljava/lang/Object;") ;; IV - ;; ;; Cons: End - ;; (.visitInsn Opcodes/SWAP) ;; VI - ;; (.visitJumpInsn Opcodes/GOTO $loop) - ;; ;; Loop: End - ;; (.visitLabel $end) ;; VI - ;; (.visitInsn Opcodes/POP) ;; V - ;; (.visitVarInsn Opcodes/ASTORE (int 0)) ;; - ;; ) - ;; ] - ;; _ (compile ?body) - ;; :let [_ (doto main-writer - ;; (.visitTypeInsn Opcodes/CHECKCAST &&/function-class) - ;; (.visitInsn Opcodes/ACONST_NULL) - ;; (.visitMethodInsn Opcodes/INVOKEVIRTUAL &&/function-class &&/apply-method (&&/apply-signature 1)))] - ;; :let [_ (doto main-writer - ;; (.visitInsn Opcodes/POP) - ;; (.visitInsn Opcodes/RETURN) - ;; (.visitMaxs 0 0) - ;; (.visitEnd))]] - ;; (return nil)))) - ) + (|do [=body (compile ?body) + :let [program-js (str (str "var " (register-name 0) " = LuxRT.programArgs();") + (str "(" =body ")(null);"))] + eval? &/get-eval + ^StringBuilder buffer &&/get-buffer + :let [_ (when (not eval?) + (.append buffer ^String (str program-js "\n")))]] + (return ""))) diff --git a/luxc/src/lux/compiler/js/rt.clj b/luxc/src/lux/compiler/js/rt.clj index 0ece93d6e..c022dd3bb 100644 --- a/luxc/src/lux/compiler/js/rt.clj +++ b/luxc/src/lux/compiler/js/rt.clj @@ -420,108 +420,6 @@ ;; (.visitEnd)))] ;; nil)) -;; (let [+wrapper-class+ (&host-generics/->bytecode-class-name "java.lang.Long")] -;; (defn ^:private compile-LuxRT-nat-methods [^ClassWriter =class] -;; (|let [;; http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/java/lang/Long.java#677 -;; _ (let [$from (new Label) -;; $to (new Label) -;; $handler (new Label) - -;; $good-start (new Label) -;; $short-enough (new Label) -;; $bad-digit (new Label) -;; $out-of-bounds (new Label)] -;; (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "decode_nat" "(Ljava/lang/String;)Ljava/lang/Object;" nil nil) -;; (.visitCode) -;; (.visitTryCatchBlock $from $to $handler "java/lang/Exception") -;; (.visitLabel $from) -;; ;; Remove the + at the beginning... -;; (.visitVarInsn Opcodes/ALOAD 0) -;; (.visitLdcInsn (int 0)) -;; (.visitLdcInsn (int 1)) -;; (.visitMethodInsn Opcodes/INVOKEVIRTUAL "java/lang/String" "substring" "(II)Ljava/lang/String;") -;; (.visitLdcInsn "+") -;; (.visitMethodInsn Opcodes/INVOKEVIRTUAL "java/lang/Object" "equals" "(Ljava/lang/Object;)Z") -;; (.visitJumpInsn Opcodes/IFNE $good-start) -;; ;; Doesn't start with + -;; (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "make_none" "()Ljava/lang/Object;") -;; (.visitInsn Opcodes/ARETURN) -;; ;; Starts with + -;; (.visitLabel $good-start) -;; (.visitVarInsn Opcodes/ALOAD 0) -;; (.visitLdcInsn (int 1)) -;; (.visitVarInsn Opcodes/ALOAD 0) -;; (.visitMethodInsn Opcodes/INVOKEVIRTUAL "java/lang/String" "length" "()I") -;; (.visitMethodInsn Opcodes/INVOKEVIRTUAL "java/lang/String" "substring" "(II)Ljava/lang/String;") -;; (.visitVarInsn Opcodes/ASTORE 0) ;; Removed the + prefix... -;; ;; Begin parsing processs -;; (.visitVarInsn Opcodes/ALOAD 0) -;; (.visitMethodInsn Opcodes/INVOKEVIRTUAL "java/lang/String" "length" "()I") -;; (.visitLdcInsn (int 18)) -;; (.visitJumpInsn Opcodes/IF_ICMPLE $short-enough) -;; ;; Too long -;; ;; Get prefix... -;; (.visitVarInsn Opcodes/ALOAD 0) -;; (.visitLdcInsn (int 0)) -;; (.visitVarInsn Opcodes/ALOAD 0) -;; (.visitMethodInsn Opcodes/INVOKEVIRTUAL "java/lang/String" "length" "()I") -;; (.visitLdcInsn (int 1)) -;; (.visitInsn Opcodes/ISUB) -;; (.visitMethodInsn Opcodes/INVOKEVIRTUAL "java/lang/String" "substring" "(II)Ljava/lang/String;") -;; (.visitMethodInsn Opcodes/INVOKESTATIC "java/lang/Long" "parseLong" "(Ljava/lang/String;)J") -;; (.visitInsn Opcodes/DUP2) ;; Clone prefix, for later... -;; ;; Get last digit... -;; (.visitVarInsn Opcodes/ALOAD 0) -;; (.visitVarInsn Opcodes/ALOAD 0) -;; (.visitMethodInsn Opcodes/INVOKEVIRTUAL "java/lang/String" "length" "()I") -;; (.visitLdcInsn (int 1)) -;; (.visitInsn Opcodes/ISUB) -;; (.visitMethodInsn Opcodes/INVOKEVIRTUAL "java/lang/String" "charAt" "(I)C") -;; (.visitLdcInsn (int 10)) -;; (.visitMethodInsn Opcodes/INVOKESTATIC "java/lang/Character" "digit" "(CI)I") -;; ;; Test last digit... -;; (.visitInsn Opcodes/DUP) -;; (.visitJumpInsn Opcodes/IFLT $bad-digit) -;; ;; Good digit... -;; ;; Stack: prefix::L, prefix::L, last-digit::I -;; (.visitInsn Opcodes/I2L) -;; ;; Build the result... -;; swap2 -;; (.visitLdcInsn (long 10)) -;; (.visitInsn Opcodes/LMUL) -;; (.visitInsn Opcodes/LADD) ;; Stack: prefix::L, result::L -;; (.visitInsn Opcodes/DUP2_X2) ;; Stack: result::L, prefix::L, result::L -;; swap2 ;; Stack: result::L, result::L, prefix::L -;; (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "_compareUnsigned" "(JJ)I") -;; (.visitJumpInsn Opcodes/IFLT $out-of-bounds) -;; ;; Within bounds -;; ;; Stack: result::L -;; &&/wrap-long -;; (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "make_some" "(Ljava/lang/Object;)Ljava/lang/Object;") -;; (.visitInsn Opcodes/ARETURN) -;; ;; Out of bounds -;; (.visitLabel $out-of-bounds) -;; (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "make_none" "()Ljava/lang/Object;") -;; (.visitInsn Opcodes/ARETURN) -;; ;; Bad digit... -;; (.visitLabel $bad-digit) -;; (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "make_none" "()Ljava/lang/Object;") -;; (.visitInsn Opcodes/ARETURN) -;; ;; 18 chars or less -;; (.visitLabel $short-enough) -;; (.visitVarInsn Opcodes/ALOAD 0) -;; (.visitMethodInsn Opcodes/INVOKESTATIC "java/lang/Long" "parseLong" "(Ljava/lang/String;)J") -;; &&/wrap-long -;; (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "make_some" "(Ljava/lang/Object;)Ljava/lang/Object;") -;; (.visitInsn Opcodes/ARETURN) -;; (.visitLabel $to) -;; (.visitLabel $handler) -;; (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "make_none" "()Ljava/lang/Object;") -;; (.visitInsn Opcodes/ARETURN) -;; (.visitMaxs 0 0) -;; (.visitEnd)))] -;; nil))) - (def ^:private const-none (str "[0,null," &&/unit "]")) (defn ^:private make-some [value] (str "[1,''," value "]")) @@ -867,6 +765,30 @@ "return '+'.concat(LuxRT.encodeI64(input));" "}") "})") + "decodeN64" (str "(function decodeN64(input) {" + (str "if(/^\\+\\d+$/.exec(input)) {" + (str "input = input.substring(1);") + (str "if(input.length <= 18) {" + ;; Short enough... + "return LuxRT.decodeI64(input);" + "}" + "else {" + ;; Too long + (str "var prefix = LuxRT.decodeI64(input.substring(0, input.length-1))[2];" + "var suffix = LuxRT.decodeI64(input.charAt(input.length-1))[2];" + "var total = LuxRT.addI64(LuxRT.mulI64(prefix,LuxRT.fromNumberI64(10)),suffix);" + (str "if(LuxRT.ltN64(total,prefix)) {" + (str "return " const-none ";") + "}" + "else {" + (str "return " (make-some "total") ";") + "}")) + "}") + "}" + "else {" + (str "return " const-none ";") + "}") + "})") "divN64" (str "(function divN64(l,r) {" (str "if(LuxRT.ltI64(r,LuxRT.ZERO)) {" (str "if(LuxRT.ltN64(l,r)) {" @@ -1128,6 +1050,18 @@ (str "return [0,null,ex.toString()];") "}") "})") + "programArgs" (str "(function programArgs() {" + (str "if(typeof process !== 'undefined' && process.argv) {" + (str (str "var result = " const-none ";") + "for(var idx = process.argv.length-1; idx >= 0; idx--) {" + (str "result = " (make-some "[process.argv[idx],result]") ";") + "}") + (str "return result;") + "}" + "else {" + (str "return " const-none ";") + "}") + "})") }) (def LuxRT "LuxRT") -- cgit v1.2.3