aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/lux/tool/compiler/phase/directive.lux
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib/source/lux/tool/compiler/phase/directive.lux')
-rw-r--r--stdlib/source/lux/tool/compiler/phase/directive.lux79
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))))))