diff options
Diffstat (limited to 'stdlib/source/lux/tool/compiler/phase/directive.lux')
-rw-r--r-- | stdlib/source/lux/tool/compiler/phase/directive.lux | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/stdlib/source/lux/tool/compiler/phase/directive.lux b/stdlib/source/lux/tool/compiler/phase/directive.lux new file mode 100644 index 000000000..f79f2b586 --- /dev/null +++ b/stdlib/source/lux/tool/compiler/phase/directive.lux @@ -0,0 +1,79 @@ +(.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] + ["/" directive (#+ Phase)]]]) + +(exception: #export (not-a-directive {code Code}) + (exception.report + ["Directive" (%.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 [<lux_def_module> (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& <lux_def_module> referrals)) + (do @ + [requirements (compile <lux_def_module>)] + (wrap (update@ #/.referrals (list;compose referrals) requirements))) + + _ + (|> expansion + (monad.map @ compile) + (:: @ map (list;fold /.merge-requirements /.no-requirements))))] + (wrap requirements)) + + _ + (//.throw not-a-directive code)))))) |