(.module: lux (lux (control [monad #+ do] ["p" parser] ["ex" exception #+ exception:]) (data ["e" error #+ Error] [maybe] [text "text/" Eq] text/format) [macro] (macro [code] ["s" syntax]) [io #+ Process]) (luxc [lang] (lang [".L" module]))) (do-template [] [(exception: #export ( {message Text}) message)] [Invalid-Imports] [Module-Cannot-Import-Itself] [Circular-Dependency] ) (type: Import {#module Text #alias Text}) (def: import (s.Syntax Import) (s.tuple (p.seq s.text s.text))) (def: #export (translate-imports translate-module annotations) (-> (-> Text Lux (Process Lux)) Code (Meta (Process Lux))) (do macro.Monad [_ (moduleL.set-annotations annotations) current-module macro.current-module-name imports (let [imports (|> (macro.get-tuple-ann (ident-for #.imports) annotations) (maybe.default (list)))] (case (s.run imports (p.some import)) (#e.Success imports) (wrap imports) (#e.Error error) (lang.throw Invalid-Imports (%code (code.tuple imports))))) _ (monad.map @ (function (_ [dependency alias]) (do @ [_ (lang.assert Module-Cannot-Import-Itself current-module (not (text/= current-module dependency))) already-seen? (moduleL.exists? dependency) circular-dependency? (if already-seen? (moduleL.active? dependency) (wrap false)) _ (lang.assert Circular-Dependency (format "From: " current-module "\n" " To: " dependency) (not circular-dependency?)) _ (moduleL.import dependency) _ (if (text/= "" alias) (wrap []) (moduleL.alias alias dependency))] (wrap []))) imports) compiler macro.get-compiler] (wrap (monad.fold io.Monad (function (_ import) (translate-module (get@ #module import))) compiler imports))))