From 12402b01ce04428fee46a9441a4d1f4cf16db179 Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Sun, 13 Sep 2015 00:58:35 -0400 Subject: - Fixed bug wherein mutual recursion could occur between modules. - Fixed bug wherein recompiling a previously cached module didn't always trigger all the necessary recompilations from dependent modules. --- src/lux/analyser/lux.clj | 7 +++++-- src/lux/base.clj | 38 ++++++++++++++++++++++++++++++++++++-- src/lux/compiler.clj | 7 ++++--- src/lux/compiler/cache.clj | 6 ++++-- 4 files changed, 49 insertions(+), 9 deletions(-) diff --git a/src/lux/analyser/lux.clj b/src/lux/analyser/lux.clj index 4a03c4848..3de4db89f 100644 --- a/src/lux/analyser/lux.clj +++ b/src/lux/analyser/lux.clj @@ -364,7 +364,7 @@ (|do [;; :let [_ (prn 'MACRO-EXPAND|PRE (&/ident->text real-name))] macro-expansion #(-> macro (.apply ?args) (.apply %)) ;; :let [_ (prn 'MACRO-EXPAND|POST (&/ident->text real-name))] - ;; :let [_ (when (or (= "zip" (aget real-name 1)) + ;; :let [_ (when (or (= "invoke-interface$" (aget real-name 1)) ;; ;; (= "..?" (aget real-name 1)) ;; ;; (= "try$" (aget real-name 1)) ;; ) @@ -534,7 +534,10 @@ (return nil))] (&/save-module (|do [already-compiled? (&&module/exists? path) - ;; :let [_ (prn 'analyse-import module-name path already-compiled?)] + ;; :let [_ (prn 'analyse-import module-name path + ;; already-compiled?)] + active? (&/active-module? path) + _ (&/assert! (not active?) (str "[Analyser Error] Can't import a module that is mid-compilation: " path " @ " module-name)) _ (&&module/add-import path) _ (&/when% (not already-compiled?) (compile-module path))] (return &/Nil$))))) diff --git a/src/lux/base.clj b/src/lux/base.clj index aefa0cf4c..4c5d8ae44 100644 --- a/src/lux/base.clj +++ b/src/lux/base.clj @@ -80,12 +80,19 @@ "locals" "closure"]) +;; ModuleState +(deftags + ["Active" + "Compiled" + "Cached"]) + ;; Host (deftags ["writer" "loader" "classes" - "catching"]) + "catching" + "module-states"]) ;; Compiler (deftags @@ -110,7 +117,6 @@ (def eval-field "_eval") (def tags-field "_tags") (def module-class-name "_") - (def +name-separator+ ";") (defn T [& elems] @@ -604,6 +610,8 @@ store ;; "lux;catching" Nil$ + ;; "lux;module-states" + (|table) ))) (defn init-state [_] @@ -937,3 +945,29 @@ ($None) (V $None nil) ($Some xs**) (V $Some (V $Cons (T x xs**)))) ))) + +(do-template [ ] + (do (defn [module] + "(-> Text (Lux (,)))" + (fn [state] + (let [state* (update$ $host (fn [host] + (update$ $module-states + (fn [module-states] + (|put module (V nil) module-states)) + host)) + state)] + (V $Right (T state* nil))))) + (defn [module] + "(-> Text (Lux Bool))" + (fn [state] + (if-let [module-state (->> state (get$ $host) (get$ $module-states) (|get module))] + (V $Right (T state (|case module-state + () true + _ false))) + (V $Right (T state false))) + ))) + + flag-active-module active-module? $Active + flag-compiled-module compiled-module? $Compiled + flag-cached-module cached-module? $Cached + ) diff --git a/src/lux/compiler.clj b/src/lux/compiler.clj index 759fc98fc..d6bbb17ae 100644 --- a/src/lux/compiler.clj +++ b/src/lux/compiler.clj @@ -483,8 +483,8 @@ (|do [module-exists? (&a-module/exists? name)] (if module-exists? (fail "[Compiler Error] Can't redefine a module!") - (|do [_ (&&cache/delete name) - _ (&a-module/enter-module name) + (|do [_ (&a-module/enter-module name) + _ (&/flag-active-module name) :let [=class (doto (new ClassWriter ClassWriter/COMPUTE_MAXS) (.visit Opcodes/V1_6 (+ Opcodes/ACC_PUBLIC Opcodes/ACC_SUPER) (str (&host/->module-class name) "/_") nil "java/lang/Object" nil) @@ -529,7 +529,8 @@ .visitEnd) (.visitEnd)) ;; _ (prn 'CLOSED name =class) - ]] + ] + _ (&/flag-compiled-module name)] (&&/save-class! &/module-class-name (.toByteArray =class))) ?state) diff --git a/src/lux/compiler/cache.clj b/src/lux/compiler/cache.clj index 3532cf843..d4ce7516d 100644 --- a/src/lux/compiler/cache.clj +++ b/src/lux/compiler/cache.clj @@ -89,8 +89,9 @@ ;; _ (prn 'load/IMPORTS module imports) ] (|do [loads (&/map% (fn [_import] - (|do [content (&&io/read-file (str &&/input-dir "/" _import ".lux"))] - (load _import (hash content) compile-module))) + (|do [content (&&io/read-file (str &&/input-dir "/" _import ".lux")) + _ (load _import (hash content) compile-module)] + (&/cached-module? _import))) (if (= [""] imports) &/Nil$ (&/->list imports)))] @@ -120,6 +121,7 @@ &/->list)))] ;; (prn 'load module defs) (|do [_ (&a-module/enter-module module) + _ (&/flag-cached-module module) _ (&a-module/set-imports imports) _ (&/map% (fn [_def] (let [[_exported? _name _ann] (string/split _def #" ") -- cgit v1.2.3