(.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]))) (exception: #export Invalid-Imports) (exception: #export Module-Cannot-Import-Itself) (exception: #export 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 Compiler (Process Compiler)) Code (Meta (Process Compiler))) (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))))