aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/extension.lux
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib/source/library/lux/extension.lux')
-rw-r--r--stdlib/source/library/lux/extension.lux89
1 files changed, 89 insertions, 0 deletions
diff --git a/stdlib/source/library/lux/extension.lux b/stdlib/source/library/lux/extension.lux
new file mode 100644
index 000000000..5cad0158c
--- /dev/null
+++ b/stdlib/source/library/lux/extension.lux
@@ -0,0 +1,89 @@
+(.module:
+ [library
+ [lux #*
+ [abstract
+ ["." monad]]
+ [control
+ ["<>" parser ("#\." monad)
+ ["<c>" code (#+ Parser)]
+ ["<a>" analysis]
+ ["<s>" synthesis]]]
+ [data
+ ["." product]
+ [collection
+ ["." list ("#\." functor)]]]
+ [macro (#+ with_gensyms)
+ ["." code]
+ [syntax (#+ syntax:)]]
+ [tool
+ [compiler
+ ["." phase]]]]])
+
+(type: Input
+ {#variable Text
+ #parser Code})
+
+(def: (simple default)
+ (-> Code (Parser Input))
+ ($_ <>.and
+ <c>.local_identifier
+ (<>\wrap default)))
+
+(def: complex
+ (Parser Input)
+ (<c>.record ($_ <>.and
+ <c>.local_identifier
+ <c>.any)))
+
+(def: (input default)
+ (-> Code (Parser Input))
+ (<>.either (..simple default)
+ ..complex))
+
+(type: Declaration
+ {#name Code
+ #label Text
+ #phase Text
+ #archive Text
+ #inputs (List Input)})
+
+(def: (declaration default)
+ (-> Code (Parser Declaration))
+ (<c>.form ($_ <>.and
+ <c>.any
+ <c>.local_identifier
+ <c>.local_identifier
+ <c>.local_identifier
+ (<>.some (..input default)))))
+
+(template [<any> <end> <and> <run> <extension> <name>]
+ [(syntax: #export (<name>
+ {[name extension phase archive inputs] (..declaration (` <any>))}
+ body)
+ (let [g!parser (case (list\map product.right inputs)
+ #.Nil
+ (` <end>)
+
+ parsers
+ (` (.$_ <and> (~+ parsers))))
+ g!name (code.local_identifier extension)
+ g!phase (code.local_identifier phase)
+ g!archive (code.local_identifier archive)]
+ (with_gensyms [g!handler g!inputs g!error]
+ (wrap (list (` (<extension> (~ name)
+ (.function ((~ g!handler) (~ g!name) (~ g!phase) (~ g!archive) (~ g!inputs))
+ (.case ((~! <run>) (~ g!parser) (~ g!inputs))
+ (#.Right [(~+ (list\map (|>> product.left
+ code.local_identifier)
+ inputs))])
+ (~ body)
+
+ (#.Left (~ g!error))
+ ((~! phase.fail) (~ g!error)))
+ ))))))))]
+
+ [<c>.any <c>.end! <c>.and <c>.run "lux def analysis" analysis:]
+ [<a>.any <a>.end! <a>.and <a>.run "lux def synthesis" synthesis:]
+ [<s>.any <s>.end! <s>.and <s>.run "lux def generation" generation:]
+ [<c>.any <c>.end! <c>.and <c>.run "lux def directive" directive:]
+ )