This is much tougher to solve than the other issues with coroutines.
A macro call looks exactly like a regular function call, except that macro calls receive expressions as their arguments instead of the value of the expressions. Macros can also do whatever with those expressions.
While I can simply don't support yield within the coroutines, due to how variables are renamed, macros may not work. For example, this "short lambda" example where fn is a macro:
function():Iterator<Int>
{
var y = 0, z = 0;
fn([x, y] => x + y + z); // undetermined if x, y and z should be mangled or not
}
Variables y and z gets mangled into something like var_y_0 and var_z_1. Without knowing what fn does, it's not possible to tell if the generator builder should rename the y and z variables within the fn call.
A possible solution would be to add a meta to indicate "don't do anything to the next expression". Borrowing from Lisp:
function():Iterator<Int>
{
var y = 0, z = 0;
@quote fn([x, y] => x + y + @unquote z); // quote preserves everything, z gets mangled
}
This is much tougher to solve than the other issues with coroutines.
A macro call looks exactly like a regular function call, except that macro calls receive expressions as their arguments instead of the value of the expressions. Macros can also do whatever with those expressions.
While I can simply don't support yield within the coroutines, due to how variables are renamed, macros may not work. For example, this "short lambda" example where fn is a macro:
Variables y and z gets mangled into something like var_y_0 and var_z_1. Without knowing what fn does, it's not possible to tell if the generator builder should rename the y and z variables within the fn call.
A possible solution would be to add a meta to indicate "don't do anything to the next expression". Borrowing from Lisp: