10.12. AST pattern matching

AST pattern matching via reverse reification. Matches expressions and blocks against structural patterns using the same tag system as qmacro but in reverse: $e clones a matched expression, $v extracts a constant value, $i extracts an identifier name, $c extracts a call name, $f extracts a field name, $b captures a statement range, $t captures a type, and $a captures remaining arguments.

10.12.1. Enumerations

QMatchError
Values:
  • ok = 0 - Match succeeded.

  • rtti_mismatch = 1 - Expression RTTI type does not match the pattern.

  • field_mismatch = 2 - A named field (name, op, etc.) differs between pattern and expression.

  • const_type_mismatch = 3 - $v extraction failed — expression is not the expected constant type.

  • type_mismatch = 4 - TypeDecl comparison failed — types do not match.

  • list_length = 5 - Block statement count mismatch (after wildcard resolution).

  • wildcard_not_found = 6 - Wildcard could not find a matching statement.

  • null_expression = 7 - A null expression was passed where a non-null was expected.

10.12.2. Structures

QMatchResult
Fields:
  • matched : bool - True if the pattern matched the expression.

  • error : QMatchError - Error code describing why the match failed (ok when matched).

  • expr : Expression? - Pointer to the expression where matching failed (null on success).

10.12.3. Call macros

qmatch_block

Function annotation qmatch_block

qmatch

Function annotation qmatch

qmatch_function

qmatch_function(func, block_pattern) — match function body against block pattern.

10.12.4. Match execution

qm_run(expr: Expression?; blk: block<(var arg:Expression?):QMatchResult>): QMatchResult

Invoke a matching block on the expression. Used internally by the qmatch macro.

Arguments:
qm_run_function(func: FunctionPtr; blk: block<(var body:Expression?;var func_ptr:Function?):QMatchResult>): QMatchResult

Run matching block on a function, passing both body and Function pointer.

Arguments:

10.12.5. Result builders

qm_fail_const(expr: Expression?): QMatchResult

Return a failure — constant type does not match $v extraction target.

Arguments:
qm_fail_field(expr: Expression?): QMatchResult

Return a failure — a named field differs between pattern and expression.

Arguments:
qm_fail_list(expr: Expression?): QMatchResult

Return a failure — block statement count mismatch.

Arguments:
qm_fail_null(): QMatchResult

Return a failure — null expression encountered.

qm_fail_rtti(expr: Expression?): QMatchResult

Return a failure — expression RTTI type does not match the pattern.

Arguments:
qm_fail_type(expr: Expression?): QMatchResult

Return a failure — TypeDecl comparison failed.

Arguments:
qm_fail_wildcard(expr: Expression?): QMatchResult

Return a failure — wildcard could not find a matching statement.

Arguments:
qm_ok(): QMatchResult

Return a successful match result.

10.12.6. Value extraction

10.12.6.1. qm_extract

qm_extract(expr: Expression?; val: float&): QMatchResult

Extract float from ExprConstFloat. Fails if wrong type.

Arguments:
qm_extract(expr: Expression?; val: int&): QMatchResult
qm_extract(expr: Expression?; val: string&): QMatchResult
qm_extract(expr: Expression?; val: bool&): QMatchResult
qm_extract(expr: Expression?; val: double&): QMatchResult
qm_extract(expr: Expression?; val: uint&): QMatchResult
qm_extract(expr: Expression?; val: int64&): QMatchResult

10.12.7. Name and type extraction

qm_call_name_matches(call: ExprCall?; expected_name: string): bool

Check if a call’s name matches, accounting for generic instantiation. When a generic function is instantiated, the call name is mangled (e.g. generic_add`123456). This checks the mangled name first, then falls back to the fromGeneric original name.

Arguments:
  • call : ExprCall?

  • expected_name : string

qm_extract_call_name(expr: Expression?): string

Extract call name from ExprCall. If the call targets a generic instance, returns the original generic name (before mangling).

Arguments:
qm_extract_field_name(expr: Expression?): string

Extract field name from ExprField, ExprSafeField, or variant expressions.

Arguments:
qm_extract_name(expr: Expression?): string

Extract the “name” field from common expression types. Works for ExprVar, ExprCall, ExprField, ExprSafeField, ExprLet variables, etc.

Arguments:
qm_extract_type(expr: Expression?; out_type: TypeDeclPtr): QMatchResult

Extract TypeDeclPtr from ExprTypeDecl.

Arguments:
qm_rtti(expr: Expression const?): string

Return the RTTI type name of an expression.

Arguments:

10.12.8. Argument filtering

qm_count_real_args(args: dasvector`ptr`Variable): int

Count arguments excluding fakeContext and fakeLineInfo.

Arguments:
  • args : vector<Variable*>

qm_count_real_call_args(args: dasvector`ptr`Expression): int

Count call arguments excluding fakeContext and fakeLineInfo expressions.

Arguments:
  • args : vector<Expression*>

qm_extract_remaining_args(args: dasvector`ptr`Variable; from_logical: int; result: array<VariablePtr>)

Collect remaining real arguments (skipping fakeContext/fakeLineInfo) starting from logical index.

Arguments:
  • args : vector<Variable*>

  • from_logical : int

  • result : array< VariablePtr>

qm_is_fake_arg(arg: Expression?): bool

Returns true if the expression is a compiler-injected fakeContext or fakeLineInfo.

Arguments:
qm_real_arg_index(args: dasvector`ptr`Variable; logical_idx: int): int

Map logical argument index (skipping fakeContext/fakeLineInfo) to physical index.

Arguments:
  • args : vector<Variable*>

  • logical_idx : int

qm_real_call_arg_index(args: dasvector`ptr`Expression; logical_idx: int): int

Map logical call argument index (skipping fake args) to physical index.

Arguments:
  • args : vector<Expression*>

  • logical_idx : int

10.12.9. Block scanning

qm_extract_stmts(blk_expr: Expression?; from_pos: int; to_pos: int; result: array<Expression?>)

Extract statements [from_pos, to_pos) from a block into an array (cloned).

Arguments:
qm_scan(blk_expr: Expression?&; pos: int&; len: int; matcher: block<(var elem:Expression?):QMatchResult>): QMatchResult

Scan block statements from pos to len, trying matcher at each position. On first success, update pos to the position after the match and return ok.

Arguments:

10.12.10. Constant construction

qm_make_zero_const(call_name: string): Expression?

Create a zero-value ExprConst for the range first component. range → 0, urange → 0u, range64 → 0l, urange64 → 0ul.

Arguments:
  • call_name : string

10.12.11. AST reconstruction

qm_convert_comprehension(expr: Expression?): Expression?

Reverse generateComprehension: ExprInvoke(invoke, ExprMakeBlock(closure)) → ExprArrayComprehension. Detects the pattern by checking ExprReturn.fromComprehension flag. Returns null if the expression is not a generated comprehension.

Arguments:
qm_convert_local_function(expr: Expression?): Expression?

Reverse generateLocalFunction: ExprAddr → ExprMakeBlock(isLocalFunction=true). Returns null if the expression is not a generated local function.

Arguments:
qm_resolve_comprehension(expr: Expression?): Expression?

If expr is ExprArrayComprehension, shallow-clone it. If ExprInvoke (post-inference comprehension), reconstruct ExprArrayComprehension. Returns null if neither works.

Arguments:
qm_resolve_local_function(expr: Expression?): Expression?

If expr is ExprMakeBlock, clone it. If ExprAddr (post-inference local function), convert back to ExprMakeBlock. Returns null if neither works.

Arguments: