From d1e7c4dd03a72a93dbca15cbc1b0ac29ab49efbc Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Fri, 16 Jan 2015 03:43:55 -0400 Subject: Fixed a bug in the ' macro. --- src/lux/analyser.clj | 26 ++++++++++++------------ src/lux/compiler.clj | 57 +++++++++++++++++++++++++++++++--------------------- src/lux/util.clj | 4 +++- 3 files changed, 50 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/lux/analyser.clj b/src/lux/analyser.clj index 6b823b3ee..1aa2d587b 100644 --- a/src/lux/analyser.clj +++ b/src/lux/analyser.clj @@ -477,39 +477,39 @@ ;; (prn '->token x) (match x [::&parser/bool ?bool] - (doto (.newInstance (.loadClass loader "test2.Variant1")) + (doto (.newInstance (.loadClass @loader "test2.Variant1")) (-> .-tag (set! "Bool")) (-> .-_1 (set! ?bool))) [::&parser/int ?int] - (doto (.newInstance (.loadClass loader "test2.Variant1")) + (doto (.newInstance (.loadClass @loader "test2.Variant1")) (-> .-tag (set! "Int")) (-> .-_1 (set! ?int))) [::&parser/real ?real] - (doto (.newInstance (.loadClass loader "test2.Variant1")) + (doto (.newInstance (.loadClass @loader "test2.Variant1")) (-> .-tag (set! "Real")) (-> .-_1 (set! ?real))) [::&parser/char ?elem] - (doto (.newInstance (.loadClass loader "test2.Variant1")) + (doto (.newInstance (.loadClass @loader "test2.Variant1")) (-> .-tag (set! "Char")) (-> .-_1 (set! ?elem))) [::&parser/text ?text] - (doto (.newInstance (.loadClass loader "test2.Variant1")) + (doto (.newInstance (.loadClass @loader "test2.Variant1")) (-> .-tag (set! "Text")) (-> .-_1 (set! ?text))) [::&parser/tag ?tag] - (doto (.newInstance (.loadClass loader "test2.Variant1")) + (doto (.newInstance (.loadClass @loader "test2.Variant1")) (-> .-tag (set! "Tag")) (-> .-_1 (set! ?tag))) [::&parser/ident ?ident] - (doto (.newInstance (.loadClass loader "test2.Variant1")) + (doto (.newInstance (.loadClass @loader "test2.Variant1")) (-> .-tag (set! "Ident")) (-> .-_1 (set! ?ident))) [::&parser/tuple ?elems] - (doto (.newInstance (.loadClass loader "test2.Variant1")) + (doto (.newInstance (.loadClass @loader "test2.Variant1")) (-> .-tag (set! "Tuple")) (-> .-_1 (set! (->tokens ?elems)))) [::&parser/form ?elems] - (doto (.newInstance (.loadClass loader "test2.Variant1")) + (doto (.newInstance (.loadClass @loader "test2.Variant1")) (-> .-tag (set! "Form")) (-> .-_1 (set! (->tokens ?elems)))) )) @@ -517,11 +517,11 @@ (defn ->tokens [xs] (reduce (fn [tail x] ;; (prn 'tail (.-tag tail) 'x x) - (doto (.newInstance (.loadClass loader "test2.Variant2")) + (doto (.newInstance (.loadClass @loader "test2.Variant2")) (-> .-tag (set! "Cons")) (-> .-_1 (set! (->token x))) (-> .-_2 (set! tail)))) - (doto (.newInstance (.loadClass loader "test2.Variant0")) + (doto (.newInstance (.loadClass @loader "test2.Variant0")) (-> .-tag (set! "Nil"))) (reverse xs))) @@ -557,12 +557,12 @@ :let [_ (prn 'analyse-call [:global-fn ?module ?name] macro? scoped?)]] (if (and macro? (not scoped?)) (let [macro-class (str ?module "$" (normalize-ident ?name)) - transformed (-> (.loadClass loader macro-class) + transformed (-> (.loadClass @loader macro-class) .newInstance (.apply (->tokens ?args)) ->clojure-token) _ (prn 'analyse-call/transformed transformed)] - (-> (.loadClass loader macro-class) + (-> (.loadClass @loader macro-class) .newInstance (.apply (->tokens ?args)) ->clojure-token diff --git a/src/lux/compiler.clj b/src/lux/compiler.clj index aea9ea1e2..31b440b88 100644 --- a/src/lux/compiler.clj +++ b/src/lux/compiler.clj @@ -8,7 +8,7 @@ repeat-m try-m try-all-m map-m reduce-m apply-m within normalize-ident - loader]] + loader reset-loader!]] [type :as &type] [lexer :as &lexer] [parser :as &parser] @@ -36,7 +36,7 @@ ;; (println "Defining..." name "@" file-name ;; (alength bytecode) ;; ) ;; (prn 'loader loader) - (.loadClass loader name) + (.loadClass @loader name) ;; (println "SUCCESFUL LOAD!") ;; (.defineClass loader name bytecode 0 (alength bytecode)) )) @@ -281,24 +281,26 @@ nil) ))) -(defcompiler ^:private compile-if - [::&analyser/if ?test ?then ?else] - (let [else-label (new Label) - end-label (new Label)] - ;; (println "PRE") - (compile-form (assoc *state* :form ?test)) - (doto *writer* - (.visitMethodInsn Opcodes/INVOKEVIRTUAL (->class "java.lang.Boolean") "booleanValue" "()Z") - (.visitJumpInsn Opcodes/IFEQ else-label)) - ;; (prn 'compile-if/?then (:form ?then)) - (compile-form (assoc *state* :form ?then)) - ;; (.visitInsn *writer* Opcodes/POP) - (doto *writer* - (.visitJumpInsn Opcodes/GOTO end-label) - (.visitLabel else-label)) - (compile-form (assoc *state* :form ?else)) - ;; (.visitInsn *writer* Opcodes/POP) - (.visitLabel *writer* end-label))) +(let [+bool-class+ (->class "java.lang.Boolean")] + (defcompiler ^:private compile-if + [::&analyser/if ?test ?then ?else] + (let [else-label (new Label) + end-label (new Label)] + ;; (println "PRE") + (compile-form (assoc *state* :form ?test)) + (doto *writer* + (.visitTypeInsn Opcodes/CHECKCAST +bool-class+) + (.visitMethodInsn Opcodes/INVOKEVIRTUAL +bool-class+ "booleanValue" "()Z") + (.visitJumpInsn Opcodes/IFEQ else-label)) + ;; (prn 'compile-if/?then (:form ?then)) + (compile-form (assoc *state* :form ?then)) + ;; (.visitInsn *writer* Opcodes/POP) + (doto *writer* + (.visitJumpInsn Opcodes/GOTO end-label) + (.visitLabel else-label)) + (compile-form (assoc *state* :form ?else)) + ;; (.visitInsn *writer* Opcodes/POP) + (.visitLabel *writer* end-label)))) (defcompiler ^:private compile-do [::&analyser/do ?exprs] @@ -330,6 +332,11 @@ (.visitInsn Opcodes/POP) (.visitJumpInsn Opcodes/GOTO default-label))) + [::default [::&analyser/local _ ?idx] $body] + (doto writer + (.visitVarInsn Opcodes/ASTORE ?idx) + (.visitJumpInsn Opcodes/GOTO (get mappings $body))) + [::store [::&analyser/local _ ?idx] $body] (doto writer (.visitVarInsn Opcodes/ASTORE ?idx) @@ -543,10 +550,13 @@ (.visitVarInsn Opcodes/ASTORE ?idx) (.visitJumpInsn Opcodes/GOTO (get mappings* ?body))) (doto *writer* - (.visitInsn Opcodes/POP) + ;; (.visitInsn Opcodes/POP) + (.visitTypeInsn Opcodes/CHECKCAST (->class +variant-class+)) + (.visitFieldInsn Opcodes/GETFIELD (->class +variant-class+) "tag" (->type-signature "java.lang.String")) (.visitTypeInsn Opcodes/NEW ex-class) - (.visitInsn Opcodes/DUP) - (.visitMethodInsn Opcodes/INVOKESPECIAL ex-class "" "()V") + (.visitInsn Opcodes/DUP_X1) + (.visitInsn Opcodes/SWAP) + (.visitMethodInsn Opcodes/INVOKESPECIAL ex-class "" (str "(" (->type-signature "java.lang.String") ")" "V")) (.visitInsn Opcodes/ATHROW))) ;; (if default-code ;; ;; (do (prn 'default-code default-code) @@ -1006,6 +1016,7 @@ ;; [Interface] (defn compile [class-name inputs] ;; (prn 'inputs inputs) + (reset-loader!) (let [=class (doto (new ClassWriter ClassWriter/COMPUTE_MAXS) (.visit Opcodes/V1_5 (+ Opcodes/ACC_PUBLIC Opcodes/ACC_SUPER) (->class class-name) nil "java/lang/Object" nil)) diff --git a/src/lux/util.clj b/src/lux/util.clj index 890b73880..5496e8699 100644 --- a/src/lux/util.clj +++ b/src/lux/util.clj @@ -160,4 +160,6 @@ (defn normalize-ident [ident] (reduce str "" (map normalize-char ident))) -(defonce loader (-> (java.io.File. "./") .toURL vector into-array java.net.URLClassLoader.)) +(defonce loader (atom nil)) +(defn reset-loader! [] + (reset! loader (-> (java.io.File. "./") .toURL vector into-array java.net.URLClassLoader.))) -- cgit v1.2.3