On this page:
expr
expr_  meta.space
expr.macro
expr_  meta.Parsed
expr_  meta.After  Prefix  Parsed
expr_  meta.After  Infix  Parsed
expr_  meta.parse_  more
expr_  meta.parse_  all
expr_  meta.pack_  s_  exp
expr_  meta.pack_  expr
expr_  meta.pack_  meta_  expr
expr_  meta.pack_  and_  meta_  expr
8.12

7.6 Expression Macros🔗ℹ

space

expr

The space for bindings of identifiers and operators that can be used in expression, definition, and declaration positions.

Provided as meta.

A compile-time value that identifies the same space as expr. See also SpaceMeta.

definition

expr.macro macro_patterns

 

macro_patterns

 = 

macro_case

 | 

 | macro_case

 | ...

 | 

op_or_id_name:

  option; ...

| macro_case

| ...

 

macro_case

 = 

macro_pattern:

  option; ...

  body

  ...

Like macro, but arbitrary compile-time code can appear in the body after each macro_pattern.

If a macro_pattern ends with $() or $id ..., then a match covers all subsequent terms in the enclosing group of a use of the macro. In that case, the body after the pattern can return two values: an expansion for the consumed part of the input match, and a tail for the unconsumed part. Returning a single value is the same as return an empty tail.

The expr.macro form does not define an assignment operator that works with mutable targets. To define an assignment operator, use assign.macro, instead.

syntax class

syntax_class expr_meta.Parsed:

  kind: ~group

  fields:

    group

 

syntax class

syntax_class expr_meta.AfterPrefixParsed(op_name):

  kind: ~group

  fields:

    group

    [tail, ...]

 

syntax class

syntax_class expr_meta.AfterInfixParsed(op_name):

  kind: ~group

  fields:

    group

    [tail, ...]

Provided as meta.

Syntax classes that match by parsing expressions. The value of the binding in each case is an opaque syntax object that represents the parsed expression form, while the group field holds a syntax object for the original terms that were parsed.

The expr_meta.AfterPrefixParsed and expr_meta.AfterInfixParsed syntax classes expect an operator name that is bound as a prefix or infix operator, respectively. Parsing procedes as if immediately after the given operator—stopping when an infix operator of weaker precencence is encountered, for example. The result is in pattern variable’s value plus a tail field that contains the remaining unparsed input.

// an infix `no_fail` that works without a right-hand side

// expression, and that has weak precendence

expr.macro no_fail:

  ~weaker_than: ~other

| '$left no_fail $()':

    'try: $left; ~catch _: #false'

| '$left no_fail $(right :: expr_meta.AfterInfixParsed('no_fail')) $()':

     values('try: $left; ~catch _: $right', '$right.tail ...')

> 1/0 no_fail

#false

> 1/0 no_fail 0

0

> 1/0 no_fail 0 + 1

1

> 1+0 no_fail 0 + 1

1

> (1+0 no_fail 0) + 1

2

Provided as meta.

Similar to matching stx using the syntax class expr_meta.Parsed, but further forces expression parsing to reveal immediate static information from parsing and macro expansion.

function

fun expr_meta.parse_all(group :: Syntax) :: (Syntax, Syntax)

Provided as meta.

Similar to expr_meta.parse_all, but further forces expansion of all nested forms. Avoid this function, and use it only when control over expansion order is absolutely necessary.

Two results are returned: the expanded expression in its normal opaque form, and the expanded expression in an form that can be reused only in the current macro’s expansion context but without a further expansion traversal (which may be necessary to avoid exponential expansion work).

function

fun expr_meta.pack_s_exp(tree :: Any) :: Syntax

Provided as meta.

Converts a tree of terms, which can include parsed terms, into a new parsed term representing a Racket parenthesized form. The intent is that the result is a Racket form to be used in a Rhombus context.

A “tree” is a syntax object or a list of trees (i.e., syntax objects and arbitrary nestings of them within lists). Each syntax object must contain a single term.

Any parsed form as a leaf of tree is exposed directly in the parenthesized sequence, which enables the construction of parsed terms that combine other parsed terms.

> expr_meta.pack_s_exp(['lambda', ['x'], 'x'])

'#{(parsed #:rhombus/expr (lambda (x) x))}'

> expr_meta.pack_s_exp(['lambda', ['x'], expr_meta.pack_expr('x + 1')])

'

  #{(parsed #:rhombus/expr (lambda (x) (rhombus-expression (group x (op +) 1))))}

'

Provided as meta.

Converts a syntax object, which can be a multi-term syntax object, into an parsed term, but one that represents a run-time expression with delayed parsing. The function is intended for use in combination with expr_meta.pack_s_exp.

> expr_meta.pack_expr('x + 1')

'#{(parsed #:rhombus/expr (rhombus-expression (group x (op +) 1)))}'

Provided as meta.

Like expr_meta.pack_expr, but for an expression to be used in a compile-time position or both a run-time and compile-time position.

Although there are cases where expr_meta.pack_and_meta_expr is the right choice, either expr_meta.pack_expr or expr_meta.pack_meta_expr is almost always more appropriate.