From e35f31c170be160b30f22eae22871eba74db2767 Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Mon, 30 Oct 2017 23:55:33 -0400 Subject: - Added "^code" pattern-matching macro for easier handling of code. --- stdlib/source/lux.lux | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) (limited to 'stdlib/source') 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 [ ] + [_ ( value)] + (do Monad + [g!meta (gensym "g!meta")] + (wrap (` [(~ g!meta) ( (~ ( 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 + [=fields (mapM Monad + (function [[key value]] + (do Monad + [=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 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 [] + [_ ( elems)] + (case (reverse elems) + (#;Cons [_ (#Form (#Cons [[_ (#Symbol ["" "~@"])] (#Cons [spliced #Nil])]))] + inits) + (do Monad + [=inits (mapM Monad untemplate-pattern (reverse inits)) + g!meta (gensym "g!meta")] + (wrap (` [(~ g!meta) ( (~ (untemplate-list& spliced =inits)))]))) + + _ + (do Monad + [=elems (mapM Monad untemplate-pattern elems) + g!meta (gensym "g!meta")] + (wrap (` [(~ g!meta) ( (~ (untemplate-list =elems)))]))))) + ([#;Tuple] [#;Form]) + )) + +(macro: #export (^code tokens) + (case tokens + (^ (list& [_meta (#;Form (list template))] body branches)) + (do Monad + [pattern (untemplate-pattern template)] + (wrap (list& pattern body branches))) + + _ + (fail "Wrong syntax for ^code"))) -- cgit v1.2.3