aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEduardo Julian2015-01-11 17:55:14 -0400
committerEduardo Julian2015-01-11 17:55:14 -0400
commit7f076e6ca1a107b6b0ce54784e9b9eb2ae715771 (patch)
tree5d4a83f39cdb814d37bf03dc9c9aae853ddd1490
parenta315700f4fb7b981fff3bab0a29de0ec53fc1e6b (diff)
- Added integer remainder.
- Now, can handle boolean returns from methods. - Static functions now define a "_datum" field containing an empty instance. - Fixed a bug when analysing lambdas that made their arguments get treated like they were closure variables.
-rw-r--r--src/lux/analyser.clj6
-rw-r--r--src/lux/compiler.clj72
-rw-r--r--src/lux/parser.clj10
-rw-r--r--test2.lux47
4 files changed, 92 insertions, 43 deletions
diff --git a/src/lux/analyser.clj b/src/lux/analyser.clj
index 4866ab04e..1bac77dce 100644
--- a/src/lux/analyser.clj
+++ b/src/lux/analyser.clj
@@ -188,7 +188,9 @@
(update-in [:env] rest)
;; (update-in [:lambda-scope 1] inc)
)
- [(get-in ?state [:lambda-scope 0]) (-> ?state :env first) ?value]]])
+ [(get-in ?state [:lambda-scope 0])
+ (-> ?state :env first (update-in [:mappings] #(reduce dissoc % args-vars)))
+ ?value]]])
_
=return)))))
@@ -849,6 +851,7 @@
^:private analyse-jvm-i- ::&parser/jvm-i- ::jvm-i-
^:private analyse-jvm-i* ::&parser/jvm-i* ::jvm-i*
^:private analyse-jvm-idiv ::&parser/jvm-idiv ::jvm-idiv
+ ^:private analyse-jvm-irem ::&parser/jvm-irem ::jvm-irem
)
(def analyse-form
@@ -877,6 +880,7 @@
analyse-jvm-i-
analyse-jvm-i*
analyse-jvm-idiv
+ analyse-jvm-irem
analyse-jvm-getstatic
analyse-jvm-invokevirtual]))
diff --git a/src/lux/compiler.clj b/src/lux/compiler.clj
index 5db85d17f..9ffee56dc 100644
--- a/src/lux/compiler.clj
+++ b/src/lux/compiler.clj
@@ -81,6 +81,9 @@
::&type/any
(->java-sig [::&type/object "java.lang.Object" []])
+ [::&type/primitive "boolean"]
+ "Z"
+
[::&type/object ?name []]
(->type-signature ?name)
@@ -169,6 +172,11 @@
(.visitFieldInsn Opcodes/GETSTATIC (->class (str ?owner-class "$" (normalize-ident ?name))) "_datum" "Ljava/lang/Object;" ;; (->java-sig *type*)
))))
+(defcompiler ^:private compile-global-fn
+ [::&analyser/global-fn ?owner-class ?name]
+ (let [fn-class (str ?owner-class "$" (normalize-ident ?name))]
+ (.visitFieldInsn *writer* Opcodes/GETSTATIC (->class fn-class) "_datum" (->type-signature fn-class))))
+
;; (defcompiler ^:private compile-call
;; [::&analyser/call ?fn ?args]
;; (do (prn 'compile-call (:form ?fn) ?fn ?args)
@@ -249,23 +257,27 @@
(.visitInsn Opcodes/ACONST_NULL)))
))
-(defcompiler ^:private compile-jvm-invokevirtual
- [::&analyser/jvm-invokevirtual ?class ?method ?classes ?object ?args]
- (let [_ (prn 'compile-jvm-invokevirtual [?class ?method ?classes] '-> *type*)
- method-sig (str "(" (reduce str "" (map ->type-signature ?classes)) ")" (->java-sig *type*))]
- (compile-form (assoc *state* :form ?object))
- (.visitTypeInsn *writer* Opcodes/CHECKCAST (->class ?class))
- (doseq [[class-name arg] (map vector ?classes ?args)]
- (do (compile-form (assoc *state* :form arg))
- (.visitTypeInsn *writer* Opcodes/CHECKCAST (->class class-name))))
- (.visitMethodInsn *writer* Opcodes/INVOKEVIRTUAL (->class ?class) ?method method-sig)
- (match *type*
- ::&type/nothing
- (.visitInsn *writer* Opcodes/ACONST_NULL)
-
- [::&type/object ?oclass _]
- nil)
- ))
+(let [boolean-class "java.lang.Boolean"]
+ (defcompiler ^:private compile-jvm-invokevirtual
+ [::&analyser/jvm-invokevirtual ?class ?method ?classes ?object ?args]
+ (let [_ (prn 'compile-jvm-invokevirtual [?class ?method ?classes] '-> *type*)
+ method-sig (str "(" (reduce str "" (map ->type-signature ?classes)) ")" (->java-sig *type*))]
+ (compile-form (assoc *state* :form ?object))
+ (.visitTypeInsn *writer* Opcodes/CHECKCAST (->class ?class))
+ (doseq [[class-name arg] (map vector ?classes ?args)]
+ (do (compile-form (assoc *state* :form arg))
+ (.visitTypeInsn *writer* Opcodes/CHECKCAST (->class class-name))))
+ (.visitMethodInsn *writer* Opcodes/INVOKEVIRTUAL (->class ?class) ?method method-sig)
+ (match *type*
+ ::&type/nothing
+ (.visitInsn *writer* Opcodes/ACONST_NULL)
+
+ [::&type/primitive "boolean"]
+ (.visitMethodInsn *writer* Opcodes/INVOKESTATIC (->class boolean-class) "valueOf" (str "(Z)" (->type-signature boolean-class)))
+
+ [::&type/object ?oclass _]
+ nil)
+ )))
(defcompiler ^:private compile-if
[::&analyser/if ?test ?then ?else]
@@ -528,6 +540,7 @@
apply-signature "(Ljava/lang/Object;)Ljava/lang/Object;"
real-signature (str "(" (apply str (repeat num-args clo-field-sig)) ")" "Ljava/lang/Object;")
current-class (str outer-class "$" (normalize-ident fn-name))
+ self-sig (->type-signature current-class)
num-captured (dec num-args)
init-signature (if (not= 0 num-captured)
(str "(" (apply str counter-sig (repeat num-captured clo-field-sig)) ")" "V")
@@ -536,9 +549,10 @@
(let [=class (doto (new ClassWriter ClassWriter/COMPUTE_MAXS)
(.visit Opcodes/V1_5 (+ Opcodes/ACC_PUBLIC Opcodes/ACC_FINAL Opcodes/ACC_SUPER)
current-class nil "java/lang/Object" (into-array ["test2/Function"]))
- (-> (doto (.visitField (+ Opcodes/ACC_PRIVATE Opcodes/ACC_FINAL) "_counter" counter-sig nil nil)
- (.visitEnd))
- (->> (when (not= 0 num-captured)))))
+ (.visitField (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "_datum" self-sig nil nil)
+ (-> (.visitField (+ Opcodes/ACC_PRIVATE Opcodes/ACC_FINAL) "_counter" counter-sig nil nil)
+ (->> (when (not= 0 num-captured))))
+ (.visitEnd))
=impl (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "impl" real-signature nil nil)
(.visitCode)
(->> (assoc *state* :form body :writer) compile-form)
@@ -563,6 +577,19 @@
(.visitInsn Opcodes/RETURN)
(.visitMaxs 0 0)
(.visitEnd))
+ =clinit (doto (.visitMethod =class Opcodes/ACC_PUBLIC "<clinit>" "()V" nil nil)
+ (.visitCode)
+ (.visitTypeInsn Opcodes/NEW current-class)
+ (.visitInsn Opcodes/DUP)
+ (-> (doto (.visitLdcInsn (int 0))
+ (-> (.visitInsn Opcodes/ACONST_NULL)
+ (->> (dotimes [_ num-captured]))))
+ (->> (when (> num-captured 0))))
+ (.visitMethodInsn Opcodes/INVOKESPECIAL current-class "<init>" init-signature)
+ (.visitFieldInsn Opcodes/PUTSTATIC current-class "_datum" self-sig)
+ (.visitInsn Opcodes/RETURN)
+ (.visitMaxs 0 0)
+ (.visitEnd))
=method (let [default-label (new Label)
branch-labels (for [_ (range num-captured)]
(new Label))]
@@ -661,7 +688,7 @@
(defcompiler ^:private compile-lambda
[::&analyser/lambda ?scope ?frame ?args ?body]
- (let [;; _ (prn '[?scope ?frame] ?scope ?frame)
+ (let [_ (prn '[?scope ?frame] ?scope ?frame ?args)
num-args (count ?args)
outer-class (->class *class-name*)
clo-field-sig (->type-signature "java.lang.Object")
@@ -915,6 +942,7 @@
^:private compile-jvm-i- ::&analyser/jvm-i- Opcodes/ISUB
^:private compile-jvm-i* ::&analyser/jvm-i* Opcodes/IMUL
^:private compile-jvm-idiv ::&analyser/jvm-idiv Opcodes/IDIV
+ ^:private compile-jvm-irem ::&analyser/jvm-irem Opcodes/IREM
))
(let [+compilers+ [compile-literal
@@ -923,6 +951,7 @@
compile-local
compile-captured
compile-global
+ compile-global-fn
compile-static-call
compile-call
compile-dynamic-field
@@ -942,6 +971,7 @@
compile-jvm-i-
compile-jvm-i*
compile-jvm-idiv
+ compile-jvm-irem
compile-jvm-getstatic
compile-jvm-invokevirtual]]
(defn ^:private compile-form [state]
diff --git a/src/lux/parser.clj b/src/lux/parser.clj
index 4de0b6896..db64adf4a 100644
--- a/src/lux/parser.clj
+++ b/src/lux/parser.clj
@@ -202,10 +202,11 @@
=y (apply-m parse-form (list ?y))]
(return [<tag> =x =y])))
- ^:private parse-jvm-i+ "jvm/i+" ::jvm-i+
- ^:private parse-jvm-i- "jvm/i-" ::jvm-i-
- ^:private parse-jvm-i* "jvm/i*" ::jvm-i*
- ^:private parse-jvm-idiv "jvm/i/" ::jvm-idiv
+ ^:private parse-jvm-i+ "jvm/i+" ::jvm-i+
+ ^:private parse-jvm-i- "jvm/i-" ::jvm-i-
+ ^:private parse-jvm-i* "jvm/i*" ::jvm-i*
+ ^:private parse-jvm-idiv "jvm/i/" ::jvm-idiv
+ ^:private parse-jvm-irem "jvm/irem" ::jvm-irem
)
(def ^:private parse-form
@@ -236,6 +237,7 @@
parse-jvm-i-
parse-jvm-i*
parse-jvm-idiv
+ parse-jvm-irem
parse-jvm-getstatic
parse-jvm-invokevirtual
parse-fn-call]))
diff --git a/test2.lux b/test2.lux
index 19054e699..9cea62d8a 100644
--- a/test2.lux
+++ b/test2.lux
@@ -67,6 +67,10 @@
[java.lang.Object _5] [java.lang.Object _6]
[java.lang.Object _7] [java.lang.Object _8]])
+(def (println x)
+ (jvm/invokevirtual java.io.PrintStream "println" [Object]
+ (jvm/getstatic System out) [x]))
+
(def (++ xs ys)
(case xs
#Nil
@@ -139,22 +143,26 @@
(def inc (+ 1))
-#( (def (fold f init values)
- (case values
- #Nil
- init
- (#Cons x xs)
- (fold f (f init x) xs)))
+(def (id x)
+ x)
- (def length (fold inc 0))
+(def (fold f init values)
+ (case values
+ #Nil
+ init
+ (#Cons x xs)
+ (fold f (f init x) xs)))
- (def (mod dividend divisor)
- (jvm/imod dividend divisor))
+(def length (fold (lambda [l x] (inc l)) 0))
- (def (= x y)
- (.equals x y))
+(def (rem dividend divisor)
+ (jvm/irem dividend divisor))
- (def (as-pairs list)
+(def (= x y)
+ (jvm/invokevirtual Object "equals" [Object]
+ x [y]))
+
+#( (def (as-pairs list)
(case list
(#Cons x (#Cons y list*))
(#Cons [x y] (as-pairs list*))
@@ -175,10 +183,6 @@
(as-pairs steps))
(#Text "Oh no!")))) )#
-(def (println x)
- (jvm/invokevirtual java.io.PrintStream "println" [Object]
- (jvm/getstatic System out) [x]))
-
## Program
(def (main args)
(case (' ((~ "Oh yeah...")))
@@ -188,7 +192,16 @@
(println (inc 10))
(println (jvm/i- 10 20))
(println (jvm/i* 10 20))
- (println (jvm/i/ 10 2)))
+ (println (jvm/i/ 10 2))
+ (let list (#Cons 1 (#Cons 2 (#Cons 3 (#Cons 4 (#Cons 5 (#Cons 6 #Nil))))))
+ (do (println (fold + 0 list))
+ (println (length list))))
+ (println (rem 21 6))
+ (println (rem 21 7))
+ (println (= false false))
+ (println (= false true))
+ (println (= true false))
+ (println (= true true)))
))
#( (def (main args)