11.3 Simple Expression Macros
definition | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
definition | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
definition | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
expression | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
expression | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
entry point | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
entry point | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
As an expression or entry point, macro is a shorthand for a function that expects a syntax object to match, as explained further below. The expr.macro form is similar to macro; it allows more general compile-time code, but it also requires that rhombus/meta is imported.
For a macro defined with macro, macro_pattern is matched to a sequence within a group. Within the '…' of each macro_pattern, either the first term is a defined_name to be defined as a prefix macro, or the first term is a single $ escape followed by a defined_name to be defined as an infix macro.
In the case of an infix macro, the left-hand $ escape must be an identifier. It stands for a match to preceding terms that have been parsed as an expression, and the identifier is bound to an opaque representation of the expression. The right-hand side of the macro (for either a prefix or infix form) can be either $ followed by an identifier or an arbitrary pattern:
When the right-hand side is $ followed by an identifier (optionally parenthesized), then the macro is applied with an already-parsed term after the macro name in a use of the macro. That parse heeds precedence and associativity declarations for other macros and for operators defined with op.
Otherwise, the right-hand side is an arbitrary pattern that is matched to a sequence of terms after the macro name in its enclosing group. Unless the pattern ends with $(), a block pattern, or an alternatives pattern, the use of the macro can be followed by additional terms in the same group. If the pattern ends with $(), a block pattern, or an alternatives pattern, then all terms after the macro operator must match the right-hand pattern. The position before $() is itself treated as a group position.
Using | alternatives, a single definition can have any number of macro_patterns. The patterns describe any number of prefix and infix variants that are (presumably) distinguished by patterns that are tried in order. The name to define must be the same across all macro_patterns. If the right-hand side in a macro_pattern of an infix or prefix form implies a parsed match, then it must be the only infix or prefix macro_pattern among the alternatives.
The body after each macro_pattern must be an immediate '…' template, and any $ escape within the template can only refer to an input pattern variable or a literal syntax object, optionally parenthesized, or an operator (e.g., $('$') to generate a literal $). More general compile-time expressions are not allowed; use expr.macro or expr.macro, instead, to enable compile-time expressions.
Before the template body of a macro_pattern, option keywords can appear. The options ~weaker_than, ~stronger_than, ~same_as, ~same_on_left_as, and ~same_on_right_as declare an name’s precedence relative to other names or operator orders, where ~other stands for any operator not otherwise mentioned. The ~associativity option is allowed only with an infix macro_pattern. The ~order option selects a operator order for the operator, which defines precedence relationships to other operator orders and a default associativity, but precedence and associativity options within macro override the ones defined with the operator order. The ~op_stx option binds an identifier to an identifier or operator syntax object as it appears in a use of the macro (which cannot be matched directly in the macro_pattern, since that position is used for the name that expr.macro binds). The ~all_stx option binds an identifier to the input that is matched by the macro_pattern, which includes the identifier or operator that ~op_stx would capture. In a definition with | alternatives, most options are allowed only in the first case, but ~op_stx and ~all_stx are allowed and separate in each case.
When multiple cases are written with |, they can appear after a block that supplies options that apply to all cases, the same as in operator.
> thunk: "ok"
#<function:fun>
> (thunk: "ok")()
"ok"
An expression or entry-point macro describes a function that takes a syntax object and returns two syntax objects: the results produced by template and the tail of an enclosing group that follows the match to pattern. The defined_name position must be (), the pattern form must be a prefix (not infix) pattern, and the only allowed options are ~op_stx and ~all_stx. For the purpose of matching a syntax object passed to the function produced by macro, the leading () in each pattern is replaced by _. In addition, unless the pattern ends with $() or $id ..., a $tail ... pattern is added to the end; and the result values are the syntax object produced by template and '$tail ...'.
> converter('ListLike[1, 2, 3].more')
'handle_list ([1, 2, 3])'
'. more'
The macro form does not define an assignment operator that works with mutable targets. To define an assignment operator, use assign.macro, instead.