(.module: [lux #* [abstract ["." monad (#+ do)]] [control ["." exception (#+ exception:)]] [data [text ["%" format (#+ format)]] [collection ["." list ("#;." fold monoid)]]] ["." macro]] ["." // ["#." macro (#+ Expander)] ["#." extension] [".P" analysis ["." type]] ["#/" // #_ [reference (#+)] ["#." analysis] ["/" statement (#+ Phase)]]]) (exception: #export (not-a-statement {code Code}) (exception.report ["Statement" (%.code code)])) (exception: #export (invalid-macro-call {code Code}) (exception.report ["Code" (%.code code)])) (exception: #export (macro-was-not-found {name Name}) (exception.report ["Name" (%.name name)])) (with-expansions [ (as-is [|form-cursor| (#.Form (list& [|text-cursor| (#.Text "lux def module")] annotations))])] (def: #export (phase expander) (-> Expander Phase) (let [analyze (analysisP.phase expander)] (function (compile code) (case code (^ [_ (#.Form (list& [_ (#.Text name)] inputs))]) (do //.monad [requirements (//extension.apply compile [name inputs])] (wrap requirements)) (^ [_ (#.Form (list& macro inputs))]) (do //.monad [expansion (/.lift-analysis (do @ [macroA (type.with-type Macro (analyze macro))] (case macroA (^ (///analysis.constant macro-name)) (do @ [?macro (//extension.lift (macro.find-macro macro-name)) macro (case ?macro (#.Some macro) (wrap macro) #.None (//.throw macro-was-not-found macro-name))] (//extension.lift (//macro.expand expander macro-name macro inputs))) _ (//.throw invalid-macro-call code)))) requirements (case expansion (^ (list& referrals)) (do @ [requirements (compile )] (wrap (update@ #/.referrals (list;compose referrals) requirements))) _ (|> expansion (monad.map @ compile) (:: @ map (list;fold /.merge-requirements /.no-requirements))))] (wrap requirements)) _ (//.throw not-a-statement code))))))