From e1b37ec360d39e218bc6b617ace23cd665d0189d Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Sun, 9 Oct 2016 19:39:53 -0400 Subject: - Now merging compiler-states pre-and-post module compilation. - Added a temporary fix for the survival/accumulation of zombie type-vars. --- project.clj | 3 ++- src/lux/analyser/module.clj | 33 ++++++++++++++++-------- src/lux/compiler.clj | 12 ++++++--- src/lux/compiler/parallel.clj | 60 +++++++++++++++++++++++++++++++++++++++++++ src/lux/packager/program.clj | 6 +++-- 5 files changed, 97 insertions(+), 17 deletions(-) create mode 100644 src/lux/compiler/parallel.clj diff --git a/project.clj b/project.clj index 726b3b120..5ea065037 100644 --- a/project.clj +++ b/project.clj @@ -13,7 +13,8 @@ [:url "https://github.com/eduardoejp"]]] :dependencies [[org.clojure/clojure "1.6.0"] [org.clojure/core.match "0.2.1"] - [org.ow2.asm/asm-all "5.0.3"]] + [org.ow2.asm/asm-all "5.0.3"] + [org.clojure/core.async "0.2.391"]] :warn-on-reflection true :main lux :repositories [["snapshots" "https://oss.sonatype.org/content/repositories/snapshots/"] diff --git a/src/lux/analyser/module.clj b/src/lux/analyser/module.clj index a06988a3f..6af4adff6 100644 --- a/src/lux/analyser/module.clj +++ b/src/lux/analyser/module.clj @@ -43,8 +43,9 @@ )) ;; [Exports] -(defn add-import [module] +(defn add-import "(-> Text (Lux Null))" + [module] (|do [current-module &/get-module-name] (fn [state] (if (&/|member? module (->> state (&/get$ &/$modules) (&/|get current-module) (&/get$ $imports))) @@ -58,8 +59,9 @@ state) nil))))) -(defn set-imports [imports] +(defn set-imports "(-> (List Text) (Lux Null))" + [imports] (|do [current-module &/get-module-name] (fn [state] (return* (&/update$ &/$modules @@ -91,8 +93,9 @@ ((&/fail-with-loc (str "[Analyser Error] Can't create a new global definition outside of a global environment: " module ";" name)) state)))) -(defn def-type [module name] +(defn def-type "(-> Text Text (Lux Type))" + [module name] (fn [state] (if-let [$module (->> state (&/get$ &/$modules) (&/|get module))] (if-let [$def (->> $module (&/get$ $defs) (&/|get name))] @@ -103,8 +106,9 @@ ((&/fail-with-loc (str "[Analyser Error] Unknown module: " module)) state)))) -(defn type-def [module name] +(defn type-def "(-> Text Text (Lux [Bool Type]))" + [module name] (fn [state] (if-let [$module (->> state (&/get$ &/$modules) (&/|get module))] (if-let [$def (->> $module (&/get$ $defs) (&/|get name))] @@ -127,8 +131,9 @@ ((&/fail-with-loc (str "[Analyser Error] Unknown module: " module)) state)))) -(defn exists? [name] +(defn exists? "(-> Text (Lux Bool))" + [name] (fn [state] (return* state (->> state (&/get$ &/$modules) (&/|contains? name))))) @@ -220,8 +225,9 @@ state)) ))) -(defn ensure-type-def [def-data] +(defn ensure-type-def "(-> DefData (Lux Type))" + [def-data] (|let [[?type ?meta ?value] def-data] (|case (&meta/meta-get &meta/type?-tag ?meta) (&/$Some _) @@ -235,8 +241,9 @@ (return true)) (return false)))) -(defn create-module [name hash] +(defn create-module "(-> Text Hash-Code (Lux Null))" + [name hash] (fn [state] (return* (->> state (&/update$ &/$modules #(&/|put name (new-module hash) %)) @@ -244,8 +251,9 @@ nil))) (do-template [ ] - (defn [module] + (defn + [module] (fn [state] (if-let [=module (->> state (&/get$ &/$modules) (&/|get module))] (return* state (&/get$ =module)) @@ -282,8 +290,9 @@ (str "[Analyser Error] Can't re-declare type: " (&/ident->text (&/T [module name]))))] (return nil))) -(defn declare-tags [module tag-names was-exported? type] +(defn declare-tags "(-> Text (List Text) Bool Type (Lux Null))" + [module tag-names was-exported? type] (|do [_ (ensure-undeclared-tags module tag-names) type-name (&type/type-name type) :let [[_module _name] type-name] @@ -309,8 +318,9 @@ ((&/fail-with-loc (str "[Lux Error] Unknown module: " module)) state))))) -(defn ensure-can-see-tag [module tag-name] +(defn ensure-can-see-tag "(-> Text Text (Lux Unit))" + [module tag-name] (|do [current-module &/get-module-name] (fn [state] (if-let [=module (->> state (&/get$ &/$modules) (&/|get module))] @@ -327,8 +337,9 @@ state))))) (do-template [ ] - (defn [module tag-name] + (defn + [module tag-name] (fn [state] (if-let [=module (->> state (&/get$ &/$modules) (&/|get module))] (if-let [^objects idx+tags+exported+type (&/|get tag-name (&/get$ $tags =module))] diff --git a/src/lux/compiler.clj b/src/lux/compiler.clj index 7bf53ada7..5dd2e3684 100644 --- a/src/lux/compiler.clj +++ b/src/lux/compiler.clj @@ -29,7 +29,8 @@ [case :as &&case] [lambda :as &&lambda] [module :as &&module] - [io :as &&io]) + [io :as &&io] + [parallel :as &¶llel]) [lux.packager.program :as &packager-program]) (:import (org.objectweb.asm Opcodes Label @@ -118,6 +119,7 @@ )) (defn init! [] + (&¶llel/setup!) (reset! !source->last-line {}) (.mkdirs (java.io.File. &&/output-dir)) (doto (.getDeclaredMethod java.net.URLClassLoader "addURL" (into-array [java.net.URL])) @@ -170,7 +172,10 @@ :let [file-hash (hash file-content)]] (if (&&cache/cached? name) (&&cache/load source-dirs name file-hash compile-module) - (let [compiler-step (&analyser/analyse &optimizer/optimize eval! (partial compile-module source-dirs) all-compilers)] + (let [compiler-step (&analyser/analyse &optimizer/optimize + eval! + (&¶llel/parallel-compilation (partial compile-module source-dirs)) + all-compilers)] (|do [module-exists? (&a-module/exists? name)] (if module-exists? (fail "[Compiler Error] Can't redefine a module!") @@ -253,7 +258,8 @@ (defn compile-program [mode program-module source-dirs] (init!) - (let [m-action (&/map% (partial compile-module source-dirs) (&/|list "lux" program-module))] + (let [m-action (&/map% (&¶llel/parallel-compilation (partial compile-module source-dirs)) + (&/|list "lux" program-module))] (|case (m-action (&/init-state mode)) (&/$Right ?state _) (do (println "Compilation complete!") diff --git a/src/lux/compiler/parallel.clj b/src/lux/compiler/parallel.clj new file mode 100644 index 000000000..92ff0a79e --- /dev/null +++ b/src/lux/compiler/parallel.clj @@ -0,0 +1,60 @@ +;; Copyright (c) Eduardo Julian. All rights reserved. +;; This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. +;; If a copy of the MPL was not distributed with this file, +;; You can obtain one at http://mozilla.org/MPL/2.0/. + +(ns lux.compiler.parallel + (:require (clojure [string :as string] + [set :as set] + [template :refer [do-template]]) + clojure.core.async + clojure.core.match + clojure.core.match.array + (lux [base :as & :refer [|let |do return* return fail fail* |case]]))) + +;; [Utils] +(def ^:private !state! (atom {})) + +(def ^:private get-compiler + (fn [compiler] + (return* compiler compiler))) + +(defn ^:private set-compiler [compiler*] + (fn [_] + (return* compiler* compiler*))) + +(defn ^:private merge-modules + "(-> Compiler Compiler)" + [new old] + (->> old + (&/set$ &/$source (&/get$ &/$source new)) + (&/set$ &/$modules (&/get$ &/$modules new)) + (&/set$ &/$seed (&/get$ &/$seed new)) + (&/set$ &/$host (&/get$ &/$host new)))) + +;; [Exports] +(defn setup! + "Must always call this function before using parallel compilation to make sure that the state that is being tracked is in proper shape." + [] + (reset! !state! {})) + +(defn parallel-compilation [compile-module*] + (fn [module-name] + (|do [:let [_ (prn 'parallel-compilation module-name)] + pre get-compiler + output (compile-module* module-name) + post get-compiler + post* (set-compiler (merge-modules post pre)) + ;; TODO: Some type-vars in the typing environment stay in + ;; the environment forever, making type-checking slower. + ;; The merging process for modules more-or-less "fixes" the + ;; problem by resetting the typing enviroment, but ideally + ;; those type-vars shouldn't survive in the first place. + ;; MUST FIX + ;; :let [_ (prn 'parallel-compilation module-name + ;; 'PRE (->> pre (&/get$ &/$type-vars) (&/get$ &/$mappings) &/|length) + ;; 'POST (->> post (&/get$ &/$type-vars) (&/get$ &/$mappings) &/|length) + ;; 'POST* (->> post* (&/get$ &/$type-vars) (&/get$ &/$mappings) &/|length))] + ] + (return output) + ))) diff --git a/src/lux/packager/program.clj b/src/lux/packager/program.clj index 54cc8a813..27484c300 100644 --- a/src/lux/packager/program.clj +++ b/src/lux/packager/program.clj @@ -85,7 +85,8 @@ (filter #(.endsWith ^String % ".jar")) (filter #(not (or (.contains ^String % "org/ow2/asm/asm-all") (.contains ^String % "org/clojure/core.match") - (.contains ^String % "org/clojure/clojure")))))) + (.contains ^String % "org/clojure/clojure") + (.contains ^String % "org/clojure/core.async")))))) (let [init-capacity (* 100 1024) buffer-size 1024] @@ -132,7 +133,8 @@ (not (.endsWith ^String % "tools.nrepl-0.2.3.jar")) (not (.endsWith ^String % "clojure-complete-0.2.3.jar")) (not (.endsWith ^String % "clojure-1.6.0.jar")) - (not (.endsWith ^String % "core.match-0.2.1.jar")))) + (not (.endsWith ^String % "core.match-0.2.1.jar")) + (not (.endsWith ^String % "core.async-0.2.391.jar")))) (reduce (fn [s ^String j] (add-jar! (new File ^String j) s out)) #{"META-INF/MANIFEST.MF"})) nil) -- cgit v1.2.3 From ee646a676e3fa240e696178bcebe852c454e1b16 Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Tue, 11 Oct 2016 08:11:49 -0400 Subject: - Finished a working implementation of parallel compilation, that doesn't rely on core.async. --- project.clj | 3 +- src/lux/analyser/host.clj | 4 +- src/lux/analyser/lux.clj | 143 +++++++++++++++++++++++++++++++++++------- src/lux/analyser/module.clj | 64 ++++++++++++++++--- src/lux/base.clj | 7 +++ src/lux/compiler.clj | 20 +++--- src/lux/compiler/lux.clj | 4 +- src/lux/compiler/parallel.clj | 62 +++++++++++------- src/lux/packager/program.clj | 5 +- 9 files changed, 241 insertions(+), 71 deletions(-) diff --git a/project.clj b/project.clj index 5ea065037..726b3b120 100644 --- a/project.clj +++ b/project.clj @@ -13,8 +13,7 @@ [:url "https://github.com/eduardoejp"]]] :dependencies [[org.clojure/clojure "1.6.0"] [org.clojure/core.match "0.2.1"] - [org.ow2.asm/asm-all "5.0.3"] - [org.clojure/core.async "0.2.391"]] + [org.ow2.asm/asm-all "5.0.3"]] :warn-on-reflection true :main lux :repositories [["snapshots" "https://oss.sonatype.org/content/repositories/snapshots/"] diff --git a/src/lux/analyser/host.clj b/src/lux/analyser/host.clj index b84b31dff..ff998c2d5 100644 --- a/src/lux/analyser/host.clj +++ b/src/lux/analyser/host.clj @@ -935,7 +935,7 @@ (defn ^:private analyse-jvm-interface [analyse compile-interface interface-decl supers =anns =methods] (|do [module &/get-module-name _ (compile-interface interface-decl supers =anns =methods) - :let [_ (println 'INTERFACE (str module "." (&/|first interface-decl)))] + :let [_ (&/|log! 'INTERFACE (str module "." (&/|first interface-decl)))] _cursor &/cursor] (return (&/|list (&&/|meta &/$UnitT _cursor (&&/$tuple (&/|list))))))) @@ -954,7 +954,7 @@ _ (check-method-completion all-supers =methods) _ (compile-class class-decl super-class interfaces =inheritance-modifier =anns =fields =methods &/$Nil &/$None) _ &/pop-dummy-name - :let [_ (println 'CLASS full-name)] + :let [_ (&/|log! 'CLASS full-name)] _cursor &/cursor] (return (&/|list (&&/|meta &/$UnitT _cursor (&&/$tuple (&/|list)))))))) diff --git a/src/lux/analyser/lux.clj b/src/lux/analyser/lux.clj index 208890d78..b755a6b0b 100644 --- a/src/lux/analyser/lux.clj +++ b/src/lux/analyser/lux.clj @@ -4,7 +4,8 @@ ;; You can obtain one at http://mozilla.org/MPL/2.0/. (ns lux.analyser.lux - (:require (clojure [template :refer [do-template]]) + (:require (clojure [template :refer [do-template]] + [set :as set]) clojure.core.match clojure.core.match.array (lux [base :as & :refer [|do return return* fail fail* |let |list |case]] @@ -575,6 +576,78 @@ (return &/$Nil)) ))) +(defn ^:private merge-hosts + "(-> Host Host Host)" + [new old] + (|let [merged-module-states (&/fold (fn [total m-state] + (|let [[_name _state] m-state] + (|case _state + (&/$Cached) + (&/|put _name _state total) + + (&/$Compiled) + (&/|put _name _state total) + + _ + total))) + (&/get$ &/$module-states old) + (&/get$ &/$module-states new))] + (->> old + (&/set$ &/$module-states merged-module-states)))) + +(defn ^:private merge-modules + "(-> Text Module Module Module)" + [current-module new old] + (do ;; (&/|log! 'old (->> old (&/|map &/|first) &/->seq set) + ;; "\n" + ;; 'new (->> new (&/|map &/|first) &/->seq set) + ;; "\n" + ;; 'old+new (set/union (->> old (&/|map &/|first) &/->seq set) + ;; (->> new (&/|map &/|first) &/->seq set))) + (&/fold (fn [total* entry] + (|let [[_name _module] entry] + (if (or (= current-module _name) + (->> _module + (&/get$ &&module/$defs) + &/|length + (= 0))) + ;; Don't modify the entry of the current module, to + ;; avoid overwritting it's data in improper ways. + ;; Since it's assumed the "original" old module + ;; contains all the proper own-module information. + total* + (do ;; (&/|log! "Adding:" _name "to" current-module + ;; (->> _module + ;; (&/get$ &&module/$defs) + ;; &/|length) + ;; (->> _module + ;; (&/get$ &&module/$defs) + ;; (&/|filter (comp &&module/exported? &/|second)) + ;; (&/|map &/|first) + ;; &/->seq pr-str)) + (&/|put _name _module total*))))) + old new))) + +(defn ^:private merge-compilers + "(-> Text Compiler Compiler Compiler)" + [current-module new old] + (->> old + (&/set$ &/$modules (merge-modules current-module + (&/get$ &/$modules new) + (&/get$ &/$modules old))) + (&/set$ &/$seed (max (&/get$ &/$seed new) + (&/get$ &/$seed old))) + (&/set$ &/$host (merge-hosts (&/get$ &/$host new) + (&/get$ &/$host old))))) + +(def ^:private get-compiler + (fn [compiler] + (return* compiler compiler))) + +(defn ^:private set-compiler [compiler*] + (fn [_] + (return* compiler* compiler*))) + (defn analyse-module [analyse optimize eval! compile-module ?meta] (|do [_ &/ensure-statement =anns (&&/analyse-1 analyse &type/Anns ?meta) @@ -582,27 +655,53 @@ module-name &/get-module-name _ (&&module/set-anns ==anns module-name) _imports (&&module/fetch-imports ==anns) - current-module &/get-module-name] - (&/map% (fn [_import] - (|let [[path alias] _import] - (&/without-repl - (&/save-module - (|do [_ (if (= current-module path) - (&/fail-with-loc (str "[Analyser Error] Module can't import itself: " path)) - (return nil)) - already-compiled? (&&module/exists? path) - active? (&/active-module? path) - _ (&/assert! (not active?) - (str "[Analyser Error] Can't import a module that is mid-compilation: " path " @ " current-module)) - _ (&&module/add-import path) - ?module-hash (if (not already-compiled?) - (compile-module path) - (&&module/module-hash path)) - _ (if (= "" alias) - (return nil) - (&&module/alias current-module alias path))] - (return &/$Nil)))))) - _imports))) + current-module &/get-module-name + ;; :let [_ (&/|log! 'analyse-module module-name (->> _imports (&/|map &/|first) &/->seq))] + =asyncs (&/map% (fn [_import] + (|let [[path alias] _import] + (&/without-repl + (&/save-module + (|do [_ (if (= current-module path) + (&/fail-with-loc (str "[Analyser Error] Module can't import itself: " path)) + (return nil)) + already-compiled? (&&module/exists? path) + active? (&/active-module? path) + _ (&/assert! (not active?) + (str "[Analyser Error] Can't import a module that is mid-compilation: " path " @ " current-module)) + _ (&&module/add-import path) + ?async (if (not already-compiled?) + (compile-module path) + (|do [_module (&&module/find-module path) + ;; :let [_ (&/|log! "Already compiled:" path (->> _module + ;; (&/get$ &&module/$defs) + ;; &/|length))] + _compiler get-compiler] + (return (doto (promise) + (deliver _compiler))))) + _ (if (= "" alias) + (return nil) + (&&module/alias current-module alias path))] + (return ?async)))))) + _imports) + _compiler get-compiler + :let [_compiler* (&/fold2 (fn [compiler _import _async] + (|let [[path alias] _import + ;; _ (&/|log! 'import-compiler 'PRE [module-name path]) + import-compiler @_async + ;; _ (&/|log! 'import-compiler 'POST [module-name path] import-compiler) + ] + (merge-compilers current-module import-compiler compiler))) + _compiler + _imports + =asyncs)] + _ (set-compiler _compiler*) + ;; _ (->> _imports + ;; (&/|map &/|first) + ;; (&/|filter (partial not= "lux")) + ;; (&/map% &&module/add-import)) + ;; :let [_ (&/|log! "CONTINUE" module-name (->> _imports (&/|map &/|first) &/->seq))] + ] + (return &/$Nil))) (defn ^:private coerce [new-type analysis] "(-> Type Analysis Analysis)" diff --git a/src/lux/analyser/module.clj b/src/lux/analyser/module.clj index 6af4adff6..d60298b4a 100644 --- a/src/lux/analyser/module.clj +++ b/src/lux/analyser/module.clj @@ -141,9 +141,21 @@ (defn dealias [name] (|do [current-module &/get-module-name] (fn [state] - (if-let [real-name (->> state (&/get$ &/$modules) (&/|get current-module) (&/get$ $module-aliases) (&/|get name))] + (if-let [real-name (->> state + (&/get$ &/$modules) + (&/|get current-module) + (&/get$ $module-aliases) + (&/|get name))] (return* state real-name) - ((&/fail-with-loc (str "[Analyser Error] Unknown alias: " name)) + ((&/fail-with-loc (str "[Analyser Error] Unknown alias: " name + "\n" + "@@@ " (->> state + (&/get$ &/$modules) + (&/|get current-module) + (&/get$ $module-aliases) + (&/|map &/|first) + &/->seq + pr-str))) state))))) (defn alias [module alias reference] @@ -167,12 +179,12 @@ nil)))) )) -(defn ^:private imports? [state imported-module source-module] +(defn ^:private imports? [state imported-module-name source-module-name] (->> state (&/get$ &/$modules) - (&/|get source-module) + (&/|get source-module-name) (&/get$ $imports) - (&/|any? (partial = imported-module)))) + (&/|any? (partial = imported-module-name)))) (defn get-anns [module-name] (fn [state] @@ -193,6 +205,17 @@ ms)))) nil))) +(defn exported? + "(-> Def Bool)" + [?def] + (|let [[?type ?ann ?value] ?def] + (|case (&meta/meta-get &meta/export?-tag ?ann) + (&/$Some (&/$BoolM true)) + true + + _ + false))) + (defn find-def [module name] (|do [current-module &/get-module-name] (fn [state] @@ -215,13 +238,27 @@ (return* state (&/T [(&/T [module name]) $def])) _ - ((&/fail-with-loc (str "[Analyser Error] Can't use unexported definition: " (str module &/+name-separator+ name))) + ((&/fail-with-loc (str "[Analyser Error @ find-def] Can't use unexported definition: " (str module &/+name-separator+ name))) state)))) - ((&/fail-with-loc (str "[Analyser Error] Definition does not exist: " (str module &/+name-separator+ name))) + ((&/fail-with-loc (str "[Analyser Error @ find-def] Definition does not exist: " (str module &/+name-separator+ name) + "\n @@@" + (->> $module (&/get$ $defs) (&/|map &/|first) &/->seq pr-str))) state)) - ((&/fail-with-loc (str "[Analyser Error] Module doesn't exist: " module)) + ((&/fail-with-loc (str "[Analyser Error @ find-def] Module doesn't exist: " module)) state)) - ((&/fail-with-loc (str "[Analyser Error] Unknown module: " module)) + ((&/fail-with-loc (str "[Analyser Error @ find-def] Unknown module: " module + "\n" + "@@@ " current-module " :: " + (->> state + (&/get$ &/$modules) + (&/|get current-module) + (&/get$ $imports) + &/->seq) + " " + (->> state + (&/get$ &/$modules) + (&/|map &/|first) + &/->seq))) state)) ))) @@ -400,3 +437,12 @@ _ (&/fail-with-loc "[Analyser Error] No import meta-data."))) + +(defn find-module + "(-> Text (Lux Module))" + [module-name] + (fn [state] + (if-let [module (->> state (&/get$ &/$modules) (&/|get module-name))] + (return* state module) + ((&/fail-with-loc (str "[Analyser Error] Unknown module: " module-name)) + state)))) diff --git a/src/lux/base.clj b/src/lux/base.clj index 88d50002b..68406ed1b 100644 --- a/src/lux/base.clj +++ b/src/lux/base.clj @@ -2,6 +2,7 @@ ;; This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. ;; If a copy of the MPL was not distributed with this file, ;; You can obtain one at http://mozilla.org/MPL/2.0/. + (ns lux.base (:require (clojure [template :refer [do-template]] [string :as string]) @@ -1444,3 +1445,9 @@ _ class-name)])))) + +(let [!out! *out*] + (defn |log! [& parts] + (binding [*out* !out!] + (do (print (apply println-str parts)) + (flush))))) diff --git a/src/lux/compiler.clj b/src/lux/compiler.clj index 5dd2e3684..8b9e8bbed 100644 --- a/src/lux/compiler.clj +++ b/src/lux/compiler.clj @@ -257,14 +257,14 @@ ))) (defn compile-program [mode program-module source-dirs] - (init!) - (let [m-action (&/map% (&¶llel/parallel-compilation (partial compile-module source-dirs)) - (&/|list "lux" program-module))] - (|case (m-action (&/init-state mode)) - (&/$Right ?state _) - (do (println "Compilation complete!") - (&&cache/clean ?state) - (&packager-program/package program-module)) + (do (init!) + (let [m-action (|do [_ (compile-module source-dirs "lux")] + (compile-module source-dirs program-module))] + (|case (m-action (&/init-state mode)) + (&/$Right ?state _) + (do (println "Compilation complete!") + (&&cache/clean ?state) + (&packager-program/package program-module)) - (&/$Left ?message) - (assert false ?message)))) + (&/$Left ?message) + (assert false ?message))))) diff --git a/src/lux/compiler/lux.clj b/src/lux/compiler/lux.clj index 976bdfa15..551572a87 100644 --- a/src/lux/compiler/lux.clj +++ b/src/lux/compiler/lux.clj @@ -346,7 +346,7 @@ [_ (&/$None)] (return nil)) - :let [_ (println 'DEF (str module-name ";" ?name))]] + :let [_ (&/|log! 'DEF (str module-name ";" ?name))]] (return nil))) _ @@ -428,7 +428,7 @@ [_ (&/$None)] (return nil)) - :let [_ (println 'DEF (str module-name ";" ?name))]] + :let [_ (&/|log! 'DEF (str module-name ";" ?name))]] (return nil))) )))) diff --git a/src/lux/compiler/parallel.clj b/src/lux/compiler/parallel.clj index 92ff0a79e..42598ef7e 100644 --- a/src/lux/compiler/parallel.clj +++ b/src/lux/compiler/parallel.clj @@ -7,44 +7,64 @@ (:require (clojure [string :as string] [set :as set] [template :refer [do-template]]) - clojure.core.async clojure.core.match clojure.core.match.array - (lux [base :as & :refer [|let |do return* return fail fail* |case]]))) + (lux [base :as & :refer [|let |do return* return fail fail* |case]]) + (lux.analyser [base :as &a] + [module :as &a-module]))) ;; [Utils] -(def ^:private !state! (atom {})) +(def ^:private !state! (ref {})) (def ^:private get-compiler (fn [compiler] (return* compiler compiler))) -(defn ^:private set-compiler [compiler*] - (fn [_] - (return* compiler* compiler*))) +(defn ^:private compilation-task [compile-module* module-name] + (|do [current-module &/get-module-name + compiler get-compiler + :let [[task new?] (dosync (if-let [existing-task (get @!state! module-name)] + (&/T [existing-task false]) + (let [new-task (promise)] + (do (alter !state! assoc module-name new-task) + (&/T [new-task true]))))) + result (when new? + (doto (new Thread + (fn [] + (do ;; (&/|log! 'THREAD-START [current-module module-name]) + (|case (&/run-state (|do [_ (compile-module* module-name) + _module (&a-module/find-module module-name) + ;; :let [_ (&/|log! "Just compiled:" module-name (->> _module + ;; (&/get$ &a-module/$defs) + ;; &/|length))] + ] + (return nil)) + compiler) + (&/$Right post-compiler _) + (do ;; (&/|log! 'FINISHED 'compilation-task [current-module module-name] post-compiler) + (deliver task post-compiler)) -(defn ^:private merge-modules - "(-> Compiler Compiler)" - [new old] - (->> old - (&/set$ &/$source (&/get$ &/$source new)) - (&/set$ &/$modules (&/get$ &/$modules new)) - (&/set$ &/$seed (&/get$ &/$seed new)) - (&/set$ &/$host (&/get$ &/$host new)))) + (&/$Left ?error) + (do (&/|log! ?error) + ;; (System/exit 1) + ))))) + (.start))) + ;; _ (&/|log! 'parallel-compilation [current-module module-name] new? result) + ]] + (return task))) ;; [Exports] (defn setup! "Must always call this function before using parallel compilation to make sure that the state that is being tracked is in proper shape." [] - (reset! !state! {})) + (dosync (ref-set !state! {}))) (defn parallel-compilation [compile-module*] (fn [module-name] - (|do [:let [_ (prn 'parallel-compilation module-name)] - pre get-compiler - output (compile-module* module-name) - post get-compiler - post* (set-compiler (merge-modules post pre)) + (|do [;; pre get-compiler + ?async (compilation-task compile-module* module-name) + ;; post get-compiler + ;; post* (set-compiler (merge-compilers post pre)) ;; TODO: Some type-vars in the typing environment stay in ;; the environment forever, making type-checking slower. ;; The merging process for modules more-or-less "fixes" the @@ -56,5 +76,5 @@ ;; 'POST (->> post (&/get$ &/$type-vars) (&/get$ &/$mappings) &/|length) ;; 'POST* (->> post* (&/get$ &/$type-vars) (&/get$ &/$mappings) &/|length))] ] - (return output) + (return ?async) ))) diff --git a/src/lux/packager/program.clj b/src/lux/packager/program.clj index 27484c300..2afda2674 100644 --- a/src/lux/packager/program.clj +++ b/src/lux/packager/program.clj @@ -86,7 +86,7 @@ (filter #(not (or (.contains ^String % "org/ow2/asm/asm-all") (.contains ^String % "org/clojure/core.match") (.contains ^String % "org/clojure/clojure") - (.contains ^String % "org/clojure/core.async")))))) + ))))) (let [init-capacity (* 100 1024) buffer-size 1024] @@ -133,8 +133,7 @@ (not (.endsWith ^String % "tools.nrepl-0.2.3.jar")) (not (.endsWith ^String % "clojure-complete-0.2.3.jar")) (not (.endsWith ^String % "clojure-1.6.0.jar")) - (not (.endsWith ^String % "core.match-0.2.1.jar")) - (not (.endsWith ^String % "core.async-0.2.391.jar")))) + (not (.endsWith ^String % "core.match-0.2.1.jar")))) (reduce (fn [s ^String j] (add-jar! (new File ^String j) s out)) #{"META-INF/MANIFEST.MF"})) nil) -- cgit v1.2.3 From b103dafd2c60b91a9c02bbfcee6c2fcb30e40582 Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Tue, 11 Oct 2016 15:50:24 -0400 Subject: - Refactored the code. --- src/lux/analyser/lux.clj | 77 +++++++++++++++---------------------------- src/lux/analyser/module.clj | 54 +++--------------------------- src/lux/base.clj | 2 +- src/lux/compiler/parallel.clj | 56 +++++++------------------------ 4 files changed, 43 insertions(+), 146 deletions(-) diff --git a/src/lux/analyser/lux.clj b/src/lux/analyser/lux.clj index b755a6b0b..69b389e70 100644 --- a/src/lux/analyser/lux.clj +++ b/src/lux/analyser/lux.clj @@ -33,7 +33,7 @@ 0)) ;; TODO: This technique won't work if the body of the type contains -;; nested quantifications that are cannot be directly counted. +;; nested quantifications that cannot be directly counted. (defn ^:private next-bound-type [type] "(-> Type Type)" (&/$BoundT (->> (count-univq type) (* 2) (+ 1)))) @@ -522,8 +522,6 @@ (return (&&/|meta exo-type* _cursor (&&/$lambda =scope =captured =body)))) - - _ (fail ""))) (fn [err] @@ -598,35 +596,20 @@ (defn ^:private merge-modules "(-> Text Module Module Module)" [current-module new old] - (do ;; (&/|log! 'old (->> old (&/|map &/|first) &/->seq set) - ;; "\n" - ;; 'new (->> new (&/|map &/|first) &/->seq set) - ;; "\n" - ;; 'old+new (set/union (->> old (&/|map &/|first) &/->seq set) - ;; (->> new (&/|map &/|first) &/->seq set))) - (&/fold (fn [total* entry] - (|let [[_name _module] entry] - (if (or (= current-module _name) - (->> _module - (&/get$ &&module/$defs) - &/|length - (= 0))) - ;; Don't modify the entry of the current module, to - ;; avoid overwritting it's data in improper ways. - ;; Since it's assumed the "original" old module - ;; contains all the proper own-module information. - total* - (do ;; (&/|log! "Adding:" _name "to" current-module - ;; (->> _module - ;; (&/get$ &&module/$defs) - ;; &/|length) - ;; (->> _module - ;; (&/get$ &&module/$defs) - ;; (&/|filter (comp &&module/exported? &/|second)) - ;; (&/|map &/|first) - ;; &/->seq pr-str)) - (&/|put _name _module total*))))) - old new))) + (&/fold (fn [total* entry] + (|let [[_name _module] entry] + (if (or (= current-module _name) + (->> _module + (&/get$ &&module/$defs) + &/|length + (= 0))) + ;; Don't modify the entry of the current module, to + ;; avoid overwritting it's data in improper ways. + ;; Since it's assumed the "original" old module + ;; contains all the proper own-module information. + total* + (&/|put _name _module total*)))) + old new)) (defn ^:private merge-compilers "(-> Text Compiler Compiler Compiler)" @@ -656,7 +639,6 @@ _ (&&module/set-anns ==anns module-name) _imports (&&module/fetch-imports ==anns) current-module &/get-module-name - ;; :let [_ (&/|log! 'analyse-module module-name (->> _imports (&/|map &/|first) &/->seq))] =asyncs (&/map% (fn [_import] (|let [[path alias] _import] (&/without-repl @@ -671,10 +653,7 @@ _ (&&module/add-import path) ?async (if (not already-compiled?) (compile-module path) - (|do [_module (&&module/find-module path) - ;; :let [_ (&/|log! "Already compiled:" path (->> _module - ;; (&/get$ &&module/$defs) - ;; &/|length))] + (|do [_module (&/find-module path) _compiler get-compiler] (return (doto (promise) (deliver _compiler))))) @@ -684,23 +663,19 @@ (return ?async)))))) _imports) _compiler get-compiler - :let [_compiler* (&/fold2 (fn [compiler _import _async] - (|let [[path alias] _import - ;; _ (&/|log! 'import-compiler 'PRE [module-name path]) - import-compiler @_async - ;; _ (&/|log! 'import-compiler 'POST [module-name path] import-compiler) - ] - (merge-compilers current-module import-compiler compiler))) + :let [;; Some type-vars in the typing environment stay in + ;; the environment forever, making type-checking slower. + ;; The merging process for compilers more-or-less "fixes" the + ;; problem by resetting the typing enviroment, but ideally + ;; those type-vars shouldn't survive in the first place. + ;; TODO: MUST FIX + _compiler* (&/fold2 (fn [compiler _import _async] + (|let [[path alias] _import] + (merge-compilers current-module @_async compiler))) _compiler _imports =asyncs)] - _ (set-compiler _compiler*) - ;; _ (->> _imports - ;; (&/|map &/|first) - ;; (&/|filter (partial not= "lux")) - ;; (&/map% &&module/add-import)) - ;; :let [_ (&/|log! "CONTINUE" module-name (->> _imports (&/|map &/|first) &/->seq))] - ] + _ (set-compiler _compiler*)] (return &/$Nil))) (defn ^:private coerce [new-type analysis] diff --git a/src/lux/analyser/module.clj b/src/lux/analyser/module.clj index d60298b4a..21aa324e8 100644 --- a/src/lux/analyser/module.clj +++ b/src/lux/analyser/module.clj @@ -141,21 +141,9 @@ (defn dealias [name] (|do [current-module &/get-module-name] (fn [state] - (if-let [real-name (->> state - (&/get$ &/$modules) - (&/|get current-module) - (&/get$ $module-aliases) - (&/|get name))] + (if-let [real-name (->> state (&/get$ &/$modules) (&/|get current-module) (&/get$ $module-aliases) (&/|get name))] (return* state real-name) - ((&/fail-with-loc (str "[Analyser Error] Unknown alias: " name - "\n" - "@@@ " (->> state - (&/get$ &/$modules) - (&/|get current-module) - (&/get$ $module-aliases) - (&/|map &/|first) - &/->seq - pr-str))) + ((&/fail-with-loc (str "[Analyser Error] Unknown alias: " name)) state))))) (defn alias [module alias reference] @@ -205,17 +193,6 @@ ms)))) nil))) -(defn exported? - "(-> Def Bool)" - [?def] - (|let [[?type ?ann ?value] ?def] - (|case (&meta/meta-get &meta/export?-tag ?ann) - (&/$Some (&/$BoolM true)) - true - - _ - false))) - (defn find-def [module name] (|do [current-module &/get-module-name] (fn [state] @@ -240,25 +217,11 @@ _ ((&/fail-with-loc (str "[Analyser Error @ find-def] Can't use unexported definition: " (str module &/+name-separator+ name))) state)))) - ((&/fail-with-loc (str "[Analyser Error @ find-def] Definition does not exist: " (str module &/+name-separator+ name) - "\n @@@" - (->> $module (&/get$ $defs) (&/|map &/|first) &/->seq pr-str))) + ((&/fail-with-loc (str "[Analyser Error @ find-def] Definition does not exist: " (str module &/+name-separator+ name))) state)) ((&/fail-with-loc (str "[Analyser Error @ find-def] Module doesn't exist: " module)) state)) - ((&/fail-with-loc (str "[Analyser Error @ find-def] Unknown module: " module - "\n" - "@@@ " current-module " :: " - (->> state - (&/get$ &/$modules) - (&/|get current-module) - (&/get$ $imports) - &/->seq) - " " - (->> state - (&/get$ &/$modules) - (&/|map &/|first) - &/->seq))) + ((&/fail-with-loc (str "[Analyser Error @ find-def] Unknown module: " module)) state)) ))) @@ -437,12 +400,3 @@ _ (&/fail-with-loc "[Analyser Error] No import meta-data."))) - -(defn find-module - "(-> Text (Lux Module))" - [module-name] - (fn [state] - (if-let [module (->> state (&/get$ &/$modules) (&/|get module-name))] - (return* state module) - ((&/fail-with-loc (str "[Analyser Error] Unknown module: " module-name)) - state)))) diff --git a/src/lux/base.clj b/src/lux/base.clj index 68406ed1b..b59141b34 100644 --- a/src/lux/base.clj +++ b/src/lux/base.clj @@ -902,7 +902,7 @@ (fn [state] (if-let [module (|get name (get$ $modules state))] (return* state module) - ((fail-with-loc (str "Unknown module: " name)) state)))) + ((fail-with-loc (str "[Error] Unknown module: " name)) state)))) (def get-current-module "(Lux (Module Compiler))" diff --git a/src/lux/compiler/parallel.clj b/src/lux/compiler/parallel.clj index 42598ef7e..453033287 100644 --- a/src/lux/compiler/parallel.clj +++ b/src/lux/compiler/parallel.clj @@ -9,9 +9,7 @@ [template :refer [do-template]]) clojure.core.match clojure.core.match.array - (lux [base :as & :refer [|let |do return* return fail fail* |case]]) - (lux.analyser [base :as &a] - [module :as &a-module]))) + (lux [base :as & :refer [|let |do return* return fail fail* |case]]))) ;; [Utils] (def ^:private !state! (ref {})) @@ -21,36 +19,22 @@ (return* compiler compiler))) (defn ^:private compilation-task [compile-module* module-name] - (|do [current-module &/get-module-name - compiler get-compiler + (|do [compiler get-compiler :let [[task new?] (dosync (if-let [existing-task (get @!state! module-name)] (&/T [existing-task false]) (let [new-task (promise)] (do (alter !state! assoc module-name new-task) (&/T [new-task true]))))) - result (when new? - (doto (new Thread - (fn [] - (do ;; (&/|log! 'THREAD-START [current-module module-name]) - (|case (&/run-state (|do [_ (compile-module* module-name) - _module (&a-module/find-module module-name) - ;; :let [_ (&/|log! "Just compiled:" module-name (->> _module - ;; (&/get$ &a-module/$defs) - ;; &/|length))] - ] - (return nil)) - compiler) - (&/$Right post-compiler _) - (do ;; (&/|log! 'FINISHED 'compilation-task [current-module module-name] post-compiler) - (deliver task post-compiler)) + _ (when new? + (.start (new Thread + (fn [] + (|case (&/run-state (compile-module* module-name) + compiler) + (&/$Right post-compiler _) + (deliver task post-compiler) - (&/$Left ?error) - (do (&/|log! ?error) - ;; (System/exit 1) - ))))) - (.start))) - ;; _ (&/|log! 'parallel-compilation [current-module module-name] new? result) - ]] + (&/$Left ?error) + (&/|log! ?error))))))]] (return task))) ;; [Exports] @@ -61,20 +45,4 @@ (defn parallel-compilation [compile-module*] (fn [module-name] - (|do [;; pre get-compiler - ?async (compilation-task compile-module* module-name) - ;; post get-compiler - ;; post* (set-compiler (merge-compilers post pre)) - ;; TODO: Some type-vars in the typing environment stay in - ;; the environment forever, making type-checking slower. - ;; The merging process for modules more-or-less "fixes" the - ;; problem by resetting the typing enviroment, but ideally - ;; those type-vars shouldn't survive in the first place. - ;; MUST FIX - ;; :let [_ (prn 'parallel-compilation module-name - ;; 'PRE (->> pre (&/get$ &/$type-vars) (&/get$ &/$mappings) &/|length) - ;; 'POST (->> post (&/get$ &/$type-vars) (&/get$ &/$mappings) &/|length) - ;; 'POST* (->> post* (&/get$ &/$type-vars) (&/get$ &/$mappings) &/|length))] - ] - (return ?async) - ))) + (compilation-task compile-module* module-name))) -- cgit v1.2.3 From 3614dd21db8ddfb8cf1c0e842d035709d8bee8e8 Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Tue, 11 Oct 2016 16:15:06 -0400 Subject: - Better log printing. --- src/lux/analyser/host.clj | 4 ++-- src/lux/base.clj | 2 +- src/lux/compiler/lux.clj | 4 ++-- src/lux/compiler/parallel.clj | 39 +++++++++++++++++++-------------------- 4 files changed, 24 insertions(+), 25 deletions(-) diff --git a/src/lux/analyser/host.clj b/src/lux/analyser/host.clj index ff998c2d5..b84b31dff 100644 --- a/src/lux/analyser/host.clj +++ b/src/lux/analyser/host.clj @@ -935,7 +935,7 @@ (defn ^:private analyse-jvm-interface [analyse compile-interface interface-decl supers =anns =methods] (|do [module &/get-module-name _ (compile-interface interface-decl supers =anns =methods) - :let [_ (&/|log! 'INTERFACE (str module "." (&/|first interface-decl)))] + :let [_ (println 'INTERFACE (str module "." (&/|first interface-decl)))] _cursor &/cursor] (return (&/|list (&&/|meta &/$UnitT _cursor (&&/$tuple (&/|list))))))) @@ -954,7 +954,7 @@ _ (check-method-completion all-supers =methods) _ (compile-class class-decl super-class interfaces =inheritance-modifier =anns =fields =methods &/$Nil &/$None) _ &/pop-dummy-name - :let [_ (&/|log! 'CLASS full-name)] + :let [_ (println 'CLASS full-name)] _cursor &/cursor] (return (&/|list (&&/|meta &/$UnitT _cursor (&&/$tuple (&/|list)))))))) diff --git a/src/lux/base.clj b/src/lux/base.clj index b59141b34..54a0354c6 100644 --- a/src/lux/base.clj +++ b/src/lux/base.clj @@ -1449,5 +1449,5 @@ (let [!out! *out*] (defn |log! [& parts] (binding [*out* !out!] - (do (print (apply println-str parts)) + (do (print (apply str parts)) (flush))))) diff --git a/src/lux/compiler/lux.clj b/src/lux/compiler/lux.clj index 551572a87..976bdfa15 100644 --- a/src/lux/compiler/lux.clj +++ b/src/lux/compiler/lux.clj @@ -346,7 +346,7 @@ [_ (&/$None)] (return nil)) - :let [_ (&/|log! 'DEF (str module-name ";" ?name))]] + :let [_ (println 'DEF (str module-name ";" ?name))]] (return nil))) _ @@ -428,7 +428,7 @@ [_ (&/$None)] (return nil)) - :let [_ (&/|log! 'DEF (str module-name ";" ?name))]] + :let [_ (println 'DEF (str module-name ";" ?name))]] (return nil))) )))) diff --git a/src/lux/compiler/parallel.clj b/src/lux/compiler/parallel.clj index 453033287..3506eb82e 100644 --- a/src/lux/compiler/parallel.clj +++ b/src/lux/compiler/parallel.clj @@ -18,25 +18,6 @@ (fn [compiler] (return* compiler compiler))) -(defn ^:private compilation-task [compile-module* module-name] - (|do [compiler get-compiler - :let [[task new?] (dosync (if-let [existing-task (get @!state! module-name)] - (&/T [existing-task false]) - (let [new-task (promise)] - (do (alter !state! assoc module-name new-task) - (&/T [new-task true]))))) - _ (when new? - (.start (new Thread - (fn [] - (|case (&/run-state (compile-module* module-name) - compiler) - (&/$Right post-compiler _) - (deliver task post-compiler) - - (&/$Left ?error) - (&/|log! ?error))))))]] - (return task))) - ;; [Exports] (defn setup! "Must always call this function before using parallel compilation to make sure that the state that is being tracked is in proper shape." @@ -45,4 +26,22 @@ (defn parallel-compilation [compile-module*] (fn [module-name] - (compilation-task compile-module* module-name))) + (|do [compiler get-compiler + :let [[task new?] (dosync (if-let [existing-task (get @!state! module-name)] + (&/T [existing-task false]) + (let [new-task (promise)] + (do (alter !state! assoc module-name new-task) + (&/T [new-task true]))))) + _ (when new? + (.start (new Thread + (fn [] + (let [out-str (with-out-str + (|case (&/run-state (compile-module* module-name) + compiler) + (&/$Right post-compiler _) + (deliver task post-compiler) + + (&/$Left ?error) + (println ?error)))] + (&/|log! out-str))))))]] + (return task)))) -- cgit v1.2.3 From d790fa289a9670c98fea5347fa0eed9845751468 Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Tue, 11 Oct 2016 19:52:06 -0400 Subject: - Better error handling with paraller compilation. - When issuing re-compilation from the compiler-cache, it's also done in parallel. --- src/lux/analyser/lux.clj | 33 +++++++++++++++++---------------- src/lux/compiler.clj | 10 ++++------ src/lux/compiler/cache.clj | 2 +- src/lux/compiler/parallel.clj | 4 ++-- 4 files changed, 24 insertions(+), 25 deletions(-) diff --git a/src/lux/analyser/lux.clj b/src/lux/analyser/lux.clj index 69b389e70..8a8f22586 100644 --- a/src/lux/analyser/lux.clj +++ b/src/lux/analyser/lux.clj @@ -653,29 +653,30 @@ _ (&&module/add-import path) ?async (if (not already-compiled?) (compile-module path) - (|do [_module (&/find-module path) - _compiler get-compiler] + (|do [_compiler get-compiler] (return (doto (promise) - (deliver _compiler))))) + (deliver (&/$Right _compiler)))))) _ (if (= "" alias) (return nil) (&&module/alias current-module alias path))] (return ?async)))))) _imports) _compiler get-compiler - :let [;; Some type-vars in the typing environment stay in - ;; the environment forever, making type-checking slower. - ;; The merging process for compilers more-or-less "fixes" the - ;; problem by resetting the typing enviroment, but ideally - ;; those type-vars shouldn't survive in the first place. - ;; TODO: MUST FIX - _compiler* (&/fold2 (fn [compiler _import _async] - (|let [[path alias] _import] - (merge-compilers current-module @_async compiler))) - _compiler - _imports - =asyncs)] - _ (set-compiler _compiler*)] + ;; Some type-vars in the typing environment stay in + ;; the environment forever, making type-checking slower. + ;; The merging process for compilers more-or-less "fixes" the + ;; problem by resetting the typing enviroment, but ideally + ;; those type-vars shouldn't survive in the first place. + ;; TODO: MUST FIX + _ (&/fold% (fn [compiler _async] + (|case @_async + (&/$Right _new-compiler) + (set-compiler (merge-compilers current-module _new-compiler compiler)) + + (&/$Left ?error) + (fail ?error))) + _compiler + =asyncs)] (return &/$Nil))) (defn ^:private coerce [new-type analysis] diff --git a/src/lux/compiler.clj b/src/lux/compiler.clj index 8b9e8bbed..6506c867b 100644 --- a/src/lux/compiler.clj +++ b/src/lux/compiler.clj @@ -169,13 +169,11 @@ (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)]] + :let [file-hash (hash file-content) + compile-module!! (&¶llel/parallel-compilation (partial compile-module source-dirs))]] (if (&&cache/cached? name) - (&&cache/load source-dirs name file-hash compile-module) - (let [compiler-step (&analyser/analyse &optimizer/optimize - eval! - (&¶llel/parallel-compilation (partial compile-module source-dirs)) - all-compilers)] + (&&cache/load source-dirs name file-hash compile-module!!) + (let [compiler-step (&analyser/analyse &optimizer/optimize eval! compile-module!! all-compilers)] (|do [module-exists? (&a-module/exists? name)] (if module-exists? (fail "[Compiler Error] Can't redefine a module!") diff --git a/src/lux/compiler/cache.clj b/src/lux/compiler/cache.clj index f2668f8b5..4f90c7cce 100644 --- a/src/lux/compiler/cache.clj +++ b/src/lux/compiler/cache.clj @@ -89,7 +89,7 @@ (if already-loaded? (return module-hash) (|let [redo-cache (|do [_ (delete module)] - (compile-module source-dirs module))] + (compile-module module))] (if (cached? module) (|do [loader &/loader !classes &/classes diff --git a/src/lux/compiler/parallel.clj b/src/lux/compiler/parallel.clj index 3506eb82e..8f6fee99d 100644 --- a/src/lux/compiler/parallel.clj +++ b/src/lux/compiler/parallel.clj @@ -39,9 +39,9 @@ (|case (&/run-state (compile-module* module-name) compiler) (&/$Right post-compiler _) - (deliver task post-compiler) + (deliver task (&/$Right post-compiler)) (&/$Left ?error) - (println ?error)))] + (deliver task (&/$Left ?error))))] (&/|log! out-str))))))]] (return task)))) -- cgit v1.2.3