Details
Description
Current macro macro: syntax is a little unfriendly when it comes to handling and checking arguments.
Either you manually do a lot of manual checks and casting, either you use pattern matching to match arguments, but it is somewhat non-wrist-friendly to do it for simple patterns).
Macro definitions now support arguments definition in a wrist-friendly and intuitive way, including handling of variable number of (optional) arguments.
To match a variable number of arguments use T* (enumerable) notation (e.g 'arg as string*' for a variable number of string arguments).
To match argument type against macro's body, just name the argument `body` (e.g 'body as MethodInvocationExpression*' for allowing only method invocation expressions within the body).
Testcase (and documentation
):
""" the sum of those 6 numbers is 108 foofoo barbar invocation #1 of 2 invocation #2 of 2 Line 'How do you bou?' contains unknown word 'bou'. Did you mean 'boo'? """ import System import Boo.Lang.Compiler.Ast import Boo.Lang.PatternMatching macro sum(numbers as int*): s = 0 for n in numbers: s += n yield [| print "the sum of those ${$(numbers.Count)} numbers is ${$s}" |] macro repeatLines(repeatCount as int, lines as string*): for line in lines: yield [| print $line * $repeatCount |] macro invokeWithCount(body as MethodInvocationExpression*): for invocation in body: invocation.Arguments.Add([| $(body.Count) |]) yield invocation macro spellCheck(lang as string, body as string*): raise "Unknown language `${lang}`" if lang != "en-EN" for line in body: if line.Contains("bou"): yield [| print "line '${$line}' contains unknown word 'bou'. Did you mean 'boo'?" |] sum 4, 8, 15, 16, 23, 42 repeatLines 2, "foo", "bar" invokeWithCount: Console.WriteLine("invocation #1 of {0}") Console.WriteLine("invocation #2 of {0}") spellCheck "en-EN": "Hello boo!" "How do you bou?"
The text misrepresents the way macros are expressed Today. The first macro could be: