aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--stdlib/source/lux/macro/template.lux2
-rw-r--r--stdlib/test/test/lux/macro/ast.lux52
-rw-r--r--stdlib/test/test/lux/macro/syntax.lux419
-rw-r--r--stdlib/test/test/lux/macro/template.lux27
-rw-r--r--stdlib/test/tests.lux18
5 files changed, 318 insertions, 200 deletions
diff --git a/stdlib/source/lux/macro/template.lux b/stdlib/source/lux/macro/template.lux
index fe533cae8..e66d386d8 100644
--- a/stdlib/source/lux/macro/template.lux
+++ b/stdlib/source/lux/macro/template.lux
@@ -49,6 +49,6 @@
(: (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)))
+ (~@ (map (|>. [""] ast;symbol) args)))
((~' wrap) (list (` (~ (prepare bindings template)))))))))
))
diff --git a/stdlib/test/test/lux/macro/ast.lux b/stdlib/test/test/lux/macro/ast.lux
index b06efce01..a10486edc 100644
--- a/stdlib/test/test/lux/macro/ast.lux
+++ b/stdlib/test/test/lux/macro/ast.lux
@@ -1,31 +1,39 @@
+## 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 (codata [io])
+ (codata function)
(control monad)
- (data [text "Text/" Monoid<Text>]
+ (data [text "T/" Eq<Text>]
+ text/format
[number])
- (macro ast)
- (codata function))
+ (math ["R" random])
+ pipe
+ (macro ["&" ast]))
lux/test)
-(test: "lux/macro/ast exports"
- (let% [<tests> (do-template [<expr> <text> <pattern>]
- [(match <pattern> <expr>)
- (match <text> (ast-to-text <expr>))
- (match true (:: Eq<AST> = <expr> <expr>))]
+(test: "AST"
+ (let% [<tests> (do-template [<expr> <text>]
+ [(assert (format "Can produce AST node: " <text>)
+ (and (T/= <text> (&;to-text <expr>))
+ (:: &;Eq<AST> = <expr> <expr>)))]
- [(bool true) "true" [["" -1 -1] (#;BoolS true)]]
- [(bool false) "false" [_ (#;BoolS false)]]
- [(int 123) "123" [_ (#;IntS 123)]]
- [(real 123.0) "123.0" [_ (#;RealS 123.0)]]
- [(char #"\n") "#\"\\n\"" [_ (#;CharS #"\n")]]
- [(text "\n") "\"\\n\"" [_ (#;TextS "\n")]]
- [(tag ["yolo" "lol"]) "#yolo;lol" [_ (#;TagS ["yolo" "lol"])]]
- [(symbol ["yolo" "lol"]) "yolo;lol" [_ (#;SymbolS ["yolo" "lol"])]]
- [(form (list (bool true) (int 123))) "(true 123)" (^ [_ (#;FormS (list [_ (#;BoolS true)] [_ (#;IntS 123)]))])]
- [(tuple (list (bool true) (int 123))) "[true 123]" (^ [_ (#;TupleS (list [_ (#;BoolS true)] [_ (#;IntS 123)]))])]
- [(record (list [(bool true) (int 123)])) "{true 123}" (^ [_ (#;RecordS (list [[_ (#;BoolS true)] [_ (#;IntS 123)]]))])]
- [(local-tag "lol") "#lol" [_ (#;TagS ["" "lol"])]]
- [(local-symbol "lol") "lol" [_ (#;SymbolS ["" "lol"])]]
+ [(&;bool true) "true"]
+ [(&;bool false) "false"]
+ [(&;int 123) "123"]
+ [(&;real 123.0) "123.0"]
+ [(&;char #"\n") "#\"\\n\""]
+ [(&;text "\n") "\"\\n\""]
+ [(&;tag ["yolo" "lol"]) "#yolo;lol"]
+ [(&;symbol ["yolo" "lol"]) "yolo;lol"]
+ [(&;form (list (&;bool true) (&;int 123))) "(true 123)"]
+ [(&;tuple (list (&;bool true) (&;int 123))) "[true 123]"]
+ [(&;record (list [(&;bool true) (&;int 123)])) "{true 123}"]
+ [(&;local-tag "lol") "#lol"]
+ [(&;local-symbol "lol") "lol"]
)]
- (test-all <tests>)))
+ ($_ seq <tests>)))
diff --git a/stdlib/test/test/lux/macro/syntax.lux b/stdlib/test/test/lux/macro/syntax.lux
index 99f8550c0..17d4c935b 100644
--- a/stdlib/test/test/lux/macro/syntax.lux
+++ b/stdlib/test/test/lux/macro/syntax.lux
@@ -1,176 +1,259 @@
+## 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 (codata [io])
- (control monad)
+ (control monad
+ eq)
(data [text "Text/" Monoid<Text>]
- [number])
+ text/format
+ [number]
+ [bool]
+ [char]
+ [ident]
+ [error #- fail])
+ (codata function)
+ (math ["R" random])
+ pipe
+ [compiler]
(macro [ast]
- ["s" syntax #+ syntax: Syntax])
- (codata function))
+ ["s" syntax #+ syntax: Syntax]))
lux/test)
-(test: "lux/macro/syntax exports [Part 1]"
- (let% [<simple-tests> (do-template [<pattern> <expr> <get> <ask> <demand>]
- [(match (#;Right [_ <pattern>])
- (s;run (list <expr>)
- <get>))
- (match (#;Right [_ true])
- (s;run (list <expr>)
- (<ask> <pattern>)))
- (match (#;Right [_ []])
- (s;run (list <expr>)
- (<demand> <pattern>)))]
-
- [true (ast;bool true) s;bool s;bool? s;bool!]
- [123 (ast;int 123) s;int s;int? s;int!]
- [123.0 (ast;real 123.0) s;real s;real? s;real!]
- [#"\n" (ast;char #"\n") s;char s;char? s;char!]
- ["\n" (ast;text "\n") s;text s;text? s;text!]
- [["yolo" "lol"] (ast;symbol ["yolo" "lol"]) s;symbol s;symbol? s;symbol!]
- [["yolo" "lol"] (ast;tag ["yolo" "lol"]) s;tag s;tag? s;tag!]
- )
- <group-tests> (do-template [<parser> <ctor>]
- [(match (#;Right [_ [true 123]])
- (s;run (list (<ctor> (list (ast;bool true) (ast;int 123))))
- (<parser> (s;seq s;bool s;int))))
- (match (#;Right [_ true])
- (s;run (list (<ctor> (list (ast;bool true))))
- (<parser> s;bool)))
- (match (#;Left _)
- (s;run (list (<ctor> (list (ast;bool true) (ast;int 123))))
- (<parser> s;bool)))
- (match (#;Right [_ (#;Left true)])
- (s;run (list (<ctor> (list (ast;bool true))))
- (<parser> (s;alt s;bool s;int))))
- (match (#;Right [_ (#;Right 123)])
- (s;run (list (<ctor> (list (ast;int 123))))
- (<parser> (s;alt s;bool s;int))))
- (match (#;Left _)
- (s;run (list (<ctor> (list (ast;real 123.0))))
- (<parser> (s;alt s;bool s;int))))]
-
- [s;form ast;form]
- [s;tuple ast;tuple])]
- (test-all (match (#;Right [_ [_ (#;BoolS true)]])
- (s;run (list (ast;bool true) (ast;int 123))
- s;any))
- <simple-tests>
- (match (#;Right [_ []])
- (s;run (list (ast;bool true) (ast;int 123))
- (s;assert true "yolo")))
- (match (#;Left _)
+## [Utils]
+(def: (enforced? parser input)
+ (-> (Syntax []) (List AST) Bool)
+ (case (s;run input parser)
+ (#;Right [_ []])
+ true
+
+ _
+ false))
+
+(def: (found? parser input)
+ (-> (Syntax Bool) (List AST) Bool)
+ (case (s;run input parser)
+ (#;Right [_ true])
+ true
+
+ _
+ false))
+
+(def: (is? Eq<a> test parser input)
+ (All [a] (-> (Eq a) a (Syntax a) (List AST) Bool))
+ (case (s;run input parser)
+ (#;Right [_ output])
+ (:: Eq<a> = test output)
+
+ _
+ false))
+
+(def: (fails? input)
+ (All [a] (-> (Error a) Bool))
+ (case input
+ (#;Left _)
+ true
+
+ _
+ false))
+
+(syntax: (match pattern input)
+ (wrap (list (` (case (~ input)
+ (^ (#;Right [(~' _) (~ pattern)]))
+ true
+
+ (~' _)
+ false)))))
+
+## [Tests]
+(test: "Simple value syntax."
+ (let% [<simple-tests> (do-template [<assertion> <value> <ctor> <Eq> <get> <ask> <demand>]
+ [(assert <assertion>
+ (and (is? <Eq> <value> <get> (list (<ctor> <value>)))
+ (found? (<ask> <value>) (list (<ctor> <value>)))
+ (enforced? (<demand> <value>) (list (<ctor> <value>)))))]
+
+ ["Can parse Bool syntax." true ast;bool bool;Eq<Bool> s;bool s;bool? s;bool!]
+ ["Can parse Nat syntax." +123 ast;nat number;Eq<Nat> s;nat s;nat? s;nat!]
+ ["Can parse Int syntax." 123 ast;int number;Eq<Int> s;int s;int? s;int!]
+ ## ["Can parse Frac syntax." .123 ast;frac number;Eq<Frac> s;frac s;frac? s;frac!]
+ ["Can parse Real syntax." 123.0 ast;real number;Eq<Real> s;real s;real? s;real!]
+ ["Can parse Char syntax." #"\n" ast;char char;Eq<Char> s;char s;char? s;char!]
+ ["Can parse Text syntax." "\n" ast;text text;Eq<Text> s;text s;text? s;text!]
+ ["Can parse Symbol syntax." ["yolo" "lol"] ast;symbol ident;Eq<Ident> s;symbol s;symbol? s;symbol!]
+ ["Can parse Tag syntax." ["yolo" "lol"] ast;tag ident;Eq<Ident> s;tag s;tag? s;tag!]
+ )]
+ ($_ seq
+ <simple-tests>
+
+ (assert "Can parse symbols belonging to the current namespace."
+ (and (match "yolo"
+ (s;run (list (ast;local-symbol "yolo"))
+ s;local-symbol))
+ (fails? (s;run (list (ast;symbol ["yolo" "lol"]))
+ s;local-symbol))))
+
+ (assert "Can parse tags belonging to the current namespace."
+ (and (match "yolo"
+ (s;run (list (ast;local-tag "yolo"))
+ s;local-tag))
+ (fails? (s;run (list (ast;tag ["yolo" "lol"]))
+ s;local-tag))))
+ )))
+
+(test: "Complex value syntax."
+ (let% [<group-tests> (do-template [<type> <parser> <ctor>]
+ [(assert (format "Can parse " <type> " syntax.")
+ (and (match [true 123]
+ (s;run (list (<ctor> (list (ast;bool true) (ast;int 123))))
+ (<parser> (s;seq s;bool s;int))))
+ (match true
+ (s;run (list (<ctor> (list (ast;bool true))))
+ (<parser> s;bool)))
+ (fails? (s;run (list (<ctor> (list (ast;bool true) (ast;int 123))))
+ (<parser> s;bool)))
+ (match (#;Left true)
+ (s;run (list (<ctor> (list (ast;bool true))))
+ (<parser> (s;alt s;bool s;int))))
+ (match (#;Right 123)
+ (s;run (list (<ctor> (list (ast;int 123))))
+ (<parser> (s;alt s;bool s;int))))
+ (fails? (s;run (list (<ctor> (list (ast;real 123.0))))
+ (<parser> (s;alt s;bool s;int))))))]
+
+ ["form" s;form ast;form]
+ ["tuple" s;tuple ast;tuple])]
+ ($_ seq
+ <group-tests>
+
+ (assert "Can parse record syntax."
+ (match [true 123]
+ (s;run (list (ast;record (list [(ast;bool true) (ast;int 123)])))
+ (s;record (s;seq s;bool s;int)))))
+ )))
+
+(test: "Assertions"
+ (assert "Can make assertions while parsing."
+ (and (match []
+ (s;run (list (ast;bool true) (ast;int 123))
+ (s;assert "yolo" true)))
+ (fails? (s;run (list (ast;bool true) (ast;int 123))
+ (s;assert "yolo" false))))))
+
+(test: "Combinators [Part 1]"
+ ($_ seq
+ (assert "Can parse any AST."
+ (match [_ (#;BoolS true)]
(s;run (list (ast;bool true) (ast;int 123))
- (s;assert false "yolo")))
- (match (#;Right [_ +123])
- (s;run (list (ast;nat +123))
- s;nat))
- (match (#;Left _)
- (s;run (list (ast;int -123))
- s;nat))
- (match (#;Right [_ "yolo"])
- (s;run (list (ast;local-symbol "yolo"))
- s;local-symbol))
- (match (#;Left _)
- (s;run (list (ast;symbol ["yolo" "lol"]))
- s;local-symbol))
- (match (#;Right [_ "yolo"])
- (s;run (list (ast;local-tag "yolo"))
- s;local-tag))
- (match (#;Left _)
- (s;run (list (ast;tag ["yolo" "lol"]))
- s;local-tag))
- <group-tests>
- )))
-
-(test: "lux/macro/syntax exports [Part 2]"
- (test-all (match (#;Right [_ [true 123]])
- (s;run (list (ast;record (list [(ast;bool true) (ast;int 123)])))
- (s;record (s;seq s;bool s;int))))
- (match (#;Right [_ (#;Some +123)])
- (s;run (list (ast;nat +123))
- (s;opt s;nat)))
- (match (#;Right [_ #;None])
- (s;run (list (ast;int -123))
- (s;opt s;nat)))
- (match (^ (#;Right [_ (list +123 +456 +789)]))
- (s;run (list (ast;nat +123) (ast;nat +456) (ast;nat +789))
- (s;some s;nat)))
- (match (^ (#;Right [_ (list)]))
- (s;run (list (ast;int -123))
- (s;some s;nat)))
- (match (^ (#;Right [_ (list +123 +456 +789)]))
- (s;run (list (ast;nat +123) (ast;nat +456) (ast;nat +789))
- (s;many s;nat)))
- (match (^ (#;Right [_ (list +123)]))
- (s;run (list (ast;nat +123))
- (s;many s;nat)))
- (match (#;Left _)
- (s;run (list (ast;int -123))
- (s;many s;nat)))
- (match (#;Right [_ 123])
- (s;run (list (ast;int 123) (ast;int 456) (ast;int 789))
- (s;either s;pos-int s;int)))
- (match (#;Right [_ -123])
- (s;run (list (ast;int -123) (ast;int 456) (ast;int 789))
- (s;either s;pos-int s;int)))
- (match (#;Left _)
- (s;run (list (ast;bool true) (ast;int 456) (ast;int 789))
- (s;either s;pos-int s;int)))
- (match (#;Right [_ true])
- (s;run (list)
- s;end?))
- (match (#;Right [_ false])
- (s;run (list (ast;bool true))
- s;end?))
- (match (#;Right [_ []])
- (s;run (list)
- s;end))
- (match (#;Left _)
- (s;run (list (ast;bool true))
- s;end))
- (match (^ (#;Right [_ (list 123 456 789)]))
- (s;run (list (ast;int 123) (ast;int 456) (ast;int 789))
- (s;exactly +3 s;int)))
- (match (^ (#;Right [_ (list 123 456)]))
- (s;run (list (ast;int 123) (ast;int 456) (ast;int 789))
- (s;exactly +2 s;int)))
- (match (#;Left _)
- (s;run (list (ast;int 123) (ast;int 456) (ast;int 789))
- (s;exactly +4 s;int)))
- (match (^ (#;Right [_ (list 123 456 789)]))
- (s;run (list (ast;int 123) (ast;int 456) (ast;int 789))
- (s;at-least +3 s;int)))
- (match (^ (#;Right [_ (list 123 456 789)]))
- (s;run (list (ast;int 123) (ast;int 456) (ast;int 789))
- (s;at-least +2 s;int)))
- (match (#;Left _)
- (s;run (list (ast;int 123) (ast;int 456) (ast;int 789))
- (s;at-least +4 s;int)))
- (match (^ (#;Right [_ (list 123 456 789)]))
- (s;run (list (ast;int 123) (ast;int 456) (ast;int 789))
- (s;at-most +3 s;int)))
- (match (^ (#;Right [_ (list 123 456)]))
- (s;run (list (ast;int 123) (ast;int 456) (ast;int 789))
- (s;at-most +2 s;int)))
- (match (^ (#;Right [_ (list 123 456 789)]))
- (s;run (list (ast;int 123) (ast;int 456) (ast;int 789))
- (s;at-most +4 s;int)))
- (match (^ (#;Right [_ (list 123 456 789)]))
- (s;run (list (ast;int 123) (ast;int 456) (ast;int 789))
- (s;between +3 +10 s;int)))
- (match (#;Left _)
- (s;run (list (ast;int 123) (ast;int 456) (ast;int 789))
- (s;between +4 +10 s;int)))
- (match (^ (#;Right [_ (list 123 456 789)]))
- (s;run (list (ast;int 123) (ast;text "YOLO") (ast;int 456) (ast;text "YOLO") (ast;int 789))
- (s;sep-by (s;text! "YOLO") s;int)))
- (match (^ (#;Right [_ (list 123 456)]))
- (s;run (list (ast;int 123) (ast;text "YOLO") (ast;int 456) (ast;int 789))
- (s;sep-by (s;text! "YOLO") s;int)))
- (match (#;Left _)
- (s;run (list (ast;int 123) (ast;int 456) (ast;int 789))
- (s;not s;int)))
- (match (#;Right [_ []])
- (s;run (list (ast;bool true) (ast;int 456) (ast;int 789))
- (s;not s;int)))
- ))
+ s;any)))
+
+ (assert "Can optionally succeed with some parser."
+ (and (match (#;Some +123)
+ (s;run (list (ast;nat +123))
+ (s;opt s;nat)))
+ (match #;None
+ (s;run (list (ast;int -123))
+ (s;opt s;nat)))))
+
+ (assert "Can apply a parser 0 or more times."
+ (and (match (list +123 +456 +789)
+ (s;run (list (ast;nat +123) (ast;nat +456) (ast;nat +789))
+ (s;some s;nat)))
+ (match (list)
+ (s;run (list (ast;int -123))
+ (s;some s;nat)))))
+
+ (assert "Can apply a parser 1 or more times."
+ (and (match (list +123 +456 +789)
+ (s;run (list (ast;nat +123) (ast;nat +456) (ast;nat +789))
+ (s;many s;nat)))
+ (match (list +123)
+ (s;run (list (ast;nat +123))
+ (s;many s;nat)))
+ (fails? (s;run (list (ast;int -123))
+ (s;many s;nat)))))
+
+ (assert "Can use either parser."
+ (and (match 123
+ (s;run (list (ast;int 123) (ast;int 456) (ast;int 789))
+ (s;either s;pos-int s;int)))
+ (match -123
+ (s;run (list (ast;int -123) (ast;int 456) (ast;int 789))
+ (s;either s;pos-int s;int)))
+ (fails? (s;run (list (ast;bool true) (ast;int 456) (ast;int 789))
+ (s;either s;pos-int s;int)))))
+
+ (assert "Can create the opposite/negation of any parser."
+ (and (fails? (s;run (list (ast;int 123) (ast;int 456) (ast;int 789))
+ (s;not s;int)))
+ (match []
+ (s;run (list (ast;bool true) (ast;int 456) (ast;int 789))
+ (s;not s;int)))))
+ ))
+
+(test: "Combinators Part [2]"
+ ($_ seq
+ (assert "Can check whether the end has been reached."
+ (and (match true
+ (s;run (list)
+ s;end?))
+ (match false
+ (s;run (list (ast;bool true))
+ s;end?))))
+
+ (assert "Can ensure the end has been reached."
+ (and (match []
+ (s;run (list)
+ s;end))
+ (fails? (s;run (list (ast;bool true))
+ s;end))))
+
+ (assert "Can apply a parser N times."
+ (and (match (list 123 456 789)
+ (s;run (list (ast;int 123) (ast;int 456) (ast;int 789))
+ (s;exactly +3 s;int)))
+ (match (list 123 456)
+ (s;run (list (ast;int 123) (ast;int 456) (ast;int 789))
+ (s;exactly +2 s;int)))
+ (fails? (s;run (list (ast;int 123) (ast;int 456) (ast;int 789))
+ (s;exactly +4 s;int)))))
+
+ (assert "Can apply a parser at-least N times."
+ (and (match (list 123 456 789)
+ (s;run (list (ast;int 123) (ast;int 456) (ast;int 789))
+ (s;at-least +3 s;int)))
+ (match (list 123 456 789)
+ (s;run (list (ast;int 123) (ast;int 456) (ast;int 789))
+ (s;at-least +2 s;int)))
+ (fails? (s;run (list (ast;int 123) (ast;int 456) (ast;int 789))
+ (s;at-least +4 s;int)))))
+
+ (assert "Can apply a parser at-most N times."
+ (and (match (list 123 456 789)
+ (s;run (list (ast;int 123) (ast;int 456) (ast;int 789))
+ (s;at-most +3 s;int)))
+ (match (list 123 456)
+ (s;run (list (ast;int 123) (ast;int 456) (ast;int 789))
+ (s;at-most +2 s;int)))
+ (match (list 123 456 789)
+ (s;run (list (ast;int 123) (ast;int 456) (ast;int 789))
+ (s;at-most +4 s;int)))))
+
+ (assert "Can apply a parser between N and M times."
+ (and (match (list 123 456 789)
+ (s;run (list (ast;int 123) (ast;int 456) (ast;int 789))
+ (s;between +3 +10 s;int)))
+ (fails? (s;run (list (ast;int 123) (ast;int 456) (ast;int 789))
+ (s;between +4 +10 s;int)))))
+
+ (assert "Can parse while taking separators into account."
+ (and (match (list 123 456 789)
+ (s;run (list (ast;int 123) (ast;text "YOLO") (ast;int 456) (ast;text "YOLO") (ast;int 789))
+ (s;sep-by (s;text! "YOLO") s;int)))
+ (match (list 123 456)
+ (s;run (list (ast;int 123) (ast;text "YOLO") (ast;int 456) (ast;int 789))
+ (s;sep-by (s;text! "YOLO") s;int)))))
+ ))
diff --git a/stdlib/test/test/lux/macro/template.lux b/stdlib/test/test/lux/macro/template.lux
new file mode 100644
index 000000000..4ff5e683f
--- /dev/null
+++ b/stdlib/test/test/lux/macro/template.lux
@@ -0,0 +1,27 @@
+## 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 (codata [io])
+ (control monad)
+ (data text/format
+ [error #- fail])
+ (math ["R" random])
+ pipe
+ [compiler]
+ (macro ["s" syntax]
+ ["&" template #+ template:]))
+ lux/test)
+
+(template: (hypotenuse x y)
+ (i.+ (i.* x x) (i.* y y)))
+
+(test: "Templates"
+ [x R;int
+ y R;int]
+ (assert "Template application is a stand-in for the templated code."
+ (i.= (i.+ (i.* x x) (i.* y y))
+ (hypotenuse x y))))
diff --git a/stdlib/test/tests.lux b/stdlib/test/tests.lux
index 857d5c25c..e225e1f28 100644
--- a/stdlib/test/tests.lux
+++ b/stdlib/test/tests.lux
@@ -55,20 +55,20 @@
## ["_;" random]
["_;" simple]
)
- ## (macro [ast]
- ## [syntax])
+ ## [macro]
+ (macro ["_;" ast]
+ ["_;" syntax]
+ ["_;" template])
## [type]
+ ## (type [check] [auto])
## (control ...)
)
)
## (lux (codata [cont])
- ## [macro]
- ## (macro [template]
- ## [poly]
- ## (poly ["poly_;" eq]
- ## ["poly_;" text-encoder]
- ## ["poly_;" functor]))
- ## (type [check] [auto])
+ ## (macro [poly]
+ ## (poly ["poly_;" eq]
+ ## ["poly_;" text-encoder]
+ ## ["poly_;" functor]))
## (control [effect]))
)