diff options
-rw-r--r-- | stdlib/source/lux/macro/syntax.lux | 5 | ||||
-rw-r--r-- | stdlib/source/lux/macro/template.lux | 31 |
2 files changed, 23 insertions, 13 deletions
diff --git a/stdlib/source/lux/macro/syntax.lux b/stdlib/source/lux/macro/syntax.lux index 704f6d245..c4580f13f 100644 --- a/stdlib/source/lux/macro/syntax.lux +++ b/stdlib/source/lux/macro/syntax.lux @@ -20,25 +20,21 @@ ["." // (#+ with-gensyms) ["." code ("code/." equivalence)]]) -## [Utils] (def: (join-pairs pairs) (All [a] (-> (List [a a]) (List a))) (case pairs #.Nil #.Nil (#.Cons [[x y] pairs']) (list& x y (join-pairs pairs')))) -## [Types] (type: #export Syntax {#.doc "A Lux syntax parser."} (p.Parser (List Code))) -## [Utils] (def: (remaining-inputs asts) (-> (List Code) Text) ($_ text/compose text.new-line "Remaining input: " (|> asts (list/map code.to-text) (list.interpose " ") (text.join-with "")))) -## [Syntaxs] (def: #export any {#.doc "Just returns the next input without applying any logic."} (Syntax Code) @@ -198,7 +194,6 @@ [value (run inputs syntax)] (wrap [real value])))) -## [Syntax] (macro: #export (syntax: tokens) {#.doc (doc "A more advanced way to define macros than 'macro:'." "The inputs to the macro can be parsed in complex ways through the use of syntax parsers." diff --git a/stdlib/source/lux/macro/template.lux b/stdlib/source/lux/macro/template.lux index 21621ba07..e08446bd8 100644 --- a/stdlib/source/lux/macro/template.lux +++ b/stdlib/source/lux/macro/template.lux @@ -1,11 +1,26 @@ (.module: - [lux #*] - ["." // ("meta/." monad)]) + [lux #* + [control + ["." monad (#+ do)] + ["p" parser]] + [data + [collection + ["." list ("list/." monad)]]]] + ["." // + ["." code] + ["s" syntax (#+ syntax:)]]) -(macro: #export (splice tokens) - (case tokens - (^ (list [_ (#.Tuple parts)])) - (meta/wrap parts) +(syntax: #export (splice {parts (s.tuple (p.some s.any))}) + (wrap parts)) - _ - (//.fail (//.wrong-syntax-error (name-of ..splice))))) +(syntax: #export (with-locals {locals (s.tuple (p.some s.local-identifier))} + body) + (do @ + [g!locals (|> (//.gensym "local") + (list.repeat (list.size locals)) + (monad.seq @))] + (wrap (list (` (.with-expansions [(~+ (|> (list.zip2 locals g!locals) + (list/map (function (_ [name identifier]) + (list (code.local-identifier name) (as-is identifier)))) + list/join))] + (~ body))))))) |