diff options
Diffstat (limited to 'stdlib/source/library/lux/extension.lux')
-rw-r--r-- | stdlib/source/library/lux/extension.lux | 89 |
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:] + ) |