17.6 Expression Macros
space | |
value | |
A compile-time value that identifies the same space as expr. See also SpaceMeta.
If a macro_pattern ends with $(), $id ..., a block pattern, or an alternatives pattern, 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.
When a macro_pattern does not end with $() or $id ..., then the result of the body is automatically relocated using Syntax.relocate_ephemeral_span. This relocation is skipped if the result of the body has a #'relocated syntax property.
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 | ||||||
| ||||||
| ||||||
syntax class | ||||||
| ||||||
| ||||||
syntax class | ||||||
|
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
precedes as if immediately after the given operator—
// an infix `no_fail` that works without a right-hand side
// expression, and that has weak precedence
expr.macro no_fail:
~weaker_than: ~other
| '$left no_fail $(right :: expr_meta.AfterInfixParsed('no_fail')) $()':
The expr_meta.NameStart syntax class matches a group that starts with a name, potentially in dotted form. It converts an operator or dotted name into an identifier with the same binding; that identifier or an original one is the name field. The head field contains the terms that were combined to form name, and the tail field contains the remaining terms of the group.
Parses group as an expression and 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 | ||||
|
Dispatches to a dot provider in the same way as .. The left syntax object must represent a parsed expression to the left of ., while op_and_tail contains the operator and rest of the group to parse. The result is two values: a parsed expression that consumes left and part of op_and_tail, and an unparsed remainder of op_and_tail. The result can be #false and #false only when disable_generic is a true value.
To select a specific dot provider, use statinfo_meta.replace to adjust the static information of left, where statinfo_meta.dot_provider_key is the relevant static-information key.
The as_static argument determines whether a dot provider is considered in static or dynamic mode, independent of the mode that would be selected by the operator at the start of op_and_tail.
If no dot provider is found or if a dot provider declines to provide a conversion, then a generic fallback expression is produced unless disable_generic is a true value. Note that a resolution failure (when no dot provider is found) is an error in static mode only when disable_generic is #false.
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))))}
'
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)))}'
function | |
| |
function | |
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.
function | |||||
| |||||
function | |||||
The expr_meta.ends_parse function determines whether parsing for the argument of left_op would end before tail. The end of a parse can be determined by inspecting tail and using expr_meta.relative_precedence, but there are many cases to consider, including an empty tail and a tail that triggers implicit bindings; those cases are handled consistently by expr_meta.ends_parse.