Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 6 additions & 1 deletion src/v2/extdeps/languages/dag.dag
Original file line number Diff line number Diff line change
Expand Up @@ -1916,6 +1916,8 @@ fn dag_grammar_data_decl_expr() -> GrammarExpr {
// declarations allowed to call it (std.integer qualified_octets). v1.compiler.parse
// parse_optional_admit_callers reads it as a field-init on the fn node and refuses an empty list;
// the list here requires a first element for the same reason, so `admit_callers: []` still refuses.
// A trailing comma before `]` is admitted, as dag_grammar_comma_list_expr admits it and as v1 reads
// the list; without it every multi-line caller list written with one refused its whole module.
// `admit_callers` is matched as an exact-word terminal and stays an ordinary identifier everywhere
// else. The clause is consumed and then DISCARDED when the fn lowers to an Arrow: nothing on the
// native route checks caller admission, and the stage that does adds its Arrow carrier together
Expand All @@ -1939,7 +1941,10 @@ fn dag_grammar_admit_callers_clause_expr() -> GrammarExpr {
right: dag_grammar_nonterminal(production: ^dag_production_expr)
)
),
right: dag_grammar_terminal(token_class: ^dag_token_rbracket)
right: dag_grammar_sequence(
left: dag_grammar_optional(element: dag_grammar_terminal(token_class: ^dag_token_comma)),
right: dag_grammar_terminal(token_class: ^dag_token_rbracket)
)
)
)
)
Expand Down
72 changes: 72 additions & 0 deletions src/v2/test/claim/parse/admit_callers_trailing_comma_test.dag
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
module v2.test.claim.parse.admit_callers_trailing_comma

import v2.compiler.parse { parse_module_prepared }
import v2.compiler.program_assembly { dag_prepared_grammar }
import v2.compiler.tokenize { tokenize }
import v2.extdeps.languages.dag { dag_lex }
import v2.std.diagnostic { Accepted, Outcome, Rejected, bind_outcome }
import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly }
import v2.std.logic { Bool }
import v2.std.node { Node }
import v2.std.text { String }

data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly

// AN admit_callers LIST MAY END IN A COMMA (v2.extdeps.languages.dag
// dag_grammar_admit_callers_clause_expr), as a comma list does everywhere else and as v1 reads it;
// the list still needs a first element, so a list that is only a comma still refuses. The elements
// are bare names: the clause admits any expression, so the comma behaviour is the same and each
// claim stays one small parse (a decl_ref element list cost 118k eval steps against the 72.3k
// new-witness budget).
fn admit_source(list: String) -> String {
"module probe.admit\n\nfn sealed(n: Int) -> Int\n admit_callers: [" + list + "]\n = n\n"
}

fn admit_parse(text: String) -> Outcome<Node> {
match dag_prepared_grammar() {
Rejected { diagnostics: d } => Rejected { diagnostics: d }
Accepted { value: prepared, diagnostics: residue } =>
bind_outcome(
o: tokenize(text: text, file: ^admit_trailing_comma_probe, rules: dag_lex()),
f: fn(token_stream) {
match parse_module_prepared(tokens: token_stream, prepared: prepared, validation_residue: residue) {
Rejected { diagnostics: r } => Rejected { diagnostics: r }
Accepted { value: artifact, diagnostics: d } => Accepted { value: artifact.tree, diagnostics: d }
}
}
)
}
}

fn admit_parses(list: String) -> Bool {
match admit_parse(text: admit_source(list: list)) {
Accepted { value: _, diagnostics: _ } => true
Rejected { diagnostics: _ } => false
}
}

// Each parse is computed ONCE as a nullary value, enrolled WARM in
// v2.workflow.floor_pure_producer_share, and each claim reads it: a parse is mostly fixed front-end
// work, so a claim that parsed its own source was over the new-witness eval-step budget.
fn trailing_comma_parsed() -> Bool {
admit_parses(list: "caller_a,\n caller_b,\n ")
}

fn no_trailing_comma_parsed() -> Bool {
admit_parses(list: "caller_a, caller_b")
}

fn only_a_comma_parsed() -> Bool {
admit_parses(list: ",")
}

test fn a_trailing_comma_in_admit_callers_parses_holds() -> Bool { trailing_comma_parsed() }

test fn an_admit_callers_list_without_a_trailing_comma_parses_holds() -> Bool { no_trailing_comma_parsed() }

test fn an_admit_callers_list_of_only_a_comma_refuses_holds() -> Bool {
match only_a_comma_parsed() {
true => false
false => true
}
}
3 changes: 3 additions & 0 deletions src/v2/workflow/floor_pure_producer_share.dag
Original file line number Diff line number Diff line change
Expand Up @@ -1054,6 +1054,9 @@ data floor_cross_claim_pure_producers_warm: List<String> = [
"v2.test.claim.namespace_xl0.reference_conservation_census.under_floor_fixture_files",
"v2.test.claim.namespace_xl0.reference_conservation_census.half_share_fixture_files",
"v2.test.claim.occurrence_role.occurrence_role.roles_fixture_outcome",
"v2.test.claim.parse.admit_callers_trailing_comma.trailing_comma_parsed",
"v2.test.claim.parse.admit_callers_trailing_comma.no_trailing_comma_parsed",
"v2.test.claim.parse.admit_callers_trailing_comma.only_a_comma_parsed",
"v2.test.claim.occurrence_role.occurrence_role.binders_fixture_outcome",
"v2.test.claim.occurrence_role.occurrence_role.mixed_param_list_parsed",
"v2.test.claim.occurrence_role.occurrence_role.mixed_param_list_planted",
Expand Down