diff options
Diffstat (limited to 'stdlib/source/lux/macro/template.lux')
-rw-r--r-- | stdlib/source/lux/macro/template.lux | 54 |
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))))))))) + )) |