On this page:
macro
macro
macro
8.12

6.54 Simple Expression Macros🔗ℹ

definition

macro macro_case

 

definition

macro

| macro_case

| ...

 

definition

macro op_or_id_name:

  option; ...

| macro_case

| ...

 

expression

macro macro_case

 

expression

macro

| macro_case

| ...

 

entry point

macro macro_case

 

entry point

macro

| macro_case

| ...

 

macro_case

 = 

macro_pattern:

  option; ...

  'template'

 

macro_pattern

 = 

'defined_name $right_parsed_id'

 | 

'defined_name pattern ...'

 | 

'$left_parsed_id defined_name $right_parsed_id'

 | 

'$left_parsed_id defined_name pattern ...'

 

defined_name

 = 

id

 | 

op

 | 

$('$')

 | 

(id_name)

 | 

(op_name)

 | 

()

 

parsed_id

 = 

id

 | 

(parsed_id)

 

option

 = 

~stronger_than other ...

 | 

~stronger_than: other ...; ...

 | 

~weaker_than other ...

 | 

~weaker_than: other ...; ...

 | 

~same_as other ...

 | 

~same_as: other ...; ...

 | 

~same_on_left_as other ...

 | 

~same_on_left_as: other ...; ...

 | 

~same_on_right_as other ...

 | 

~same_on_right_as: other ...; ...

 | 

~associativity assoc

 | 

~associativity: assoc

 | 

~op_stx id

 | 

~op_stx: id

 | 

~all_stx id

 | 

~all_stx: id

 

other

 = 

id

 | 

op

 | 

~other

 

assoc

 = 

~left

 | 

~right

 | 

~none

As a definition form, macro defines the defined_name (which is an operator or identifier) within macro_pattern as a pattern-based macro whose expansion is described by a template. When defined_name is a plain op, it cannot be $, but the form $('$') can be used to define $. A defined_name cannot be () for a macro defintition. The defined_name is bound in the expr space.

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 witin 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 a prefix 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:

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, where ~other stands for any operator not otherwise mentioned. The ~associativity option is allowed only with an infix macro_pattern. 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.

macro 'thunk: $(body :: Block)':

  'fun () $body'

> 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 ...'.

def converter:

  macro '() [$x, ...]':

    'handle_list([$x, ...])'

> 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.