From 85065dcfae4ef55df519ce52ed0f6b48fea02e70 Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Sun, 8 Mar 2015 20:18:18 -0400 Subject: - Implemented comparisons and equalities for int, long, float & double. - The lexer now allows "-" in front of numbers to get negative numbers. --- src/lux/analyser.clj | 36 +++++++++++++++ src/lux/analyser/host.clj | 76 +++++++++++++++++++++---------- src/lux/compiler.clj | 36 +++++++++++++++ src/lux/compiler/host.clj | 113 +++++++++++++++++++++++++++++++++++++--------- src/lux/compiler/lux.clj | 3 +- src/lux/lexer.clj | 4 +- 6 files changed, 220 insertions(+), 48 deletions(-) (limited to 'src') diff --git a/src/lux/analyser.clj b/src/lux/analyser.clj index 3575c3007..8f05232a2 100644 --- a/src/lux/analyser.clj +++ b/src/lux/analyser.clj @@ -78,6 +78,15 @@ [::&parser/Form ([[::&parser/Ident "jvm-irem"] ?x ?y] :seq)] (&&host/analyse-jvm-irem analyse-ast ?x ?y) + [::&parser/Form ([[::&parser/Ident "jvm-ieq"] ?x ?y] :seq)] + (&&host/analyse-jvm-ieq analyse-ast ?x ?y) + + [::&parser/Form ([[::&parser/Ident "jvm-ilt"] ?x ?y] :seq)] + (&&host/analyse-jvm-ilt analyse-ast ?x ?y) + + [::&parser/Form ([[::&parser/Ident "jvm-igt"] ?x ?y] :seq)] + (&&host/analyse-jvm-igt analyse-ast ?x ?y) + ;; Long arithmetic [::&parser/Form ([[::&parser/Ident "jvm-ladd"] ?x ?y] :seq)] (&&host/analyse-jvm-ladd analyse-ast ?x ?y) @@ -94,6 +103,15 @@ [::&parser/Form ([[::&parser/Ident "jvm-lrem"] ?x ?y] :seq)] (&&host/analyse-jvm-lrem analyse-ast ?x ?y) + [::&parser/Form ([[::&parser/Ident "jvm-leq"] ?x ?y] :seq)] + (&&host/analyse-jvm-leq analyse-ast ?x ?y) + + [::&parser/Form ([[::&parser/Ident "jvm-llt"] ?x ?y] :seq)] + (&&host/analyse-jvm-llt analyse-ast ?x ?y) + + [::&parser/Form ([[::&parser/Ident "jvm-lgt"] ?x ?y] :seq)] + (&&host/analyse-jvm-lgt analyse-ast ?x ?y) + ;; Float arithmetic [::&parser/Form ([[::&parser/Ident "jvm-fadd"] ?x ?y] :seq)] (&&host/analyse-jvm-fadd analyse-ast ?x ?y) @@ -110,6 +128,15 @@ [::&parser/Form ([[::&parser/Ident "jvm-frem"] ?x ?y] :seq)] (&&host/analyse-jvm-frem analyse-ast ?x ?y) + [::&parser/Form ([[::&parser/Ident "jvm-feq"] ?x ?y] :seq)] + (&&host/analyse-jvm-feq analyse-ast ?x ?y) + + [::&parser/Form ([[::&parser/Ident "jvm-flt"] ?x ?y] :seq)] + (&&host/analyse-jvm-flt analyse-ast ?x ?y) + + [::&parser/Form ([[::&parser/Ident "jvm-fgt"] ?x ?y] :seq)] + (&&host/analyse-jvm-fgt analyse-ast ?x ?y) + ;; Double arithmetic [::&parser/Form ([[::&parser/Ident "jvm-dadd"] ?x ?y] :seq)] (&&host/analyse-jvm-dadd analyse-ast ?x ?y) @@ -126,6 +153,15 @@ [::&parser/Form ([[::&parser/Ident "jvm-drem"] ?x ?y] :seq)] (&&host/analyse-jvm-drem analyse-ast ?x ?y) + [::&parser/Form ([[::&parser/Ident "jvm-deq"] ?x ?y] :seq)] + (&&host/analyse-jvm-deq analyse-ast ?x ?y) + + [::&parser/Form ([[::&parser/Ident "jvm-dlt"] ?x ?y] :seq)] + (&&host/analyse-jvm-dlt analyse-ast ?x ?y) + + [::&parser/Form ([[::&parser/Ident "jvm-dgt"] ?x ?y] :seq)] + (&&host/analyse-jvm-dgt analyse-ast ?x ?y) + ;; Fields & methods [::&parser/Form ([[::&parser/Ident "jvm-getstatic"] [::&parser/Ident ?class] [::&parser/Text ?field]] :seq)] (&&host/analyse-jvm-getstatic analyse-ast ?class ?field) diff --git a/src/lux/analyser/host.clj b/src/lux/analyser/host.clj index aa7812421..5b96a2a74 100644 --- a/src/lux/analyser/host.clj +++ b/src/lux/analyser/host.clj @@ -19,7 +19,7 @@ (fail "[Analyser Error] Can't extract Ident."))) ;; [Resources] -(do-template [ ] +(do-template [ ] (let [elem-type [::&type/Data ]] (defn [analyse ?x ?y] (exec [[=x =y] (&&/analyse-2 analyse ?x ?y) @@ -30,29 +30,57 @@ ] (return (list [::&&/Expression [ =x =y] elem-type]))))) - analyse-jvm-iadd "jvm;iadd" ::&&/jvm-iadd "java.lang.Integer" - analyse-jvm-isub "jvm;isub" ::&&/jvm-isub "java.lang.Integer" - analyse-jvm-imul "jvm;imul" ::&&/jvm-imul "java.lang.Integer" - analyse-jvm-idiv "jvm;idiv" ::&&/jvm-idiv "java.lang.Integer" - analyse-jvm-irem "jvm;irem" ::&&/jvm-irem "java.lang.Integer" - - analyse-jvm-ladd "jvm;ladd" ::&&/jvm-ladd "java.lang.Long" - analyse-jvm-lsub "jvm;lsub" ::&&/jvm-lsub "java.lang.Long" - analyse-jvm-lmul "jvm;lmul" ::&&/jvm-lmul "java.lang.Long" - analyse-jvm-ldiv "jvm;ldiv" ::&&/jvm-ldiv "java.lang.Long" - analyse-jvm-lrem "jvm;lrem" ::&&/jvm-lrem "java.lang.Long" - - analyse-jvm-fadd "jvm;fadd" ::&&/jvm-fadd "java.lang.Float" - analyse-jvm-fsub "jvm;fsub" ::&&/jvm-fsub "java.lang.Float" - analyse-jvm-fmul "jvm;fmul" ::&&/jvm-fmul "java.lang.Float" - analyse-jvm-fdiv "jvm;fdiv" ::&&/jvm-fdiv "java.lang.Float" - analyse-jvm-frem "jvm;frem" ::&&/jvm-frem "java.lang.Float" - - analyse-jvm-dadd "jvm;dadd" ::&&/jvm-dadd "java.lang.Double" - analyse-jvm-dsub "jvm;dsub" ::&&/jvm-dsub "java.lang.Double" - analyse-jvm-dmul "jvm;dmul" ::&&/jvm-dmul "java.lang.Double" - analyse-jvm-ddiv "jvm;ddiv" ::&&/jvm-ddiv "java.lang.Double" - analyse-jvm-drem "jvm;drem" ::&&/jvm-drem "java.lang.Double" + analyse-jvm-iadd ::&&/jvm-iadd "java.lang.Integer" + analyse-jvm-isub ::&&/jvm-isub "java.lang.Integer" + analyse-jvm-imul ::&&/jvm-imul "java.lang.Integer" + analyse-jvm-idiv ::&&/jvm-idiv "java.lang.Integer" + analyse-jvm-irem ::&&/jvm-irem "java.lang.Integer" + + analyse-jvm-ladd ::&&/jvm-ladd "java.lang.Long" + analyse-jvm-lsub ::&&/jvm-lsub "java.lang.Long" + analyse-jvm-lmul ::&&/jvm-lmul "java.lang.Long" + analyse-jvm-ldiv ::&&/jvm-ldiv "java.lang.Long" + analyse-jvm-lrem ::&&/jvm-lrem "java.lang.Long" + + analyse-jvm-fadd ::&&/jvm-fadd "java.lang.Float" + analyse-jvm-fsub ::&&/jvm-fsub "java.lang.Float" + analyse-jvm-fmul ::&&/jvm-fmul "java.lang.Float" + analyse-jvm-fdiv ::&&/jvm-fdiv "java.lang.Float" + analyse-jvm-frem ::&&/jvm-frem "java.lang.Float" + + analyse-jvm-dadd ::&&/jvm-dadd "java.lang.Double" + analyse-jvm-dsub ::&&/jvm-dsub "java.lang.Double" + analyse-jvm-dmul ::&&/jvm-dmul "java.lang.Double" + analyse-jvm-ddiv ::&&/jvm-ddiv "java.lang.Double" + analyse-jvm-drem ::&&/jvm-drem "java.lang.Double" + ) + +(do-template [ ] + (let [elem-type [::&type/Data ]] + (defn [analyse ?x ?y] + (exec [[=x =y] (&&/analyse-2 analyse ?x ?y) + ;; =x-type (&&/expr-type =x) + ;; =y-type (&&/expr-type =y) + ;; _ (&type/solve elem-type =x-type) + ;; _ (&type/solve elem-type =y-type) + ] + (return (list [::&&/Expression [ =x =y] elem-type]))))) + + analyse-jvm-ieq ::&&/jvm-ieq "java.lang.Integer" "java.lang.Boolean" + analyse-jvm-ilt ::&&/jvm-ilt "java.lang.Integer" "java.lang.Boolean" + analyse-jvm-igt ::&&/jvm-igt "java.lang.Integer" "java.lang.Boolean" + + analyse-jvm-leq ::&&/jvm-leq "java.lang.Long" "java.lang.Boolean" + analyse-jvm-llt ::&&/jvm-llt "java.lang.Long" "java.lang.Boolean" + analyse-jvm-lgt ::&&/jvm-lgt "java.lang.Long" "java.lang.Boolean" + + analyse-jvm-feq ::&&/jvm-feq "java.lang.Float" "java.lang.Boolean" + analyse-jvm-flt ::&&/jvm-flt "java.lang.Float" "java.lang.Boolean" + analyse-jvm-fgt ::&&/jvm-fgt "java.lang.Float" "java.lang.Boolean" + + analyse-jvm-deq ::&&/jvm-deq "java.lang.Double" "java.lang.Boolean" + analyse-jvm-dlt ::&&/jvm-dlt "java.lang.Double" "java.lang.Boolean" + analyse-jvm-dgt ::&&/jvm-dgt "java.lang.Double" "java.lang.Boolean" ) (defn analyse-jvm-getstatic [analyse ?class ?field] diff --git a/src/lux/compiler.clj b/src/lux/compiler.clj index 503f041ea..79682754c 100644 --- a/src/lux/compiler.clj +++ b/src/lux/compiler.clj @@ -88,6 +88,15 @@ [::&a/jvm-irem ?x ?y] (&&host/compile-jvm-irem compile-expression ?type ?x ?y) + [::&a/jvm-ieq ?x ?y] + (&&host/compile-jvm-ieq compile-expression ?type ?x ?y) + + [::&a/jvm-ilt ?x ?y] + (&&host/compile-jvm-ilt compile-expression ?type ?x ?y) + + [::&a/jvm-igt ?x ?y] + (&&host/compile-jvm-igt compile-expression ?type ?x ?y) + ;; Long arithmetic [::&a/jvm-ladd ?x ?y] (&&host/compile-jvm-ladd compile-expression ?type ?x ?y) @@ -104,6 +113,15 @@ [::&a/jvm-lrem ?x ?y] (&&host/compile-jvm-lrem compile-expression ?type ?x ?y) + [::&a/jvm-leq ?x ?y] + (&&host/compile-jvm-leq compile-expression ?type ?x ?y) + + [::&a/jvm-llt ?x ?y] + (&&host/compile-jvm-llt compile-expression ?type ?x ?y) + + [::&a/jvm-lgt ?x ?y] + (&&host/compile-jvm-lgt compile-expression ?type ?x ?y) + ;; Float arithmetic [::&a/jvm-fadd ?x ?y] (&&host/compile-jvm-fadd compile-expression ?type ?x ?y) @@ -120,6 +138,15 @@ [::&a/jvm-frem ?x ?y] (&&host/compile-jvm-frem compile-expression ?type ?x ?y) + [::&a/jvm-feq ?x ?y] + (&&host/compile-jvm-feq compile-expression ?type ?x ?y) + + [::&a/jvm-flt ?x ?y] + (&&host/compile-jvm-flt compile-expression ?type ?x ?y) + + [::&a/jvm-fgt ?x ?y] + (&&host/compile-jvm-fgt compile-expression ?type ?x ?y) + ;; Double arithmetic [::&a/jvm-dadd ?x ?y] (&&host/compile-jvm-dadd compile-expression ?type ?x ?y) @@ -135,6 +162,15 @@ [::&a/jvm-drem ?x ?y] (&&host/compile-jvm-drem compile-expression ?type ?x ?y) + + [::&a/jvm-deq ?x ?y] + (&&host/compile-jvm-deq compile-expression ?type ?x ?y) + + [::&a/jvm-dlt ?x ?y] + (&&host/compile-jvm-dlt compile-expression ?type ?x ?y) + + [::&a/jvm-dgt ?x ?y] + (&&host/compile-jvm-dgt compile-expression ?type ?x ?y) [::&a/exec ?exprs] (&&host/compile-exec compile-expression ?type ?exprs) diff --git a/src/lux/compiler/host.clj b/src/lux/compiler/host.clj index 879bc52f3..f1a6492b9 100644 --- a/src/lux/compiler/host.clj +++ b/src/lux/compiler/host.clj @@ -36,25 +36,31 @@ (.visitMethodInsn Opcodes/INVOKEVIRTUAL class method sig)) (.visitTypeInsn *writer* Opcodes/CHECKCAST (&host/->class class-name))))) -;; (let [boolean-class "java.lang.Boolean" -;; integer-class "java.lang.Integer" -;; char-class "java.lang.Character"] -;; (defn prepare-return! [*writer* *type*] -;; (match *type* -;; ::&type/nothing -;; (.visitInsn *writer* Opcodes/ACONST_NULL) +(let [boolean-class "java.lang.Boolean" + integer-class "java.lang.Integer" + long-class "java.lang.Long" + char-class "java.lang.Character"] + (defn prepare-return! [*writer* *type*] + (match *type* + [::&type/Nothing] + (.visitInsn *writer* Opcodes/ACONST_NULL) -;; [::&type/primitive "char"] -;; (.visitMethodInsn *writer* Opcodes/INVOKESTATIC (&host/->class char-class) "valueOf" (str "(C)" (&host/->type-signature char-class))) + [::&type/Data "char"] + (.visitMethodInsn *writer* Opcodes/INVOKESTATIC (&host/->class char-class) "valueOf" (str "(C)" (&host/->type-signature char-class))) -;; [::&type/primitive "int"] -;; (.visitMethodInsn *writer* Opcodes/INVOKESTATIC (&host/->class integer-class) "valueOf" (str "(I)" (&host/->type-signature integer-class))) + [::&type/Data "int"] + (.visitMethodInsn *writer* Opcodes/INVOKESTATIC (&host/->class integer-class) "valueOf" (str "(I)" (&host/->type-signature integer-class))) -;; [::&type/primitive "boolean"] -;; (.visitMethodInsn *writer* Opcodes/INVOKESTATIC (&host/->class boolean-class) "valueOf" (str "(Z)" (&host/->type-signature boolean-class))) + [::&type/Data "long"] + (.visitMethodInsn *writer* Opcodes/INVOKESTATIC (&host/->class long-class) "valueOf" (str "(J)" (&host/->type-signature long-class))) -;; [::&type/Data ?oclass] -;; nil))) + [::&type/Data "boolean"] + (.visitMethodInsn *writer* Opcodes/INVOKESTATIC (&host/->class boolean-class) "valueOf" (str "(Z)" (&host/->type-signature boolean-class))) + + [::&type/Data _] + nil + ) + *writer*)) ;; [Resources] (do-template [ ] @@ -99,6 +105,71 @@ compile-jvm-drem Opcodes/DREM "java.lang.Double" "doubleValue" "()D" "valueOf" "(D)" ) +(do-template [ ] + (defn [compile *type* ?x ?y] + (exec [:let [+wrapper-class+ (&host/->class )] + *writer* &/get-writer + _ (compile ?x) + :let [_ (doto *writer* + (.visitTypeInsn Opcodes/CHECKCAST +wrapper-class+) + (.visitMethodInsn Opcodes/INVOKEVIRTUAL +wrapper-class+ ))] + _ (compile ?y) + :let [_ (doto *writer* + (.visitTypeInsn Opcodes/CHECKCAST +wrapper-class+) + (.visitMethodInsn Opcodes/INVOKEVIRTUAL +wrapper-class+ )) + $then (new Label) + $end (new Label) + _ (doto *writer* + (.visitJumpInsn $then) + (.visitFieldInsn Opcodes/GETSTATIC (&host/->class "java.lang.Boolean") "TRUE" (&host/->type-signature "java.lang.Boolean")) + (.visitJumpInsn Opcodes/GOTO $end) + (.visitLabel $then) + (.visitFieldInsn Opcodes/GETSTATIC (&host/->class "java.lang.Boolean") "FALSE" (&host/->type-signature "java.lang.Boolean")) + (.visitLabel $end))]] + (return nil))) + + compile-jvm-ieq Opcodes/IF_ICMPEQ "java.lang.Integer" "intValue" "()I" + compile-jvm-ilt Opcodes/IF_ICMPLT "java.lang.Integer" "intValue" "()I" + compile-jvm-igt Opcodes/IF_ICMPGT "java.lang.Integer" "intValue" "()I" + ) + +(do-template [ ] + (defn [compile *type* ?x ?y] + (exec [:let [+wrapper-class+ (&host/->class )] + *writer* &/get-writer + _ (compile ?x) + :let [_ (doto *writer* + (.visitTypeInsn Opcodes/CHECKCAST +wrapper-class+) + (.visitMethodInsn Opcodes/INVOKEVIRTUAL +wrapper-class+ ))] + _ (compile ?y) + :let [_ (doto *writer* + (.visitTypeInsn Opcodes/CHECKCAST +wrapper-class+) + (.visitMethodInsn Opcodes/INVOKEVIRTUAL +wrapper-class+ )) + $then (new Label) + $end (new Label) + _ (doto *writer* + (.visitInsn ) + (.visitJumpInsn $then) + (.visitFieldInsn Opcodes/GETSTATIC (&host/->class "java.lang.Boolean") "TRUE" (&host/->type-signature "java.lang.Boolean")) + (.visitJumpInsn Opcodes/GOTO $end) + (.visitLabel $then) + (.visitFieldInsn Opcodes/GETSTATIC (&host/->class "java.lang.Boolean") "FALSE" (&host/->type-signature "java.lang.Boolean")) + (.visitLabel $end))]] + (return nil))) + + compile-jvm-leq Opcodes/LCMP Opcodes/IFEQ "java.lang.Long" "longValue" "()J" + compile-jvm-llt Opcodes/LCMP Opcodes/IFLT "java.lang.Long" "longValue" "()J" + compile-jvm-lgt Opcodes/LCMP Opcodes/IFGT "java.lang.Long" "longValue" "()J" + + compile-jvm-feq Opcodes/FCMPL Opcodes/IFEQ "java.lang.Float" "floatValue" "()F" + compile-jvm-flt Opcodes/FCMPL Opcodes/IFLT "java.lang.Float" "floatValue" "()F" + compile-jvm-fgt Opcodes/FCMPL Opcodes/IFGT "java.lang.Float" "floatValue" "()F" + + compile-jvm-deq Opcodes/DCMPL Opcodes/IFEQ "java.lang.Double" "doubleValue" "()I" + compile-jvm-dlt Opcodes/DCMPL Opcodes/IFLT "java.lang.Double" "doubleValue" "()I" + compile-jvm-dgt Opcodes/FCMPL Opcodes/IFGT "java.lang.Double" "doubleValue" "()I" + ) + (defn compile-jvm-invokestatic [compile *type* ?class ?method ?classes ?args] (exec [*writer* &/get-writer :let [method-sig (str "(" (reduce str "" (map &host/->type-signature ?classes)) ")" (&host/->java-sig *type*))] @@ -107,9 +178,9 @@ :let [_ (prepare-arg! *writer* class-name)]] (return ret))) (map vector ?classes ?args)) - :let [_ (do (.visitMethodInsn *writer* Opcodes/INVOKESTATIC (&host/->class ?class) ?method method-sig) - ;; (prepare-return! *writer* *type*) - )]] + :let [_ (doto *writer* + (.visitMethodInsn Opcodes/INVOKESTATIC (&host/->class ?class) ?method method-sig) + (prepare-return! *type*))]] (return nil))) (defn compile-jvm-invokevirtual [compile *type* ?class ?method ?classes ?object ?args] @@ -123,9 +194,9 @@ :let [_ (prepare-arg! *writer* class-name)]] (return ret))) (map vector ?classes ?args)) - :let [_ (do (.visitMethodInsn *writer* Opcodes/INVOKEVIRTUAL (&host/->class ?class) ?method method-sig) - ;; (prepare-return! *writer* *type*) - )]] + :let [_ (doto *writer* + (.visitMethodInsn Opcodes/INVOKEVIRTUAL (&host/->class ?class) ?method method-sig) + (prepare-return! *type*))]] (return nil))) (defn compile-jvm-new [compile *type* ?class ?classes ?args] diff --git a/src/lux/compiler/lux.clj b/src/lux/compiler/lux.clj index 7e9e55b23..2b6c7909e 100644 --- a/src/lux/compiler/lux.clj +++ b/src/lux/compiler/lux.clj @@ -135,5 +135,6 @@ (.visitEnd))]] (return nil))) :let [_ (.visitEnd *writer*)] - _ (&&/save-class! current-class (.toByteArray =class))] + _ (&&/save-class! current-class (.toByteArray =class)) + :let [_ (prn 'compile-def ?name)]] (return nil))) diff --git a/src/lux/lexer.clj b/src/lux/lexer.clj index fe899691c..c302ef75d 100644 --- a/src/lux/lexer.clj +++ b/src/lux/lexer.clj @@ -74,8 +74,8 @@ (return [ token]))) ^:private lex-bool ::bool #"^(true|false)" - ^:private lex-real ::real #"^(0|[1-9][0-9]*)\.[0-9]+" - ^:private lex-int ::int #"^(0|[1-9][0-9]*)" + ^:private lex-real ::real #"^-?(0|[1-9][0-9]*)\.[0-9]+" + ^:private lex-int ::int #"^-?(0|[1-9][0-9]*)" ^:private lex-ident ::ident +ident-re+) (def ^:private lex-char -- cgit v1.2.3