aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source
diff options
context:
space:
mode:
authorEduardo Julian2017-10-30 23:55:33 -0400
committerEduardo Julian2017-10-30 23:55:33 -0400
commite35f31c170be160b30f22eae22871eba74db2767 (patch)
treeb73d58f00056c26996d5479370f82f485abdf827 /stdlib/source
parenta12eb1ae67e36ee12dd434da948a25b6b18e34d6 (diff)
- Added "^code" pattern-matching macro for easier handling of code.
Diffstat (limited to 'stdlib/source')
-rw-r--r--stdlib/source/lux.lux76
1 files changed, 76 insertions, 0 deletions
diff --git a/stdlib/source/lux.lux b/stdlib/source/lux.lux
index bf77ca259..e3a81cebd 100644
--- a/stdlib/source/lux.lux
+++ b/stdlib/source/lux.lux
@@ -5973,3 +5973,79 @@
_
(fail "Wrong syntax for ``")
))
+
+(def: (ident$ [module name])
+ (-> Ident Code)
+ (` [(~ (text$ module)) (~ (text$ name))]))
+
+(def: (untemplate-list& last inits)
+ (-> Code (List Code) Code)
+ (case inits
+ #Nil
+ last
+
+ (#Cons [init inits'])
+ (` (#;Cons (~ init) (~ (untemplate-list& last inits'))))))
+
+(def: (untemplate-pattern pattern)
+ (-> Code (Meta Code))
+ (case pattern
+ (^template [<tag> <name> <gen>]
+ [_ (<tag> value)]
+ (do Monad<Meta>
+ [g!meta (gensym "g!meta")]
+ (wrap (` [(~ g!meta) (<tag> (~ (<gen> value)))]))))
+ ([#Bool "Bool" bool$]
+ [#Nat "Nat" nat$]
+ [#Int "Int" int$]
+ [#Deg "Deg" deg$]
+ [#Frac "Frac" frac$]
+ [#Text "Text" text$]
+ [#Tag "Tag" ident$]
+ [#Symbol "Symbol" ident$])
+
+ [_ (#Record fields)]
+ (do Monad<Meta>
+ [=fields (mapM Monad<Meta>
+ (function [[key value]]
+ (do Monad<Meta>
+ [=key (untemplate-pattern key)
+ =value (untemplate-pattern value)]
+ (wrap (` [(~ =key) (~ =value)]))))
+ fields)
+ g!meta (gensym "g!meta")]
+ (wrap (` [(~ g!meta) (#;Record (~ (untemplate-list =fields)))])))
+
+ [_ (#Form (#Cons [[_ (#Symbol ["" "~"])] (#Cons [unquoted #Nil])]))]
+ (:: Monad<Meta> wrap unquoted)
+
+ [_ (#Form (#Cons [[_ (#Symbol ["" "~@"])] (#Cons [spliced #Nil])]))]
+ (fail "Cannot use (~@) inside of ^code unless it is the last element in a form or a tuple.")
+
+ (^template [<tag>]
+ [_ (<tag> elems)]
+ (case (reverse elems)
+ (#;Cons [_ (#Form (#Cons [[_ (#Symbol ["" "~@"])] (#Cons [spliced #Nil])]))]
+ inits)
+ (do Monad<Meta>
+ [=inits (mapM Monad<Meta> untemplate-pattern (reverse inits))
+ g!meta (gensym "g!meta")]
+ (wrap (` [(~ g!meta) (<tag> (~ (untemplate-list& spliced =inits)))])))
+
+ _
+ (do Monad<Meta>
+ [=elems (mapM Monad<Meta> untemplate-pattern elems)
+ g!meta (gensym "g!meta")]
+ (wrap (` [(~ g!meta) (<tag> (~ (untemplate-list =elems)))])))))
+ ([#;Tuple] [#;Form])
+ ))
+
+(macro: #export (^code tokens)
+ (case tokens
+ (^ (list& [_meta (#;Form (list template))] body branches))
+ (do Monad<Meta>
+ [pattern (untemplate-pattern template)]
+ (wrap (list& pattern body branches)))
+
+ _
+ (fail "Wrong syntax for ^code")))