On this page:
syntax_  meta.error
syntax_  meta.value
syntax_  meta.equal_  binding
syntax_  meta.equal_  name_  and_  scopes
syntax_  meta.flip_  introduce
syntax_  meta.is_  static
Syntax  Phase
syntax_  meta.expanding_  phase
bound_  as
8.12

7.14 Syntax Objects in Macros🔗ℹ

function

fun syntax_meta.error(in_stx :: Syntax)

  :: None

 

function

fun syntax_meta.error(message :: ReadableString,

                      in_stx :: Syntax)

  :: None

 

function

fun syntax_meta.error(message :: ReadableString,

                      in_stx :: Syntax,

                      at_stx :: Syntax || List.of(Syntax))

  :: None

Provided as meta.

Throws a syntax-error message concerning in_stx. If message is not provided, the message is "bad syntax". If at_stx is provided, it should be something like an enclosed form of in_stx to provide extra context. Alternatively, at_stx can be a list of syntax objects, in which case all syntax objects provide extra contexts, least-specific to most-specific.

function

fun syntax_meta.value(name :: Name,

                      in_space :: SpaceMeta = expr_meta.space,

                      fail :: Any:

                        fun (): throw Exn.Fail.Contract(....))

  :: Any

Provided as meta.

Returns the compile-time value of name, if available, in the space specified by in_space. If no compile-time value is available, then fail is called if it is a procedure of 0 arguments, otherwise fail is returned.

The default fail is a procedure that throws an exception.

function

fun syntax_meta.equal_binding(

  stx1 :: Name,

  stx2 :: Name,

  in_space :: SpaceMeta = expr_meta.space,

  phase1 :: SyntaxPhase = syntax_meta.expanding_phase(),

  phase2 :: SyntaxPhase = phase1

) :: Boolean

Provided as meta.

Checks whether stx1 at phase phase1 refers to the same binding as stx2 at phase2 within the space reflected by in_space.

Provided as meta.

Checks whether stx1 and stx2 have the same name (as returned by Syntax.unwrap on an identifier, for example) and the same scopes at phase.

When stx1 or stx2 is a dotted name, then both must be dotted names where each dotted component has the same name and scopes.

Provided as meta.

Returns a syntax object like stx, but where scopes indicating that the syntax object is macro-introduced are flipped. The result is stx unmodified when not during the expansion of a macro.

Macro-introduction is detected by flipping scopes to the input of a macro, then flipping scopes on the macro’s result, so that the two flip operations cancel for any part of the macro’s input that is used in the macro’s output.

A macro can flip introduction to implement a non-hygienic expansion for an introduced identifier. Flipping introduction may also be helpful when syntax is preserved through side channels, or in unusual cases when checking for the originaless of a term with Syntax.is_original.

Check whether the identifier #%dynamism using the scopes of stx is bound to indicate static mode. See use_static for more information.

annotation

SyntaxPhase

Provided as meta.

Matches an integer or #false.

A phase-level integer corresponds to a phase of evaluation, especially relative to the main body of a module. Phase level 0 corresponds to a module’s run time, 1 corresponds to expansion time for run-time forms, and so on. A phase level of #false corresponds to the label phase, like meta_label.

Provided as meta.

Returns the phase of expression forms currently being expanded, or 0 if no expansion is in progress.

unquote binding

bound_as space_expr: 'op_or_id_name'

Provided as meta.

Unquote binding operator for use with $. It matches a syntax object for an identifier or operator, where the identifier or operator’s binding is the same as op_or_id_name in the SpaceMeta reflected by space_expr (e.g., expr_meta.space).

import:

  rhombus/meta open

  rhombus:

    rename + as plus

    expose plus

expr.macro 'simplify($stx)':

  let new_stx:

    match stx

    | '$(a :: Int) $(bound_as expr_meta.space: '+') $(b :: Int)':

        '$(a.unwrap() + b.unwrap())'

    | ~else:

        stx

  'Syntax.literal($new_stx)'

> simplify(1 + 2)

'3'

> simplify(1 plus 2)

'3'

> simplify(1 * 2)

'1 * 2'