Pattern matcher
koskari.matcher
The pattern matcher behind the special forms, the macros and the match special: the patterns and the special-form composites a shape is declared with, the parsers of the explicit and case-pattern dialects, and the functions that build and try matchers
- class koskari.matcher.APP(extern_name, sub=None)
Bases:
PatternApply the named extern callable to a single source element and match the inner pattern against the call’s result. The extern is invoked through the demand path at match time, so a plain koskari callable works directly; a genuine async suspension raises KoskariSyncViolation, and a raising extractor propagates as an error, not a no-match
- lower(ctx)
Intern the extern, emit the inner pattern, then an APP node
- koskari.matcher.BIND(slot)
Capture any single element into the named slot
- class koskari.matcher.BINDING(slot)
Bases:
CompositeCapture a single binding-shaped cell, (NAME EXPR) or (EXPR as: NAME). After a successful match captures[slot] is a dict (the GROUP’s captures) or
DatumFramewithnameandexpras produced by binding_inner_pattern. For KosPair-backed subjects the whole binding cell spine is.sourceonDatumFrame
- class koskari.matcher.BINDINGS(slot)
Bases:
CompositeCapture a binding-list cell: a single element which is either nil or a proper list of binding-shaped cells. The nonempty arm uses repeat_capture so captures[slot] is a bare Python list of per-cell frame dicts (same keys as
BINDING:name,expr), not Datum-wrapped; the empty arm matches nil and binds captures[slot] = nil (a Datum in the usual CAPTURE sense). The two arms share an outer slot name through ONEOF’s per-branch capture scoping
- class koskari.matcher.BODY(slot)
Bases:
PatternRemainder capture of a slot holding the forms a body evaluates. Lowers to the same
RESTnode asREST(slot, min_tail=1)(minimum one spine cell in the body tail); the spelling records the slot’s role- lower(ctx)
Emit
RESTwithmin_tail=1
- class koskari.matcher.CALLEDBY(slot=None)
Bases:
CompositeCapture the compile-head symbol into the called-by slot
- class koskari.matcher.CAPTURE(slot, sub=None)
Bases:
PatternBind one matched element (or a sub-pattern result) into a named slot
- lower(ctx)
Reserve the slot, lower the optional sub-pattern, and emit the CAPTURE node
- class koskari.matcher.CLASS(type_extern, *fields)
Bases:
PatternMatch a single element which is an instance of the named extern type. Field children project named or positional attributes through sub-patterns
- lower(ctx)
Emit each FIELD child then a CLASS node referencing them. Toggles ctx.in_class_fields so that nested CLASS/FIELD trees validate correctly. The CLASS extern is interned before recursing into fields so that the externs tuple reflects source declaration order
- class koskari.matcher.DECL(slot)
Bases:
CompositeCapture one element shaped as a declaration: a bare symbol, a one-element list naming the symbol, the (type as: name) form, or a (name . tail) form where tail captures the keyword attribute pairs verbatim. After a successful match captures[slot] is a dict (the GROUP’s captures) or
DatumFramefor KosPair-backed subjects. Keys includenamewhere applicable,typefrom the as-form,decl_tailfrom the dotted tail arm; other keys are omitted. The whole declaration cell spine is available as.sourceonDatumFrameresults (not a dict key)
- class koskari.matcher.DEFINE(slot)
Bases:
CompositeCapture one element constrained to be a symbol. Used as the introduced-name slot for define-shaped specials
- class koskari.matcher.FIELD(sub, *, name=None)
Bases:
PatternProject a single attribute of a CLASS instance through an inner pattern. Positional when name is None, keyword otherwise
- lower(ctx)
Emit a FIELD_POS or FIELD_KW node. Rejects emission outside a CLASS scope. Temporarily clears in_class_fields so that the sub-pattern can host its own CLASS/FIELD nesting
- class koskari.matcher.FORM(sub)
Bases:
PatternDescend into a single source element treated as a pair-tree and apply the inner pattern against its contents
- lower(ctx)
Emit the inner pattern then a FORM node referencing it
- class koskari.matcher.FORMALS(slot)
Bases:
CompositeCapture one element shaped as a proper-list formals cell and decompose its structure into a nested capture dict. Improper-list formals are rejected because koskari does not allow them as a function-formals shape. After a successful match captures[slot] is a dict (the GROUP’s captures) or
DatumFramewhose keys include:‘positionals’: bare Python list of frame dicts (one per positional formal)
‘defaults’: bare Python list of frame dicts (one per default keyword/value)
‘kwonly’: bare Python list of frame dicts (one per kw-only entry)
‘starstar’: the symbol after **:
Inner keys for phases that did not run are omitted from the group dict. For KosPair-backed subjects the whole formals list spine is
.sourceonDatumFrame. Use one FORMALS per matcher
- class koskari.matcher.GROUP(slot, *children)
Bases:
PatternNested capture frame: inner captures go into a sub-dict. The GROUP node has no slot; when
slotis a non-empty str this pattern lowers toCAPTURE(slot, GROUP(children...))so naming stays on CAPTURE only. Whenslotis None the sub-dict is matched and then discarded unless a parent CAPTURE or REPEAT row collects it- lower(ctx)
Emit a slot-free GROUP node; when named, wrap with CAPTURE so the slot is claimed only on the outer CAPTURE
- koskari.matcher.KEYWORD(slot)
Capture a keyword element into the named slot; keyword is a core type, tested with no extern
- koskari.matcher.LIST(*specs, key=None)
Match a single source element which is a list whose contents satisfy the given specs in order. When key is given the matched sub-list is also captured into that slot
- class koskari.matcher.LITERAL(value)
Bases:
PatternMatch a single element equal to the given literal value
- lower(ctx)
Intern the literal in consts and emit a TEST/LITERAL node
- koskari.matcher.LITERAL_KW(s)
Match a keyword equal to keyword(s)
- koskari.matcher.LITERAL_SYM(s)
Match a symbol equal to symbol(s)
- class koskari.matcher.MAP(*entries)
Bases:
PatternMatch a single element as a mapping (dict or collections.abc Mapping): every entry’s key must be present with a value matching the entry’s sub-pattern. Extra keys are ignored, per PEP 634 mapping-pattern semantics
- lower(ctx)
Emit each entry then a MAP node chaining them
- class koskari.matcher.MAP_ENTRY(key, sub=None, extern=False)
Bases:
objectOne mapping-pattern entry: a key plus an optional sub-pattern for the looked-up value. The key is a literal constant, or – when
externis true – an extern name resolved from the namespace at match time (the same channel as TYPE / CLASS names). Not a Pattern: only meaningful as a child of MAP- lower(ctx)
Intern the key, emit the sub-pattern, then a MAP_ENTRY node
- class koskari.matcher.MATCH(*children)
Bases:
PatternSequential spine: match children in order in the current capture dict
- lower(ctx)
Emit each child then a MATCH node listing them in order
- class koskari.matcher.NOT(sub)
Bases:
PatternNegative lookahead: succeed when the inner pattern does not match the current single element. Width 1 with no captures inside
- lower(ctx)
Emit the inner pattern then a NOT node referencing it
- class koskari.matcher.ONEOF(*branches)
Bases:
PatternDisjunction: try each branch in order until one matches
- lower(ctx)
Emit each branch then a ONEOF node listing them in order. Each branch gets its own capture scope so identical slot names across mutually exclusive arms remain valid
- class koskari.matcher.OPTIONAL(sub)
Bases:
PatternMatch the inner pattern at most once. When the inner pattern does not match, any capture slots it would have bound are omitted from the result captures dict
- lower(ctx)
Emit the inner pattern then an OPTIONAL node referencing it
- koskari.matcher.PAIR(slot)
Capture a pair element into the named slot; pair is a core type, tested with no extern
- class koskari.matcher.PREDICATE(extern_name)
Bases:
PatternMatch a single element for which the named extern callable returns a truthy value
- lower(ctx)
Intern the extern and emit a TEST/PREDICATE node
- class koskari.matcher.Pattern(*args, **kwargs)
Bases:
ProtocolStructural base for matcher pattern builders. Implementations define lower(ctx); the compiler passes itself as ctx when lowering a root pattern. GROUP and ONEOF bracket nested lowering with begin_nested_claims and end_nested_claims. build lowers through TableBuilder and compiles the matcher function
- build(externs=None)
Compile this pattern to its matcher function: one positional formal, the subject; the captures on a match, None on a miss. Its externs are closure names resolved in a namespace whose builtins are the externs mapping
- Parameters:
externs – the extern names mapped to their values, or None
- Raises:
TypeError – when a LITERAL value or a MAP entry key is not one the constant pool holds, or an extern the pattern declares is not given
ValueError – when the pattern is one the core refuses
- Return type:
- lower(ctx)
Append nodes for this pattern into the compiler context and return the index of the resulting top node
- class koskari.matcher.REPEAT(sub, min_count=0)
Bases:
PatternGreedily match the inner pattern repeatedly; require at least
min_countsuccessful iterations (default 0: Kleene star)- lower(ctx)
Emit the inner pattern then a REPEAT node referencing it
- class koskari.matcher.REST(slot=None, min_tail=0)
Bases:
PatternConsume the remainder of the current spine subject.
min_tailis the minimum number of spine cells this REST must take (default 0). Whenslotis set, lowering emitsCAPTURE(slot, REST(...))so only CAPTURE carries the slot- lower(ctx)
Emit REST with min_tail only; when named, wrap with CAPTURE
- class koskari.matcher.SAME(slot, depth=0)
Bases:
PatternMatch one element equal to an earlier capture of this frame: the root, or the GROUP or REPEAT iteration the SAME sits in, at depth 0; the enclosing frame at depth 1
- lower(ctx)
Emit a SAME node referencing an existing slot index
- koskari.matcher.SYMBOL(slot)
Capture a symbol element into the named slot; symbol is a core type, tested with no extern
- class koskari.matcher.TEST_ANY
Bases:
PatternMatch any single element
- lower(ctx)
Emit the TEST_ANY node tuple
- class koskari.matcher.TYPE(extern_name)
Bases:
PatternMatch a single element which is an instance of the named type: a core type by its ordinal, any other name as an extern, a variable of the code the pattern runs in
- lower(ctx)
Emit a TEST/CORE node for a core type, else intern the extern and emit a TEST/TYPE node
- class koskari.matcher.USING(slot)
Bases:
CompositeCapture one element shaped as a using-form. Four inner shapes are recognised through an ordered ONEOF; first match wins:
(EXPR as: NAME) – as form, captures expr and name
((PATTERN…) EXPR) – unpack form, captures lhs and expr
(NAME EXPR) – named binding, captures name and expr
(EXPR) – bare expression, captures expr only
The as form comes first: a two-element shape is committed to once it matches, and the as form’s three elements skip it on a two-element cell
After a successful match captures[slot] is a dict (the GROUP’s captures) or
DatumFramewith whichever oflhs,name,exprthe winning arm binds. For KosPair-backed subjects the whole cell spine is.sourceonDatumFrame
- class koskari.matcher.USING_UNPACK(slot)
Bases:
CompositeCapture
((PATTERN...) EXPR)for unpack bindings (e.g. for-each). After a successful match captures[slot] is a dict (the GROUP’s captures) orDatumFramewithlhsandexpr. For KosPair-backed subjects the whole cell spine is.sourceonDatumFrame
- class koskari.matcher.VALUE(slot)
Bases:
PatternSingle-element capture of a slot holding an expression the form evaluates. Lowers to the same
CAPTUREnode asBIND(slot); the spelling records the slot’s role- lower(ctx)
Emit
CAPTURE
- koskari.matcher.check_pattern_arg(arg, what)
Validate that arg is a Pattern instance and raise a clear TypeError when it is not
- koskari.matcher.first_match(subject, callables)
- koskari.matcher.frame_formal_name(fr)
Resolve one positional formal frame to (name, by_ref).
The binding symbol lives under ‘ref_name’ for the (ref x) and (ref x) by-ref shapes. Otherwise it lives under ‘name’; a ‘name’ carrying a leading & is the reader-disabled by-ref fallback and is stripped. A keyword-headed cell such as (y: 1 :: int) names the parameter under ‘kw’ and the symbol that keyword spells is returned; a leading & on the keyword marks it by-ref. The returned name is the raw symbol (Datum-unwrapped) or None
- koskari.matcher.make_matcher(pattern, externs=None)
Compile a pattern AST to its matcher function, as
Pattern.build()does
- koskari.matcher.parse_case_pattern(content)
Lower the content of one match/case clause delimiter to a matcher pattern object. The delimiter ([[PATTERN] BODY…]) holds either a single pattern form, or the multi-token spelling of a marked typed pattern (x :: int); a bare multi-token content is an error – it is never a silent sequence
- Parameters:
content – the delimiter list (pair-tree)
- Return type:
- koskari.matcher.parse_explicit_rule_pattern(form, source_ctx=None)
Lower MATCH-dialect pattern source (a cons tree) to a matcher Pattern.
Distinct from
parse_matcher(), which lowers a single META element. This walks a rule-level spine: either a registered declaration(HEAD slot . opts)whenHEADis inMATCHER_REGISTRYandslotis a symbol, or a sequentialMATCHof per-cell patterns.- Parameters:
form – koskari pattern datum
source_ctx – optional value appended to error messages
- Returns:
Pattern instance (often
MATCHwrapping a sequence)- Raises:
ValueError – on ellipsis, improper lists, empty cells, or factory failures
- koskari.matcher.pattern_slot_names(pattern)
Top-level macro lambda formals for
patternin declaration orderSlots nested inside anonymous GROUP / REPEAT row frames are omitted; ONEOF branch captures and spine MATCH slots are included
- koskari.matcher.repeat_capture(slot, inner)
Capture the results of repeating inner across successive subject elements. captures[slot] is a Python list: each element is one iteration result (often a dict for a GROUP row dict, or a sparse change dict / Datum when inner does not use that shape)
- Parameters:
slot – outer slot receiving the list of per-iteration values
inner – pattern run once per repetition (often FORM around a MATCH of captures)
- Return type: