From fe0ae000cbec6f087b8997a6e3e3cf508278d066 Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Wed, 17 Feb 2016 18:36:29 -0400 Subject: - Added CompilerMode and CompilerInfo data to the Compiler state. - Removed the (now unnecessary #;eval? tag). --- src/lux.clj | 8 ++++++- src/lux/analyser/record.clj | 6 ++++- src/lux/base.clj | 53 +++++++++++++++++++++++++++++++++++---------- src/lux/compiler.clj | 6 ++--- src/lux/compiler/base.clj | 9 +++----- src/lux/compiler/cache.clj | 2 +- 6 files changed, 60 insertions(+), 24 deletions(-) diff --git a/src/lux.clj b/src/lux.clj index 15ba16e5c..f1f43b7af 100644 --- a/src/lux.clj +++ b/src/lux.clj @@ -14,7 +14,13 @@ (defn -main [& args] (|case (&/->list args) (&/$Cons "compile" (&/$Cons program-module (&/$Nil))) - (time (&compiler/compile-program program-module)) + (time (&compiler/compile-program &/$Release program-module)) + + (&/$Cons "compile" (&/$Cons "release" (&/$Cons program-module (&/$Nil)))) + (time (&compiler/compile-program &/$Release program-module)) + + (&/$Cons "compile" (&/$Cons "debug" (&/$Cons program-module (&/$Nil)))) + (time (&compiler/compile-program &/$Debug program-module)) _ (println "Can't understand command."))) diff --git a/src/lux/analyser/record.clj b/src/lux/analyser/record.clj index 8c8c657dc..335b46dbb 100644 --- a/src/lux/analyser/record.clj +++ b/src/lux/analyser/record.clj @@ -35,9 +35,13 @@ _ (fail "[Analyser Error] Wrong syntax for records. Odd elements must be tags."))) pairs) + _ (let [num-expected (&/|length tag-group) + num-got (&/|length =pairs)] + (&/assert! (= num-expected num-got) + (str "[Analyser Error] Wrong number of record members. Expected " num-expected ", but got " num-got "."))) =members (&/map% (fn [tag] (if-let [member (&/|get tag =pairs)] (return member) - (fail (str "[Analyser Error] Unknown tag: " tag)))) + (fail (str "[Analyser Error] Missing tag: " tag)))) (&/|map &/ident->text tag-group))] (return (&/T [=members tag-type])))) diff --git a/src/lux/base.clj b/src/lux/base.clj index 74bb7bfc1..581930e3a 100644 --- a/src/lux/base.clj +++ b/src/lux/base.clj @@ -130,15 +130,25 @@ "type-env"]) ;; Compiler +(defvariant + ("Release" 0) + ("Debug" 0) + ("Eval" 0)) + +(deftuple + ["compiler-name" + "compiler-version" + "compiler-mode"]) + (deftuple - ["source" + ["info" + "source" "cursor" "modules" "envs" "type-vars" "expected" "seed" - "eval?" "host"]) ;; Compiler @@ -711,8 +721,22 @@ ;; lux;type-env (|table)]))) -(defn init-state [_] - (T [;; "lux;source" +(def ^String compiler-name "Lux/JVM") +(def ^String compiler-version "0.3.3") + +(defn default-compiler-info [mode] + (T [;; compiler-name + compiler-name + ;; compiler-version + compiler-version + ;; compiler-mode + mode] + )) + +(defn init-state [mode] + (T [;; "lux;info" + (default-compiler-info mode) + ;; "lux;source" $None ;; "lux;cursor" (T ["" -1 -1]) @@ -726,8 +750,6 @@ $VoidT ;; "lux;seed" 0 - ;; "lux;eval?" - false ;; "lux;host" (host nil)] )) @@ -744,18 +766,25 @@ ($Left msg) (fail* msg)))) +(defn ^:private is-eval? [mode] + "(-> CompilerMode Bool)" + (|case mode + ($Eval) true + _ false)) + (defn with-eval [body] (fn [state] - (|case (body (set$ $eval? true state)) - ($Right state* output) - (return* (set$ $eval? (get$ $eval? state) state*) output) + (let [old-mode (->> state (get$ $info) (get$ $compiler-mode))] + (|case (body (update$ $info #(set$ $compiler-mode $Eval %) state)) + ($Right state* output) + (return* (update$ $info #(set$ $compiler-mode old-mode %) state*) output) - ($Left msg) - (fail* msg)))) + ($Left msg) + (fail* msg))))) (def get-eval (fn [state] - (return* state (get$ $eval? state)))) + (return* state (->> state (get$ $info) (get$ $compiler-mode) is-eval?)))) (def get-writer (fn [state] diff --git a/src/lux/compiler.clj b/src/lux/compiler.clj index 60ae32558..fa9527282 100644 --- a/src/lux/compiler.clj +++ b/src/lux/compiler.clj @@ -486,7 +486,7 @@ (str (&host/->module-class name) "/_") nil "java/lang/Object" nil) (-> (.visitField (+ Opcodes/ACC_PUBLIC Opcodes/ACC_FINAL Opcodes/ACC_STATIC) &/hash-field "I" nil file-hash) .visitEnd) - (-> (.visitField (+ Opcodes/ACC_PUBLIC Opcodes/ACC_FINAL Opcodes/ACC_STATIC) &/compiler-field "Ljava/lang/String;" nil &&/version) + (-> (.visitField (+ Opcodes/ACC_PUBLIC Opcodes/ACC_FINAL Opcodes/ACC_STATIC) &/compiler-field "Ljava/lang/String;" nil &/compiler-version) .visitEnd) (.visitSource file-name nil))] _ (if (= "lux" name) @@ -541,10 +541,10 @@ (.mkdirs (java.io.File. &&/output-dir))) ;; [Resources] -(defn compile-program [program-module] +(defn compile-program [mode program-module] (init!) (let [m-action (&/map% compile-module (&/|list "lux" program-module))] - (|case (m-action (&/init-state nil)) + (|case (m-action (&/init-state mode)) (&/$Right ?state _) (do (println "Compilation complete!") (&&cache/clean ?state) diff --git a/src/lux/compiler/base.clj b/src/lux/compiler/base.clj index b4c678b00..d2f84816d 100644 --- a/src/lux/compiler/base.clj +++ b/src/lux/compiler/base.clj @@ -25,7 +25,6 @@ (java.lang.reflect Field))) ;; [Constants] -(def ^String version "0.3.3") (def ^String input-dir "source") (def ^String output-dir "target/jvm") (def ^String output-package (str output-dir "/" "program.jar")) @@ -50,11 +49,9 @@ ;; [Utils] (defn ^:private write-file [^String file-name ^bytes data] - (let [;; file-name (.toLowerCase file-name) - ] - (do (assert (not (.exists (File. file-name))) (str "Can't overwrite file: " file-name)) - (with-open [stream (BufferedOutputStream. (FileOutputStream. file-name))] - (.write stream data))))) + (do (assert (not (.exists (File. file-name))) (str "Can't overwrite file: " file-name)) + (with-open [stream (BufferedOutputStream. (FileOutputStream. file-name))] + (.write stream data)))) (defn ^:private write-output [module name data] (let [module* (&host/->module-class module) diff --git a/src/lux/compiler/cache.clj b/src/lux/compiler/cache.clj index bd463635d..acbe2e6b9 100644 --- a/src/lux/compiler/cache.clj +++ b/src/lux/compiler/cache.clj @@ -91,7 +91,7 @@ ^Class module-meta (do (swap! !classes assoc class-name (read-file (File. (str module-path "/_.class")))) (&&/load-class! loader class-name))] (if (and (= module-hash (get-field &/hash-field module-meta)) - (= &&/version (get-field &/compiler-field module-meta))) + (= &/compiler-version (get-field &/compiler-field module-meta))) (let [imports (string/split (get-field &/imports-field module-meta) import-separator-re)] (|do [loads (&/map% (fn [_import] (|do [content (&&io/read-file (str _import ".lux")) -- cgit v1.2.3