-
Notifications
You must be signed in to change notification settings - Fork 44
Description
The current string-based macros, while powerfull, are also very difficult to actually use (at least in any way that couldn't just be done by a function). My suggestion would thus be to implement a simplified macro syntax which behaves more like Rust's declarative macros.
The idea is that one could write code like this:
macro typed_func = ( ( $( $arg:ident : $type:expr $( = $default_value:expr )? ),* $(,)? ) $arrow:token $body:block ) ->
( $(arg $( = $default_value )? ),* ) $arrow
$(
assert(type($arg) == $type)
)*
$block
--- Usage example:
f = $typed_func((x: "number", y: "number") -> x + y)
--- Expansion:
f = (x, y) ->
assert(type(x) == "number")
assert(type(y) == "number")
x + yNow, it would be very difficult (if not impossible) to actually implement this with the current parser. I would suggest the following solution to that: Whenever the parser hits a macro call, it could be made to parse a very loose subset of the language. It would essentially just need to be able to handle strings and comments - everything else does not get parsed, but read as literal text. Then, the macro gets used to generate new parser rules. Finally, the macro call is parsed with the now-extended parser.
This would by far be the easiest solution, but it would have the downside of requireing parenthesis around the macro's arguments. I would argue that two extra characters are a good tradeoff to make for getting a significantly more useful feature in return.
Alternatively, if the parsing library used by the YueScript compiler supports injecting new rules on-the-fly, parsing could also be done by making each macro definition immediatley modify the parser.