Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
160 commits
Select commit Hold shift + click to select a range
d61aac1
XL-2 hotfix: call arguments lower as values, so nested-call and recor…
Sep 23, 2026
52529ce
XL-2 hotfix: a match scrutinee is read as a value, so a call scrutine…
Sep 23, 2026
f600d8c
Merge remote-tracking branch 'origin/main' into session/fierce-hawk-2…
Sep 23, 2026
8c6781b
Merge remote-tracking branch 'origin/main' into session/fierce-hawk-2…
Sep 23, 2026
fbea0da
Merge branch 'session/fierce-hawk-274-call-arg-read' of https://githu…
Sep 24, 2026
f813dd9
Fix-forward #12145: operator-operand fallback and function-value argu…
Sep 24, 2026
6f6839a
Match: the scrutinee's accepted diagnostics are merged into the match…
Sep 24, 2026
31fc9e7
RFM row: the whole-route diff's driver rows carry no locus (receipt f…
Sep 24, 2026
e71710b
value_position_whole_read: shape claims read calls through v2.std.nod…
Sep 24, 2026
da4f5aa
Merge remote-tracking branch 'origin/main' into session/silent-dove-314
Sep 24, 2026
ee53a8a
Operator-operand local discriminator (call operand under ==, whole); …
Sep 24, 2026
ffe1c42
MQ-1: list literals lower whole as their free-monoid construction thr…
Sep 24, 2026
ef9f12a
Operator-operand discriminator uses a parenthesised call operand, the…
Sep 24, 2026
bc28a4b
Merge origin/main (#12173 landed) into session/silent-dove-314
Sep 24, 2026
8fc9f27
Lambda-argument claims assert RESOLVE (parameter in scope) and an und…
Sep 24, 2026
1b5a0d7
reference_conservation: the list-literal control passes its list posi…
Sep 24, 2026
4ab6497
Drop the lambda-argument carry (both resolve claims stay red with it)…
Sep 24, 2026
2544f26
Merge session/silent-dove-314 (#12198 head: lambda carry dropped, #12…
Sep 24, 2026
65205e3
MQ-1: a lambda in value position lowers to the Arrow a named fn lower…
Sep 24, 2026
a885b7a
Merge origin/main (#12198 landed) into MQ-1; #12198's files take main…
Sep 24, 2026
06140d2
Match lowering: keep main's landed scrutinee diagnostics arm (a #1219…
Sep 24, 2026
54d56d5
Merge origin/main (#12194 landed) into MQ-1: list claims read reached…
Sep 24, 2026
9c3afa4
MQ-1: the list-literal heads name std.algebra, where FreeMonoid is de…
Sep 24, 2026
ad29f84
Typed empty binder list (seed can't type a bare []); one function-val…
Sep 24, 2026
d0366e4
fn(..){..} literals in value position lower through the one function-…
Sep 24, 2026
6350074
Self-host behavioral shims follow list_snoc_item to std.algebra: one …
Sep 24, 2026
66b757d
Acceptance repro: the seven's token_stream wall (fn literal in a matc…
Sep 24, 2026
997292b
A nested function value is a scope boundary for body lowering's deep …
Sep 24, 2026
a17fda6
Function values are deferred: their interior reaches the function-val…
Sep 24, 2026
464ae26
MQ-1: list literals lower FLAT -- one Transform headed by the std.alg…
Sep 24, 2026
60f99cd
infer FreeMonoid introduction: match the Optional<Outcome> in two sin…
Sep 24, 2026
851ee4e
RFM accepted_source_emits_uncompilable_target: occurrence -- a field …
Sep 24, 2026
2531409
Floor reds on #12208: repoint doc_graph_roots' list_snoc_item citatio…
Sep 24, 2026
fb7600f
Merge remote-tracking branch 'origin/session/lively-koi-275' into ses…
Sep 24, 2026
fe0874d
Merge #12208 head and main (#12217 type-parameter binders); an unwrit…
Sep 24, 2026
d851c27
RFM receipt: the lambda frontier closes
Sep 24, 2026
288d00f
list_literal_value_lowering: llv_self_report renders the self-referen…
Sep 24, 2026
c6189e7
Merge remote-tracking branch 'origin/main' into session/lively-koi-275
Sep 24, 2026
bd61495
Merge origin/main (#12217 type-parameter binders) into MQ-1; the std.…
Sep 24, 2026
8e3198a
One reader of the two function-value productions (fold_lowering funct…
Sep 24, 2026
a2ed3ab
Merge origin/main into MQ-1 (keep both occurrence receipts on accepte…
Sep 24, 2026
9c83abe
One authority for the list-literal introduction (review 70960): v2.st…
Sep 24, 2026
976632e
infer_list_introduction: ilt_report renders each case's infer outcome…
Sep 24, 2026
13d1e2b
infer_list_introduction: the empty-list claim requires an ACCEPTED in…
Sep 24, 2026
0fbfca8
Seed typecheck: typed Optional constructors in fold_lowering's if-arm…
Sep 24, 2026
250c723
Merge #12208 head (one list-introduction authority) into MQ-1
Sep 24, 2026
7509978
Claim readers the seed types: domain via node_positional_child_target…
Sep 24, 2026
2b8c764
Merge branch 'fg556-merge-scratch' into session/fierce-gull-556
Sep 24, 2026
7f7618d
Shared list reader: read the head through list_at_optional over node_…
Sep 24, 2026
7002fe4
Merge remote-tracking branch 'origin/main' into session/lively-koi-275
Sep 24, 2026
371cc62
Merge origin/main (#12228 landed): repoint body_producer_forward's ne…
Sep 24, 2026
9a82ce0
Shared list reader: elements are skip(targets, 1) -- no empty list li…
Sep 24, 2026
c56480c
A let-bound function value lowers whole (the operand reader narrowed …
Sep 24, 2026
801be8c
Merge remote-tracking branch 'origin/session/lively-koi-275' into ses…
Sep 24, 2026
cdabcf7
infer list introduction under #12220's marked references: the supplie…
Sep 24, 2026
92d854c
std.algebra self-reference fixture: a non-generic FreeMonoid, because…
Sep 24, 2026
34784ef
Revert "std.algebra self-reference fixture: a non-generic FreeMonoid,…
Sep 24, 2026
0d91e5c
Enrol std_algebra_own_list_literals_bind_to_its_own_qualified_names e…
Sep 24, 2026
70c99db
Merge #12208 head (std.algebra self-reference expected-red) into MQ-1…
Sep 24, 2026
b39e17f
Mutation control asserts the whole [f, g, h] present and every proper…
Sep 24, 2026
f54e798
Merge origin/main into MQ-1 (keep both occurrence receipts on accepte…
Sep 24, 2026
64d37c4
Trigger CI
Sep 24, 2026
2892a87
Merge origin/main into MQ-1 (expected-red chunk list: keep both #1223…
Sep 24, 2026
c098158
Merge origin/main into MQ-1 (fn-literal expected-red chunk kept until…
Sep 24, 2026
a068158
Merge #12208 head into MQ-1; lambda chunk stays retired, fn-literal c…
Sep 24, 2026
7ab4e6e
Side-chat on #12208 (1)+(2): list element types unify through the str…
Sep 24, 2026
5e4d719
infer_list_introduction: typed optional helpers in the new readers (f…
Sep 25, 2026
fd8c238
Fresh type variables are synthetic (no authored occurrence under a ne…
Sep 25, 2026
fba3514
RFM receipt: the wildcard residue is a second '_' only; the builtin f…
Sep 25, 2026
52c56a8
Merge remote-tracking branch 'origin/session/lively-koi-275' into ses…
Sep 25, 2026
c196170
self_host_03_normalize declared-source completeness is an identity jo…
Sep 25, 2026
6986e5b
WIP: positional fold step
Sep 25, 2026
a8e46de
Merge remote-tracking branch 'origin/session/fierce-gull-556' into se…
Sep 25, 2026
3ed35fe
Transport roster: body_producer's supplementary claim-run names struc…
Sep 25, 2026
f6c5895
MQ-1: a positional fold step lowers like the named form
Sep 25, 2026
efaaf7f
fold_lowering claims: share one front end through flp_outcomes (warm)
Sep 25, 2026
1c49c1b
Merge origin/main into MQ-1: type parameters ride v2.std.type_binder'…
Sep 25, 2026
49d2df9
fold_lowering claims: well_formed_fold_still_lowers_through_the_split…
Sep 25, 2026
cc877b0
Merge remote-tracking branch 'origin/session/fierce-gull-556' into se…
Sep 25, 2026
0ce02be
Merge origin/main (MQ-4 typed wrapper retention, XL-2 bound value) in…
Sep 25, 2026
a8f13df
Merge origin/main into MQ-1 (#12205 unimported-bare-provider rule, #1…
Sep 25, 2026
123f2ad
Merge remote-tracking branch 'origin/session/fierce-gull-556' into se…
Sep 25, 2026
e164aed
Merge #12208 head (main merged there) into MQ-1
Sep 25, 2026
3958f48
Resolve the leftover import conflict marker from the #12208 merge
Sep 25, 2026
b74d700
Merge remote-tracking branch 'origin/session/fierce-gull-556' into se…
Sep 25, 2026
d990cde
required_floor_runner: read UnimportedBareProviderBaseRoster as the c…
Sep 25, 2026
467c6f9
Merge origin/main into MQ-1 (#12270, #12226): v2_native_route keeps m…
Sep 25, 2026
104737c
A function value as an Arrow's whole body refuses located at the inne…
Sep 25, 2026
38a3ddc
Merge remote-tracking branch 'origin/session/fierce-gull-556' into se…
Sep 25, 2026
63b2c46
Merge origin/main into MQ-1 (ledger receipts kept; native_route impor…
Sep 25, 2026
fb379fc
Merge remote-tracking branch 'origin/session/fierce-gull-556' into se…
Sep 25, 2026
45aac86
Merge #12208 head into MQ-1 (ledger receipts in #12208's order)
Sep 25, 2026
71b7580
fold-callee expected-red: OWNER is MQ-5 via gunbc#12272 (review 71205)
Sep 25, 2026
8ff6368
Retire the std.algebra self-reference expected-red row: #12240 (type …
Sep 25, 2026
dfbae61
Merge #12208 head (std.algebra self-reference row retired) into MQ-1
Sep 25, 2026
ec28776
RFM cost-shape row: a producer re-enters a general subtree walker and…
Sep 25, 2026
c0c9e3e
Merge origin/session/fierce-gull-556 (keep the restated fold-seam row)
Sep 25, 2026
f19bbcc
Merge origin/main (floor runner: take #12278's base-roster coproduct …
Sep 25, 2026
461e76a
Merge origin/main into MQ-1 (#12278 landed): required_floor_runner.rs…
Sep 25, 2026
43fe925
function_value_body claim: import SubstrateInputsOnly (unimported-bar…
Sep 25, 2026
8f26d36
Merge remote-tracking branch 'origin/session/fierce-gull-556' into se…
Sep 25, 2026
6713e4b
Cost-shape row: the counts do not confirm the re-entry hypothesis; th…
Sep 25, 2026
fcbb4f9
Merge remote-tracking branch 'origin/session/fierce-gull-556' into se…
Sep 25, 2026
5226a58
Merge remote-tracking branch 'origin/main' into session/merry-hawk-532
Sep 25, 2026
2508815
function_value_body: one warm pure producer (fvb_outcomes) for both v…
Sep 25, 2026
fafbd6b
Merge remote-tracking branch 'origin/session/fierce-gull-556' into se…
Sep 25, 2026
2ff34c0
Merge origin/main (#12248) into MQ-1: a fn literal's return type is c…
Sep 25, 2026
fd859a8
Merge remote-tracking branch 'origin/session/fierce-gull-556' into se…
Sep 25, 2026
7e0f8fe
Merge origin/main into MQ-1 (#12250, #12261, #12248, #12286, #12244, …
Sep 25, 2026
d34cb0a
swift_decl (#12267): list_append from std.algebra
Sep 25, 2026
4b55bdf
Merge origin/main (keep both occurrence receipts on accepted_source_e…
Sep 25, 2026
8365804
Merge origin/main (#12202 landed) into MQ-1, and a list introduction …
Sep 25, 2026
eacd30e
Merge origin/main (MQ-2/3 call-reader cutover) into MQ-1: imports as …
Sep 25, 2026
c06bff7
Merge #12208 head into MQ-1 (#12208's resolutions of its own files)
Sep 25, 2026
fb58545
Merge origin/main (#12287) into MQ-1: node_query keeps main's map imp…
Sep 25, 2026
56a00a6
Repoint two new consumers from main (skeleton_call_route_witness, bod…
Sep 25, 2026
817288e
Merge origin/session/fierce-gull-556 (ledger: take its union of recei…
Sep 25, 2026
7b749de
Merge origin/main (#12287) into MQ-1: node_query imports as the union
Sep 25, 2026
8308aac
Merge remote-tracking branch 'origin/session/fierce-gull-556' into se…
Sep 25, 2026
52aaca2
btar fn-literal claims: one warm pure producer (btar_fn_literal_outco…
Sep 25, 2026
57c8ce4
Rename the grammar-level function-literal body sum to FunctionLiteral…
Sep 25, 2026
4c0f706
Function values lower once, through their own slots: the fold lowers …
Sep 25, 2026
19275a2
Cost-shape row: confirmed on the native route, located (nested fn-lit…
Sep 25, 2026
1da6504
Merge remote-tracking branch 'origin/session/fierce-gull-556' into se…
Sep 25, 2026
a033fa1
Merge origin/main into MQ-1 (#12275 deleted the self-host hand shims;…
Sep 25, 2026
c5cd45b
Merge remote-tracking branch 'origin/session/lively-koi-275' into ses…
Sep 25, 2026
e3f20b6
Merge remote-tracking branch 'origin/session/fierce-gull-556' into se…
Sep 26, 2026
1e780e2
Delete .regen.sh: a hand-written regen loop swept into the #12208 mer…
Sep 26, 2026
7f35fae
Merge remote-tracking branch 'origin/session/fierce-gull-556' into se…
Sep 26, 2026
1f4bae6
Merge origin/main (dag.dag imports: main's any, list helpers stay on …
Sep 26, 2026
4ca672b
Cost-shape row: the native acceptance rerun passed (54 target_model c…
Sep 26, 2026
82375c4
Merge origin/main (#12208 landed) into MQ-1: dag.dag imports take mai…
Sep 26, 2026
66683f9
Merge origin/main (#12208 landed): expected-red chunk list and warm-p…
Sep 26, 2026
90737ce
Function-value domains mint anonymous slots through the shared anonym…
Sep 26, 2026
798f15c
Merge origin/main (#12299 value carry deleted; #12364 #12258 #12227) …
Sep 26, 2026
a6c348f
Merge origin/session/fierce-gull-556 (main through b1b7aea9aa): keep …
Sep 26, 2026
50f7bac
std_algebra.rs: regenerate the stage0 mirror over main's #12227 (coun…
Sep 26, 2026
a3c1899
floor_expected_red: restore main's retired chunk_15 (Empty) that a wh…
Sep 27, 2026
8a0def6
Merge remote-tracking branch 'origin/main' into session/merry-hawk-532
Sep 27, 2026
0d3c75e
Fresh type variables are minted by structural path (v2.std.anonymous_…
Sep 27, 2026
327ee63
Merge origin/main (#12373, #12375): resolve per hunk. body_lowering_f…
Sep 27, 2026
b88af22
Merge origin/main (#12373 #12375 #12378, let annotation carried) into…
Sep 27, 2026
05a9ed8
Merge origin/session/fierce-gull-556 (b88af22, mirrors the #12373/#12…
Sep 27, 2026
5dd333f
Merge remote-tracking branch 'origin/main' into session/merry-hawk-532
Sep 27, 2026
d539148
Delete the uncalled is_fresh_type_variable (review 71732, §3c dangling)
Sep 27, 2026
4debb03
Merge remote-tracking branch 'origin/session/fierce-gull-556' into se…
Sep 27, 2026
cb4254c
Merge remote-tracking branch 'origin/main' into session/merry-hawk-532
Sep 27, 2026
1bbf1c3
A function value's renaming is decided by construction (equality with…
Sep 27, 2026
18ad80a
Merge remote-tracking branch 'origin/session/fierce-gull-556' into se…
Sep 27, 2026
6f0ff77
Function-value accumulators snoc instead of list_append: the signatur…
Sep 27, 2026
61a66c5
Merge remote-tracking branch 'origin/main' into session/fierce-gull-556
Sep 27, 2026
4371fc7
Merge remote-tracking branch 'origin/session/fierce-gull-556' into se…
Sep 27, 2026
234f06e
A fold-family call taken on its raw node admits its arguments before …
Sep 27, 2026
9c6cb63
Merge remote-tracking branch 'origin/session/fierce-gull-556' into se…
Sep 27, 2026
5b860f6
Merge remote-tracking branch 'origin/main' into session/merry-hawk-532
Sep 27, 2026
21ea6bd
Merge remote-tracking branch 'origin/main' into session/fierce-gull-556
Sep 27, 2026
619f483
Merge remote-tracking branch 'origin/session/fierce-gull-556' into se…
Sep 27, 2026
28aa3d5
The positional-order control's lambda gets its own callee, so the two…
Sep 27, 2026
0359c9a
Merge remote-tracking branch 'origin/session/fierce-gull-556' into se…
Sep 27, 2026
e2f97bb
Merge remote-tracking branch 'origin/main' into mh532
Sep 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 33 additions & 2 deletions dag/std/algebra.dag
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,37 @@ fn collection_filter_shape() -> AlgebraFieldTemplate {
{ name: "filter", param_types: [ReceiverSelf, CallableOf { params: [ReceiverElement], return_type: NamedTemplate { name: "Bool" } }], return_type: ReceiverSelf, size_effect: Present { value: IdentityEffect }, cost_shape: Present { value: ShapeIterateBody }, callback_element_position: Present { value: 0 } }
}

// Collection fold is this one template, declared once for both collection profiles that carry it,
// and its param_types IS the free-call signature, receiver first, the same convention as `map` and
// `filter` (and the one v1.compiler.method pair_declared_names reads when it pairs `names: ["xs", ..]`
// with a row). The receiver slot was missing here while every sibling carried it, so the row did not
// say where the step sits in `fold(xs, init, step)`; v2.compiler.fold_lowering reads that position
// from this row through template_step_position rather than from a literal index.
fn collection_fold_shape() -> AlgebraFieldTemplate {
{ name: "fold", param_types: [ReceiverSelf, AlgebraTypeVariable { id: "FoldAccumulator" }, CallableOf { params: [AlgebraTypeVariable { id: "FoldAccumulator" }, ReceiverElement], return_type: AlgebraTypeVariable { id: "FoldAccumulator" } }], return_type: AlgebraTypeVariable { id: "FoldAccumulator" }, size_effect: none, cost_shape: Present { value: ShapeIterateBody }, callback_element_position: Present { value: 1 } }
}

type StepPositionScan {
next: Int
found: Int?
}

// The position of a template's step -- its first callable parameter -- in the free-call signature
// the row declares. Absent when the row takes no callable.
fn template_step_position(t: AlgebraFieldTemplate) -> Int? {
let scan = fold(t.param_types, init: StepPositionScan { next: 0, found: none }, f: fn(acc, p) {
match acc.found {
Present { value: _ } => acc
Absent =>
match p {
CallableOf { params: _, return_type: _ } => StepPositionScan { next: acc.next + 1, found: Present { value: acc.next } }
_ => StepPositionScan { next: acc.next + 1, found: none }
}
}
})
scan.found
}

fn is_collection_filter_template(t: AlgebraFieldTemplate) -> Bool {
let proto = collection_filter_shape()
t.return_type == proto.return_type
Expand Down Expand Up @@ -768,7 +799,7 @@ fn finite_power_set_templates() -> List<AlgebraFieldTemplate> {
collection_filter_shape(),
{ name: "map", param_types: [ReceiverSelf, CallableOf { params: [ReceiverElement], return_type: AlgebraTypeVariable { id: "MappedElement" } }], return_type: ContainerOf { source: SameAsReceiver, element: AlgebraTypeVariable { id: "MappedElement" } }, size_effect: none, cost_shape: Present { value: ShapeIterateBody }, callback_element_position: Present { value: 0 } },
{ name: "flat_map", param_types: [ReceiverSelf, CallableOf { params: [ReceiverElement], return_type: ContainerOf { source: SameAsReceiver, element: AlgebraTypeVariable { id: "MappedElement" } } }], return_type: ContainerOf { source: SameAsReceiver, element: AlgebraTypeVariable { id: "MappedElement" } }, size_effect: none, cost_shape: Present { value: ShapeIterateBody }, callback_element_position: Present { value: 0 } },
{ name: "fold", param_types: [AlgebraTypeVariable { id: "FoldAccumulator" }, CallableOf { params: [AlgebraTypeVariable { id: "FoldAccumulator" }, ReceiverElement], return_type: AlgebraTypeVariable { id: "FoldAccumulator" } }], return_type: AlgebraTypeVariable { id: "FoldAccumulator" }, size_effect: none, cost_shape: Present { value: ShapeIterateBody }, callback_element_position: Present { value: 1 } },
collection_fold_shape(),
{ name: "any", param_types: [ReceiverSelf, CallableOf { params: [ReceiverElement], return_type: NamedTemplate { name: "Bool" } }], return_type: NamedTemplate { name: "Bool" }, size_effect: none, cost_shape: Present { value: ShapeIterateBody }, callback_element_position: Present { value: 0 } },
{ name: "all", param_types: [ReceiverSelf, CallableOf { params: [ReceiverElement], return_type: NamedTemplate { name: "Bool" } }], return_type: NamedTemplate { name: "Bool" }, size_effect: none, cost_shape: Present { value: ShapeIterateBody }, callback_element_position: Present { value: 0 } },
{ name: "count", param_types: [ReceiverSelf], return_type: NamedTemplate { name: "std.nat.Nat" }, size_effect: none, cost_shape: Present { value: ShapeLinearScan }, callback_element_position: none },
Expand Down Expand Up @@ -813,7 +844,7 @@ fn free_monoid_collection_templates() -> List<AlgebraFieldTemplate> {
{ name: "map", param_types: [ReceiverSelf, CallableOf { params: [ReceiverElement], return_type: AlgebraTypeVariable { id: "MappedElement" } }], return_type: ContainerOf { source: SameAsReceiver, element: AlgebraTypeVariable { id: "MappedElement" } }, size_effect: none, cost_shape: Present { value: ShapeIterateBody }, callback_element_position: Present { value: 0 } },
collection_filter_shape(),
{ name: "flat_map", param_types: [ReceiverSelf, CallableOf { params: [ReceiverElement], return_type: ContainerOf { source: SameAsReceiver, element: AlgebraTypeVariable { id: "MappedElement" } } }], return_type: ContainerOf { source: SameAsReceiver, element: AlgebraTypeVariable { id: "MappedElement" } }, size_effect: none, cost_shape: Present { value: ShapeIterateBody }, callback_element_position: Present { value: 0 } },
{ name: "fold", param_types: [AlgebraTypeVariable { id: "FoldAccumulator" }, CallableOf { params: [AlgebraTypeVariable { id: "FoldAccumulator" }, ReceiverElement], return_type: AlgebraTypeVariable { id: "FoldAccumulator" } }], return_type: AlgebraTypeVariable { id: "FoldAccumulator" }, size_effect: none, cost_shape: Present { value: ShapeIterateBody }, callback_element_position: Present { value: 1 } },
collection_fold_shape(),
{ name: "any", param_types: [ReceiverSelf, CallableOf { params: [ReceiverElement], return_type: NamedTemplate { name: "Bool" } }], return_type: NamedTemplate { name: "Bool" }, size_effect: none, cost_shape: Present { value: ShapeIterateBody }, callback_element_position: Present { value: 0 } },
{ name: "all", param_types: [ReceiverSelf, CallableOf { params: [ReceiverElement], return_type: NamedTemplate { name: "Bool" } }], return_type: NamedTemplate { name: "Bool" }, size_effect: none, cost_shape: Present { value: ShapeIterateBody }, callback_element_position: Present { value: 0 } },
{ name: "count", param_types: [ReceiverSelf], return_type: NamedTemplate { name: "std.nat.Nat" }, size_effect: none, cost_shape: Present { value: ShapeLinearScan }, callback_element_position: none },
Expand Down
112 changes: 62 additions & 50 deletions src/v1/stage0/src/std_algebra.rs
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,66 @@ pub fn collection_filter_shape() -> Rc<AlgebraFieldTemplate> {
})
}

pub fn collection_fold_shape() -> Rc<AlgebraFieldTemplate> {
Rc::new(AlgebraFieldTemplate {
name: "fold".to_string(),
param_types: Rc::new(vec![
Rc::new(AlgebraTypeTemplate::ReceiverSelf),
Rc::new(AlgebraTypeTemplate::AlgebraTypeVariable {
id: "FoldAccumulator".to_string(),
}),
Rc::new(AlgebraTypeTemplate::CallableOf {
params: Rc::new(vec![
Rc::new(AlgebraTypeTemplate::AlgebraTypeVariable {
id: "FoldAccumulator".to_string(),
}),
Rc::new(AlgebraTypeTemplate::ReceiverElement),
]),
return_type: Rc::new(AlgebraTypeTemplate::AlgebraTypeVariable {
id: "FoldAccumulator".to_string(),
}),
}),
]),
return_type: Rc::new(AlgebraTypeTemplate::AlgebraTypeVariable {
id: "FoldAccumulator".to_string(),
}),
size_effect: std::option::Option::None,
cost_shape: Some(CostShape::ShapeIterateBody),
callback_element_position: Some(1),
})
}

#[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)]
pub struct StepPositionScan {
pub next: i64,
pub found: Option<i64>,
}

pub fn template_step_position(t: Rc<AlgebraFieldTemplate>) -> Option<i64> {
{
let scan = t.param_types.clone().iter().cloned().fold(
StepPositionScan {
next: 0,
found: std::option::Option::None,
},
|acc: StepPositionScan, p: Rc<AlgebraTypeTemplate>| match acc.found.clone() {
Some(_) => acc.clone(),
std::option::Option::None => match (*p.clone()).clone() {
AlgebraTypeTemplate::CallableOf { .. } => StepPositionScan {
next: v1_rt::int_add(acc.next.clone(), 1),
found: Some(acc.next.clone()),
},
_ => StepPositionScan {
next: v1_rt::int_add(acc.next.clone(), 1),
found: std::option::Option::None,
},
},
},
);
scan.found.clone()
}
}

pub fn is_collection_filter_template(t: Rc<AlgebraFieldTemplate>) -> bool {
{
let proto = collection_filter_shape();
Expand Down Expand Up @@ -1217,31 +1277,7 @@ pub fn finite_power_set_templates() -> Rc<Vec<Rc<AlgebraFieldTemplate>>> {
cost_shape: Some(CostShape::ShapeIterateBody),
callback_element_position: Some(0),
}),
Rc::new(AlgebraFieldTemplate {
name: "fold".to_string(),
param_types: Rc::new(vec![
Rc::new(AlgebraTypeTemplate::AlgebraTypeVariable {
id: "FoldAccumulator".to_string(),
}),
Rc::new(AlgebraTypeTemplate::CallableOf {
params: Rc::new(vec![
Rc::new(AlgebraTypeTemplate::AlgebraTypeVariable {
id: "FoldAccumulator".to_string(),
}),
Rc::new(AlgebraTypeTemplate::ReceiverElement),
]),
return_type: Rc::new(AlgebraTypeTemplate::AlgebraTypeVariable {
id: "FoldAccumulator".to_string(),
}),
}),
]),
return_type: Rc::new(AlgebraTypeTemplate::AlgebraTypeVariable {
id: "FoldAccumulator".to_string(),
}),
size_effect: std::option::Option::None,
cost_shape: Some(CostShape::ShapeIterateBody),
callback_element_position: Some(1),
}),
collection_fold_shape(),
Rc::new(AlgebraFieldTemplate {
name: "any".to_string(),
param_types: Rc::new(vec![
Expand Down Expand Up @@ -1597,31 +1633,7 @@ pub fn free_monoid_collection_templates() -> Rc<Vec<Rc<AlgebraFieldTemplate>>> {
cost_shape: Some(CostShape::ShapeIterateBody),
callback_element_position: Some(0),
}),
Rc::new(AlgebraFieldTemplate {
name: "fold".to_string(),
param_types: Rc::new(vec![
Rc::new(AlgebraTypeTemplate::AlgebraTypeVariable {
id: "FoldAccumulator".to_string(),
}),
Rc::new(AlgebraTypeTemplate::CallableOf {
params: Rc::new(vec![
Rc::new(AlgebraTypeTemplate::AlgebraTypeVariable {
id: "FoldAccumulator".to_string(),
}),
Rc::new(AlgebraTypeTemplate::ReceiverElement),
]),
return_type: Rc::new(AlgebraTypeTemplate::AlgebraTypeVariable {
id: "FoldAccumulator".to_string(),
}),
}),
]),
return_type: Rc::new(AlgebraTypeTemplate::AlgebraTypeVariable {
id: "FoldAccumulator".to_string(),
}),
size_effect: std::option::Option::None,
cost_shape: Some(CostShape::ShapeIterateBody),
callback_element_position: Some(1),
}),
collection_fold_shape(),
Rc::new(AlgebraFieldTemplate {
name: "any".to_string(),
param_types: Rc::new(vec![
Expand Down
44 changes: 44 additions & 0 deletions src/v2/compiler/fold_lowering.dag
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ module v2.compiler.fold_lowering

import v2.extdeps.languages.dag {
dag_call_named_arg_value_optional,
dag_call_positional_arg_value_optional,
dag_lex_token_symbol,
parse_production_captured_child_optional,
parse_production_emitted_identity_optional
Expand All @@ -24,6 +25,7 @@ import v2.std.diagnostic {
outcome_accepted,
outcome_rejected
}
import std.algebra { collection_fold_shape, template_step_position }
import v2.std.grammar { node_atom_identity_optional }
import std.algebra { Cons, Empty }
import v2.std.collection { List }
Expand Down Expand Up @@ -130,6 +132,37 @@ fn fold_step_argument_name(head: Symbol) -> Optional<Symbol> {
}
}

// THE STEP'S POSITION IS READ FROM THE PRIMITIVE'S DECLARED SIGNATURE, NEVER FROM A LITERAL
// INDEX. `fold` is the collection primitive whose free-call signature std.algebra
// collection_fold_shape declares, receiver first, so `fold(xs, 0, fn(acc, y) { .. })` places its
// step where template_step_position reads it off that row; both spellings then reach the same
// step node and lower to the same Loop through the one path below.
//
// fold_list, fold_list_right and fold_node answer Absent, and that is a declared frontier rather
// than an omission: their signatures are ordinary v2.std.algebra / v2.std.node fn declarations with
// no data projection this stage can read, and no positional call site of any of them exists (DESIGN
// section 3c). A positional one keeps reading as StepByName -- the counted
// FoldCallStepFormUnresolved state -- until those signatures are readable here. The row also carries
// no parameter NAMES, so the name above stays authored per head; the two facts are separate.
fn some_step_argument_position(position: Int) -> Optional<Int> {
Present { value: position }
}

fn no_step_argument_position() -> Optional<Int> {
Absent
}

fn fold_step_argument_position(head: Symbol) -> Optional<Int> {
if head == ^fold {
match template_step_position(t: collection_fold_shape()) {
Present { value: k } => some_step_argument_position(position: k)
Absent => no_step_argument_position()
}
} else {
no_step_argument_position()
}
}

// Descends the CAPTURED-CHILD CHAIN of the step argument's value and nothing else: an expr
// wrapper chain has exactly one captured child per link, so this reaches the step's own
// production or runs out. It never folds over siblings, which is what stops a literal written
Expand Down Expand Up @@ -157,6 +190,17 @@ fn fold_call_step_form(fold_call: Node, head: Symbol) -> FoldStepForm {
Absent => StepByName
Present { value: step_name } =>
match dag_call_named_arg_value_optional(node: fold_call, name: step_name) {
Present { value: step_value } => fold_step_form_at(node: step_value)
Absent => fold_call_positional_step_form(fold_call: fold_call, head: head)
}
}
}

fn fold_call_positional_step_form(fold_call: Node, head: Symbol) -> FoldStepForm {
match fold_step_argument_position(head: head) {
Absent => StepByName
Present { value: position } =>
match dag_call_positional_arg_value_optional(node: fold_call, position: position) {
Absent => StepByName
Present { value: step_value } => fold_step_form_at(node: step_value)
}
Expand Down
61 changes: 61 additions & 0 deletions src/v2/extdeps/languages/dag.dag
Original file line number Diff line number Diff line change
Expand Up @@ -5615,6 +5615,67 @@ fn dag_call_named_arg_value_under_children(node: Node, name: Symbol) -> Optional
})
}

// The DIRECT argument at one declared POSITION of one call, under the same stopping rule as the
// named lookup above: the walk counts each ^dag_surface_arg it reaches, in source order, and never
// descends into one. A NAMED argument sitting at that position answers Absent -- its slot is
// decided by its name, never by where it was written -- so a call reaches its step by exactly one
// of the two readings.
type DagPositionalArgScan {
seen: Int
decided: Bool
found: Optional<Node>
}

fn dag_call_positional_arg_value_optional(node: Node, position: Int) -> Optional<Node> {
let scan = dag_call_positional_arg_scan(
node: node,
position: position,
acc: DagPositionalArgScan { seen: 0, decided: false, found: dag_named_arg_value_absent() }
)
scan.found
}

fn dag_call_positional_arg_scan(node: Node, position: Int, acc: DagPositionalArgScan) -> DagPositionalArgScan {
if acc.decided {
acc
} else {
match parse_production_emitted_identity_optional(node: node) {
Present { value: id } =>
if id == ^dag_surface_arg {
dag_call_positional_arg_visit(node: node, position: position, acc: acc)
} else {
dag_call_positional_arg_scan_children(node: node, position: position, acc: acc)
}
Absent => dag_call_positional_arg_scan_children(node: node, position: position, acc: acc)
}
}
}

fn dag_call_positional_arg_visit(node: Node, position: Int, acc: DagPositionalArgScan) -> DagPositionalArgScan {
if acc.seen == position {
DagPositionalArgScan { seen: acc.seen + 1, decided: true, found: dag_positional_arg_value(arg: node) }
} else {
DagPositionalArgScan { seen: acc.seen + 1, decided: false, found: acc.found }
}
}

fn dag_positional_arg_value(arg: Node) -> Optional<Node> {
match parse_production_captured_child_optional(node: arg) {
Absent => dag_named_arg_value_absent()
Present { value: arg_capture } =>
match dag_named_arg_value_optional(arg_capture: arg_capture) {
Present { value: _ } => dag_named_arg_value_absent()
Absent => dag_named_arg_value_present(node: arg_capture)
}
}
}

fn dag_call_positional_arg_scan_children(node: Node, position: Int, acc: DagPositionalArgScan) -> DagPositionalArgScan {
fold(node.children, init: acc, f: fn(inner, e) {
dag_call_positional_arg_scan(node: e.target, position: position, acc: inner)
})
}

fn dag_named_arg_value_absent() -> Optional<Node> {
Absent
}
Expand Down
Loading