From 69807626d51e2abf4c41a270d8e4de3ecec9e888 Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Sun, 12 Mar 2017 20:52:10 -0400 Subject: - The compiler can now load specialized modules, depending on the host-platform being targetted. --- luxc/src/lux/compiler/cache.clj | 4 +-- luxc/src/lux/compiler/io.clj | 40 ++++++++++++++------- luxc/src/lux/compiler/js.clj | 59 +++++++++++++++--------------- luxc/src/lux/compiler/jvm.clj | 79 ++++++++++++++++++++--------------------- 4 files changed, 97 insertions(+), 85 deletions(-) (limited to 'luxc/src') diff --git a/luxc/src/lux/compiler/cache.clj b/luxc/src/lux/compiler/cache.clj index 7299b7166..91aa8802b 100644 --- a/luxc/src/lux/compiler/cache.clj +++ b/luxc/src/lux/compiler/cache.clj @@ -123,7 +123,7 @@ (&/|map #(.split ^String % &&core/datum-separator 2) imports))] cache-table* (&/fold% (fn [cache-table* _import] (|do [:let [[_module _hash] _import] - file-content (&&io/read-file source-dirs (str _module ".lux")) + file-content (&&io/read-file source-dirs _module) output (pre-load! source-dirs cache-table* _module (hash file-content) load-def-value install-all-defs-in-module uninstall-all-defs-in-module)] (return output))) @@ -199,7 +199,7 @@ (|do [:let [fs-cached-modules (enumerate-cached-modules!)] pre-loaded-modules (&/fold% (fn [cache-table module-name] (fn [_compiler] - (|case ((&&io/read-file source-dirs (str module-name ".lux")) + (|case ((&&io/read-file source-dirs module-name) _compiler) (&/$Left error) (return* _compiler cache-table) diff --git a/luxc/src/lux/compiler/io.clj b/luxc/src/lux/compiler/io.clj index 82b80f624..f129fd3f0 100644 --- a/luxc/src/lux/compiler/io.clj +++ b/luxc/src/lux/compiler/io.clj @@ -10,17 +10,31 @@ (defn init-libs! [] (reset! !libs (&lib/load))) -(defn read-file [source-dirs ^String file-name] - (|case (&/|some (fn [^String source-dir] - (let [file (new java.io.File source-dir file-name)] - (if (.exists file) - (&/$Some file) - &/$None))) - source-dirs) - (&/$Some file) - (return (slurp file)) +(defn read-file [source-dirs module-name] + (|do [jvm? &/jvm? + js? &/js? + :let [^String host-file-name (cond jvm? (str module-name ".jvm.lux") + js? (str module-name ".js.lux") + :else (assert false "[I/O Error] Unknown host platform.")) + ^String lux-file-name (str module-name ".lux")]] + (|case (&/|some (fn [^String source-dir] + (let [host-file (new java.io.File source-dir host-file-name) + lux-file (new java.io.File source-dir lux-file-name)] + (cond (.exists host-file) + (&/$Some (&/T [host-file-name host-file])) - (&/$None) - (if-let [code (get @!libs file-name)] - (return code) - (&/fail-with-loc (str "[I/O Error] File doesn't exist: " file-name))))) + (.exists lux-file) + (&/$Some (&/T [lux-file-name lux-file])) + + :else + &/$None))) + source-dirs) + (&/$Some [file-name file]) + (return (&/T [file-name (slurp file)])) + + (&/$None) + (if-let [code (get @!libs host-file-name)] + (return (&/T [host-file-name code])) + (if-let [code (get @!libs lux-file-name)] + (return (&/T [lux-file-name code])) + (&/fail-with-loc (str "[I/O Error] Module doesn't exist: " module-name))))))) diff --git a/luxc/src/lux/compiler/js.clj b/luxc/src/lux/compiler/js.clj index fa4bf9518..4f0546bf0 100644 --- a/luxc/src/lux/compiler/js.clj +++ b/luxc/src/lux/compiler/js.clj @@ -127,36 +127,35 @@ (&&/wrap-lux-obj state)]))))])) (defn compile-module [source-dirs name] - (let [file-name (str name ".lux")] - (|do [file-content (&&io/read-file source-dirs file-name) - :let [file-hash (hash file-content) - compile-module!! (&¶llel/parallel-compilation (partial compile-module source-dirs))]] - (&/|eitherL (&&cache/load name) - (let [compiler-step (&analyser/analyse &optimizer/optimize eval! compile-module!! all-compilers)] - (|do [module-exists? (&a-module/exists? name)] - (if module-exists? - (&/fail-with-loc (str "[Compiler Error] Can't re-define a module: " name)) - (|do [_ (&&cache/delete name) - _ (&&/init-buffer) - _ (&a-module/create-module name file-hash) - _ (&a-module/flag-active-module name) - _ (if (= "lux" name) - &&rt/compile-LuxRT - (return nil))] - (fn [state] - (|case ((&/exhaust% compiler-step) - (&/set$ &/$source (&reader/from name file-content) state)) - (&/$Right ?state _) - (&/run-state (|do [_ (&a-module/flag-compiled-module name) - _ &&/save-module-js! - module-descriptor (&&core/generate-module-descriptor file-hash) - _ (&&core/write-module-descriptor! name module-descriptor)] - (return file-hash)) - ?state) - - (&/$Left ?message) - (&/fail* ?message))))))))) - )) + (|do [[file-name file-content] (&&io/read-file source-dirs name) + :let [file-hash (hash file-content) + compile-module!! (&¶llel/parallel-compilation (partial compile-module source-dirs))]] + (&/|eitherL (&&cache/load name) + (let [compiler-step (&analyser/analyse &optimizer/optimize eval! compile-module!! all-compilers)] + (|do [module-exists? (&a-module/exists? name)] + (if module-exists? + (&/fail-with-loc (str "[Compiler Error] Can't re-define a module: " name)) + (|do [_ (&&cache/delete name) + _ (&&/init-buffer) + _ (&a-module/create-module name file-hash) + _ (&a-module/flag-active-module name) + _ (if (= "lux" name) + &&rt/compile-LuxRT + (return nil))] + (fn [state] + (|case ((&/exhaust% compiler-step) + (&/set$ &/$source (&reader/from name file-content) state)) + (&/$Right ?state _) + (&/run-state (|do [_ (&a-module/flag-compiled-module name) + _ &&/save-module-js! + module-descriptor (&&core/generate-module-descriptor file-hash) + _ (&&core/write-module-descriptor! name module-descriptor)] + (return file-hash)) + ?state) + + (&/$Left ?message) + (&/fail* ?message))))))))) + ) (let [!err! *err*] (defn compile-program [mode program-module resources-dir source-dirs target-dir] diff --git a/luxc/src/lux/compiler/jvm.clj b/luxc/src/lux/compiler/jvm.clj index 7fd764e56..6c4731e16 100644 --- a/luxc/src/lux/compiler/jvm.clj +++ b/luxc/src/lux/compiler/jvm.clj @@ -173,46 +173,45 @@ (let [+field-flags+ (+ Opcodes/ACC_PUBLIC Opcodes/ACC_FINAL Opcodes/ACC_STATIC) +datum-sig+ "Ljava/lang/Object;"] (defn compile-module [source-dirs name] - (let [file-name (str name ".lux")] - (|do [file-content (&&io/read-file source-dirs file-name) - :let [file-hash (hash file-content) - compile-module!! (&¶llel/parallel-compilation (partial compile-module source-dirs))]] - (&/|eitherL (&&cache/load name) - (let [compiler-step (&analyser/analyse &optimizer/optimize eval! compile-module!! all-compilers)] - (|do [module-exists? (&a-module/exists? name)] - (if module-exists? - (&/fail-with-loc "[Compiler Error] Can't re-define a module!") - (|do [_ (&&cache/delete name) - _ (&a-module/create-module name file-hash) - _ (&a-module/flag-active-module name) - :let [module-class-name (str (&host/->module-class name) "/_") - =class (doto (new ClassWriter ClassWriter/COMPUTE_MAXS) - (.visit &host/bytecode-version (+ Opcodes/ACC_PUBLIC Opcodes/ACC_SUPER) - module-class-name nil "java/lang/Object" nil) - (.visitSource file-name nil))] - _ (if (= "lux" name) - (|do [_ &&rt/compile-Function-class - _ &&rt/compile-LuxRT-class - _ &&rt/compile-LuxRunnable-class] - (return nil)) - (return nil))] - (fn [state] - (|case ((&/with-writer =class - (&/exhaust% compiler-step)) - (&/set$ &/$source (&reader/from name file-content) state)) - (&/$Right ?state _) - (&/run-state (|do [:let [_ (.visitEnd =class)] - _ (&a-module/flag-compiled-module name) - _ (&&/save-class! &/module-class-name (.toByteArray =class)) - module-descriptor (&&core/generate-module-descriptor file-hash) - _ (&&core/write-module-descriptor! name module-descriptor)] - (return file-hash)) - ?state) - - (&/$Left ?message) - (&/fail* ?message)))))))) - ) - ))) + (|do [[file-name file-content] (&&io/read-file source-dirs name) + :let [file-hash (hash file-content) + compile-module!! (&¶llel/parallel-compilation (partial compile-module source-dirs))]] + (&/|eitherL (&&cache/load name) + (let [compiler-step (&analyser/analyse &optimizer/optimize eval! compile-module!! all-compilers)] + (|do [module-exists? (&a-module/exists? name)] + (if module-exists? + (&/fail-with-loc "[Compiler Error] Can't re-define a module!") + (|do [_ (&&cache/delete name) + _ (&a-module/create-module name file-hash) + _ (&a-module/flag-active-module name) + :let [module-class-name (str (&host/->module-class name) "/_") + =class (doto (new ClassWriter ClassWriter/COMPUTE_MAXS) + (.visit &host/bytecode-version (+ Opcodes/ACC_PUBLIC Opcodes/ACC_SUPER) + module-class-name nil "java/lang/Object" nil) + (.visitSource file-name nil))] + _ (if (= "lux" name) + (|do [_ &&rt/compile-Function-class + _ &&rt/compile-LuxRT-class + _ &&rt/compile-LuxRunnable-class] + (return nil)) + (return nil))] + (fn [state] + (|case ((&/with-writer =class + (&/exhaust% compiler-step)) + (&/set$ &/$source (&reader/from name file-content) state)) + (&/$Right ?state _) + (&/run-state (|do [:let [_ (.visitEnd =class)] + _ (&a-module/flag-compiled-module name) + _ (&&/save-class! &/module-class-name (.toByteArray =class)) + module-descriptor (&&core/generate-module-descriptor file-hash) + _ (&&core/write-module-descriptor! name module-descriptor)] + (return file-hash)) + ?state) + + (&/$Left ?message) + (&/fail* ?message)))))))) + ) + )) (let [define-class (doto (.getDeclaredMethod java.lang.ClassLoader "defineClass" (into-array [String (class (byte-array [])) -- cgit v1.2.3