aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/meta/extension.lux
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib/source/library/lux/meta/extension.lux')
-rw-r--r--stdlib/source/library/lux/meta/extension.lux70
1 files changed, 70 insertions, 0 deletions
diff --git a/stdlib/source/library/lux/meta/extension.lux b/stdlib/source/library/lux/meta/extension.lux
new file mode 100644
index 000000000..3ab53a44a
--- /dev/null
+++ b/stdlib/source/library/lux/meta/extension.lux
@@ -0,0 +1,70 @@
+(.require
+ [library
+ [lux (.except)
+ [abstract
+ ["[0]" monad]]
+ [control
+ ["<>" parser (.use "[1]#[0]" monad)]]
+ [data
+ ["[0]" product]
+ [collection
+ ["[0]" list (.use "[1]#[0]" functor)]]]
+ [meta
+ ["[0]" code (.only)
+ ["<c>" \\parser (.only Parser)]]
+ [macro (.only with_symbols)
+ [syntax (.only syntax)]]
+ [compiler
+ ["[0]" phase]
+ [language
+ [lux
+ [analysis
+ ["<a>" \\parser]]
+ [synthesis
+ ["<s>" \\parser]]]]]]]])
+
+(type Declaration
+ (Record
+ [#name Code
+ #label Text
+ #phase Text
+ #archive Text
+ #inputs (List Code)]))
+
+(def (declarationP default)
+ (-> Code (Parser Declaration))
+ (<c>.form (all <>.and
+ <c>.any
+ <c>.local
+ <c>.local
+ <c>.local
+ (<c>.tuple (<>.some <c>.any)))))
+
+(with_template [<any> <end> <and> <result> <extension> <name>]
+ [(def .public <name>
+ (syntax (_ [[name extension phase archive inputs] (..declarationP (` <any>))
+ body <c>.any])
+ (let [g!name (code.local extension)
+ g!phase (code.local phase)
+ g!archive (code.local archive)]
+ (with_symbols [g!handler g!inputs g!error g!_]
+ (in (list (` (<extension> (, name)
+ (.function ((, g!handler) (, g!name) (, g!phase) (, g!archive) (, g!inputs))
+ (.case ((,! <result>)
+ ((,! monad.do) (,! <>.monad)
+ [(,* inputs)
+ (, g!_) <end>]
+ (.at (,! <>.monad) (,' in) (, body)))
+ (, g!inputs))
+ {.#Right (, g!_)}
+ (, g!_)
+
+ {.#Left (, g!error)}
+ ((,! phase.failure) (, g!error)))
+ )))))))))]
+
+ [<c>.any <c>.end <c>.and <c>.result "lux def analysis" analysis]
+ [<a>.any <a>.end <a>.and <a>.result "lux def synthesis" synthesis]
+ [<s>.any <s>.end <s>.and <s>.result "lux def generation" generation]
+ [<c>.any <c>.end <c>.and <c>.result "lux def declaration" declaration]
+ )