diff options
Diffstat (limited to 'stdlib/source/lux/platform/compiler/phase/statement/total.lux')
-rw-r--r-- | stdlib/source/lux/platform/compiler/phase/statement/total.lux | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/stdlib/source/lux/platform/compiler/phase/statement/total.lux b/stdlib/source/lux/platform/compiler/phase/statement/total.lux new file mode 100644 index 000000000..15f116aa1 --- /dev/null +++ b/stdlib/source/lux/platform/compiler/phase/statement/total.lux @@ -0,0 +1,56 @@ +(.module: + [lux #* + [control + ["." monad (#+ do)] + ["ex" exception (#+ exception:)]] + [data + [text + format]] + ["." macro]] + ["." // (#+ Phase) + ["/." // + ["." analysis + ["." expression] + ["." type] + ["///." macro]] + ["." extension]]]) + +(exception: #export (not-a-statement {code Code}) + (ex.report ["Statement" (%code code)])) + +(exception: #export (not-a-macro {code Code}) + (ex.report ["Code" (%code code)])) + +(exception: #export (macro-was-not-found {name Name}) + (ex.report ["Name" (%name name)])) + +(def: #export (phase code) + Phase + (case code + (^ [_ (#.Form (list& [_ (#.Text name)] inputs))]) + (extension.apply "Statement" phase [name inputs]) + + (^ [_ (#.Form (list& macro inputs))]) + (do ///.Monad<Operation> + [expansion (//.lift-analysis + (do @ + [macroA (type.with-type Macro + (expression.compile 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 macro-name macro inputs))) + + _ + (///.throw not-a-macro code))))] + (monad.map @ phase expansion)) + + _ + (///.throw not-a-statement code))) |