aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/lux/macro/template.lux
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib/source/lux/macro/template.lux')
-rw-r--r--stdlib/source/lux/macro/template.lux54
1 files changed, 54 insertions, 0 deletions
diff --git a/stdlib/source/lux/macro/template.lux b/stdlib/source/lux/macro/template.lux
new file mode 100644
index 000000000..0288f05cf
--- /dev/null
+++ b/stdlib/source/lux/macro/template.lux
@@ -0,0 +1,54 @@
+## Copyright (c) Eduardo Julian. All rights reserved.
+## This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
+## If a copy of the MPL was not distributed with this file,
+## You can obtain one at http://mozilla.org/MPL/2.0/.
+
+(;module:
+ lux
+ (lux (control monad)
+ (data (struct [list "" Monad<List> Fold<List>]
+ [dict #+ Dict])
+ [text])
+ [compiler]
+ (macro [ast]
+ ["s" syntax #+ syntax: Syntax]
+ (syntax [common]))))
+
+## [Syntax]
+(def: decl^
+ (Syntax [Text (List Text)])
+ (s;form (s;seq s;local-symbol (s;many s;local-symbol))))
+
+(def: (prepare bindings template)
+ (-> (Dict Text AST) AST AST)
+ (case template
+ (^=> [_ (#;SymbolS "" name)]
+ {(dict;get name bindings) (#;Some found)})
+ found
+
+ (^template [<tag>]
+ [meta (<tag> parts)]
+ [meta (<tag> (map (prepare bindings ) parts))])
+ ([#;FormS]
+ [#;TupleS])
+
+
+ [meta (#;RecordS pairs)]
+ [meta (#;RecordS (map (lambda [[slot value]]
+ [(prepare bindings slot)
+ (prepare bindings value)])
+ pairs))]
+
+ _
+ template
+ ))
+
+(syntax: #export (template: {_ex-lev common;export-level} {[name args] decl^} template)
+ (let [bindings (fold (lambda [arg bindings]
+ (dict;put arg (` ((~' ~) (~ (ast;symbol ["" arg])))) bindings))
+ (: (Dict Text AST) (dict;new text;Hash<Text>))
+ args)]
+ (wrap (list (` (syntax: (~@ (common;gen-export-level _ex-lev)) ((~ (ast;symbol ["" name]))
+ (~@ (map (|>. [""] ast;symbol) args)))
+ ((~' wrap) (list (` (~ (prepare bindings template)))))))))
+ ))