Parameters and defaults
Parameters
Every parameter has a name and a type:
macro show_sum(a: int, b: int) {
@emit a + b
}
show_sum 2, 3
5
Arguments are matched to parameters by position. Named arguments like
f(b = 1) are only for constructing structs, not for
calling macros.
Arguments are type-checked
Each argument must already have its parameter’s type. Nothing is converted automatically, even when a conversion exists:
from std.binary import bits
macro emit_byte(b: bits<8>) {
@emit b
}
emit_byte 65
type mismatch for `b`: expected `bits<8>`, found `int`
Convert explicitly with as:
from std.binary import bits
macro emit_byte(b: bits<8>) {
@emit b
}
emit_byte 65 as bits<8>
bits<8> { value: 65 }
Defaults
Parameters at the end of the list can have a default value, used when the call leaves them out:
macro encode(value: int, width: int = 8, mask: int = (1 << width) - 1) {
@emit value & mask
}
encode 0x1ff
encode 0x1ff, 4
255 15
- A default can use earlier parameters. Defaults are evaluated left to right
at each call, so
maskabove sees whicheverwidththe call ended up with. - Once one parameter has a default, every parameter after it needs one too.
Unused parameters
An unused parameter triggers the unused_parameter warning. If it’s unused
on purpose, for example because only its type matters for
overloading, start its name with an underscore:
macro kind(_value: int) {
@emit 1
}
kind 42
1