Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
6527c38
WIP: crisp-ibex-569
briansrls May 3, 2026
e8542ec
WIP: crisp-ibex-569
briansrls May 3, 2026
892e3e3
chore: apply cargo fmt
briansrls May 3, 2026
0c5afbb
WIP: crisp-ibex-569
briansrls May 3, 2026
4ad2b1f
test(v2): fix source-root helper clippy
briansrls May 3, 2026
ee021b4
Merge remote-tracking branch 'origin/main' into codex/r3-row85-v2-eph…
briansrls May 3, 2026
29b20d0
test(v2): isolate ephemeral source-root temp dirs
briansrls May 3, 2026
660df13
Merge remote-tracking branch 'origin/main' into codex/r3-row85-v2-eph…
briansrls May 3, 2026
b8ccfd8
WIP: crisp-ibex-569
briansrls May 3, 2026
a2fb7a0
chore: apply cargo fmt
briansrls May 3, 2026
a74c99c
Merge remote-tracking branch 'origin/main' into codex/r3-row85-v2-eph…
briansrls May 3, 2026
a3324ac
Merge remote-tracking branch 'origin/main' into codex/r3-row85-v2-eph…
briansrls May 3, 2026
e94ce98
Merge remote-tracking branch 'origin/main' into codex/r3-row85-v2-eph…
briansrls May 3, 2026
342f6b7
Merge remote-tracking branch 'origin/main' into codex/r3-row85-v2-eph…
briansrls May 3, 2026
ca7c3a7
Merge remote-tracking branch 'origin/main' into codex/r3-row85-v2-eph…
briansrls May 3, 2026
ab00508
Merge remote-tracking branch 'origin/main' into codex/r3-row85-v2-eph…
briansrls May 3, 2026
662131d
Merge remote-tracking branch 'origin/main' into codex/r3-row85-v2-eph…
briansrls May 3, 2026
34d2b19
Merge remote-tracking branch 'origin/main' into codex/r3-row85-v2-eph…
briansrls May 3, 2026
d613718
Merge remote-tracking branch 'origin/main' into codex/r3-row85-v2-eph…
briansrls May 3, 2026
137f42b
Merge remote-tracking branch 'origin/main' into codex/r3-row85-v2-eph…
briansrls May 3, 2026
cc8223f
Merge remote-tracking branch 'origin/main' into codex/r3-row85-v2-eph…
briansrls May 3, 2026
ee6c339
Merge remote-tracking branch 'origin/main' into codex/r3-row85-v2-eph…
briansrls May 3, 2026
a132e3d
Merge remote-tracking branch 'origin/main' into codex/r3-row85-v2-eph…
briansrls May 3, 2026
e2308b6
Merge remote-tracking branch 'origin/main' into codex/r3-row85-v2-eph…
briansrls May 3, 2026
10953f9
Merge remote-tracking branch 'origin/main' into codex/r3-row85-v2-eph…
briansrls May 4, 2026
f3b61a4
Merge remote-tracking branch 'origin/main' into codex/r3-row85-v2-eph…
briansrls May 4, 2026
3122fdb
Merge remote-tracking branch 'origin/main' into codex/r3-row85-v2-eph…
briansrls May 4, 2026
8f47e82
Merge remote-tracking branch 'origin/main' into codex/r3-row85-v2-eph…
briansrls May 4, 2026
8c10429
Merge remote-tracking branch 'origin/main' into codex/r3-row85-v2-eph…
briansrls May 4, 2026
1cb0c39
Merge remote-tracking branch 'origin/main' into codex/r3-row85-v2-eph…
briansrls May 4, 2026
c3c074d
WIP: crisp-ibex-569
briansrls May 4, 2026
6199c36
chore: apply cargo fmt
briansrls May 4, 2026
6cf05ea
WIP: crisp-ibex-569
briansrls May 4, 2026
74c67d2
chore: apply cargo fmt
briansrls May 4, 2026
be02b60
WIP: crisp-ibex-569
briansrls May 4, 2026
80929ae
Tighten lens data substitution diagnostics
briansrls May 4, 2026
26dc6fb
WIP: crisp-ibex-569
briansrls May 4, 2026
35b3c8f
WIP: crisp-ibex-569
briansrls May 4, 2026
7b5d246
chore: apply cargo fmt
briansrls May 4, 2026
7484be8
WIP: crisp-ibex-569
briansrls May 4, 2026
0630bae
WIP: crisp-ibex-569
briansrls May 4, 2026
096b36d
chore: apply cargo fmt
briansrls May 4, 2026
e6eddb1
WIP: crisp-ibex-569
briansrls May 4, 2026
c8ef0d3
chore: apply cargo fmt
briansrls May 4, 2026
50b5da8
Merge remote-tracking branch 'origin/main' into codex/r3-row85-v2-eph…
briansrls May 4, 2026
b9ac057
Specialize structural mismatch diagnostics
briansrls May 4, 2026
b17ced6
WIP: crisp-ibex-569
briansrls May 4, 2026
959b88e
chore: apply cargo fmt
briansrls May 4, 2026
009d033
Merge remote-tracking branch 'origin/main' into codex/r3-row85-v2-eph…
briansrls May 4, 2026
4c85a38
WIP: crisp-ibex-569
briansrls May 4, 2026
dec5e9c
chore: apply cargo fmt
briansrls May 4, 2026
ef9cbb4
WIP: crisp-ibex-569
briansrls May 4, 2026
3a2ea5b
Merge remote-tracking branch 'origin/main' into codex/r3-row85-v2-eph…
briansrls May 4, 2026
2ec114e
Merge remote-tracking branch 'origin/main' into codex/r3-row85-v2-eph…
briansrls May 4, 2026
e46e172
Merge remote-tracking branch 'origin/main' into codex/r3-row85-v2-eph…
briansrls May 4, 2026
35e626d
WIP: crisp-ibex-569
briansrls May 4, 2026
b69c2a4
Merge remote-tracking branch 'origin/main' into codex/r3-row85-v2-eph…
briansrls May 4, 2026
b7be0aa
WIP: crisp-ibex-569
briansrls May 4, 2026
cf911b4
Merge remote-tracking branch 'origin/main' into codex/r3-row85-v2-eph…
briansrls May 4, 2026
324b39a
test: parse v3 dag operator subset symbols locally
briansrls May 4, 2026
447e4f2
Merge remote-tracking branch 'origin/main' into codex/r3-row85-v2-eph…
briansrls May 4, 2026
d6a6871
Merge remote-tracking branch 'origin/main' into codex/r3-row85-v2-eph…
briansrls May 4, 2026
0315956
fix: validate all shared dag operator rows
briansrls May 4, 2026
26520ca
fix: derive tokenizer operator debt from v3 projection
briansrls May 4, 2026
5c0051b
Merge remote-tracking branch 'origin/main' into codex/r3-row85-v2-eph…
briansrls May 4, 2026
149d84d
Merge remote-tracking branch 'origin/main' into codex/r3-row85-v2-eph…
briansrls May 4, 2026
1846c25
WIP: crisp-ibex-569
briansrls May 4, 2026
8ea014a
Merge remote-tracking branch 'origin/main' into codex/r3-row85-v2-eph…
briansrls May 4, 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
26 changes: 22 additions & 4 deletions dsl/extdeps/languages/dag/syntax.dag
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import std.syntax {
ExprBody, BlockBody, TypeBody, ValueBody, NoBody,
ServiceBody, ResourceBody,
OperatorSpec, SyntaxSpec,
BinOp, Add, Sub, Mul, Div,
Eq, Ne, Lt, Gt, Le, Ge, And, Or,
BinOp, Add, Sub, Mul, Div, Mod,
Eq, Ne, Lt, Gt, Le, Ge, And, Or, NullCoalesce,
LiteralValue, LitBool, LitNull
}

Expand Down Expand Up @@ -91,14 +91,17 @@ data dag_non_name_keywords: Map<String, Bool> = {
"acquire": true, "release": true
}

// Operator precedence table.
// || < && < cmp < add < mul < |> < .
// External .dag operator precedence authority.
// This table models external .dag syntax reality, not the current v3-supported
// tokenizer/parser/operator subset.
// || < && < ?? < cmp < add < mul < |> < .
// |> and . have binding power entries but their binop field is unused
// (the expression loop handles them as pipe/field-access, not binary ops).

data dag_operators: List<OperatorSpec> = [
OperatorSpec { symbol: "||", left_bp: 5, right_bp: 6, binop: Or, algebra_field: none },
OperatorSpec { symbol: "&&", left_bp: 7, right_bp: 8, binop: And, algebra_field: none },
OperatorSpec { symbol: "??", left_bp: 8, right_bp: 9, binop: NullCoalesce, algebra_field: none },
OperatorSpec { symbol: "==", left_bp: 9, right_bp: 10, binop: Eq, algebra_field: none },
OperatorSpec { symbol: "!=", left_bp: 9, right_bp: 10, binop: Ne, algebra_field: none },
OperatorSpec { symbol: "<", left_bp: 11, right_bp: 12, binop: Lt, algebra_field: none },
Expand All @@ -109,10 +112,25 @@ data dag_operators: List<OperatorSpec> = [
OperatorSpec { symbol: "-", left_bp: 13, right_bp: 14, binop: Sub, algebra_field: none },
OperatorSpec { symbol: "*", left_bp: 15, right_bp: 16, binop: Mul, algebra_field: none },
OperatorSpec { symbol: "/", left_bp: 15, right_bp: 16, binop: Div, algebra_field: none },
OperatorSpec { symbol: "%", left_bp: 15, right_bp: 16, binop: Mod, algebra_field: none },
OperatorSpec { symbol: "|>", left_bp: 17, right_bp: 18, binop: none, algebra_field: none },
OperatorSpec { symbol: ".", left_bp: 19, right_bp: 20, binop: none, algebra_field: none }
]

// Current v3 capability projection.
// v3 tokenizer/parser/operator validation consumes these explicit supported
// symbols, then reads precedence/binop facts from `dag_operators`. This avoids
// duplicating operator semantics while still fencing current v3 capability.
// It intentionally excludes external `dag_operators` rows that v3 does not
// parse end-to-end yet, including `??` and `%`.

data v3_supported_dag_operators: Map<String, Bool> = {

This comment was marked as resolved.

"||": true, "&&": true,
"==": true, "!=": true, "<": true, ">": true, "<=": true, ">=": true,
"+": true, "-": true, "*": true, "/": true,
"|>": true, ".": true
}

data dag_syntax_spec: SyntaxSpec = SyntaxSpec {
item_forms: dag_item_forms,
operators: dag_operators,
Expand Down
40 changes: 39 additions & 1 deletion src/v2/stage0/src/extdeps_languages_dag_syntax.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// Generated by v2 compiler -- do not edit.
// Source module: extdeps.languages.dag.syntax

use crate::std_syntax::BinOp::{Add, And, Div, Eq, Ge, Gt, Le, Lt, Mul, Ne, Or, Sub};
use crate::std_syntax::BinOp::{
Add, And, Div, Eq, Ge, Gt, Le, Lt, Mod, Mul, Ne, NullCoalesce, Or, Sub,
};
use crate::std_syntax::BodyKind::{
BlockBody, ExprBody, NoBody, ResourceBody, ServiceBody, TypeBody, ValueBody,
};
Expand Down Expand Up @@ -193,6 +195,12 @@ pub fn dag_operators() -> Rc<Vec<Rc<OperatorSpec>>> {
right_bp: 8,
binop: Some(BinOp::And),
algebra_field: None,
}), Rc::new(OperatorSpec {
symbol: "??".to_string(),
left_bp: 8,
right_bp: 9,
binop: Some(BinOp::NullCoalesce),
algebra_field: None,
}), Rc::new(OperatorSpec {
symbol: "==".to_string(),
left_bp: 9,
Expand Down Expand Up @@ -253,6 +261,12 @@ pub fn dag_operators() -> Rc<Vec<Rc<OperatorSpec>>> {
right_bp: 16,
binop: Some(BinOp::Div),
algebra_field: None,
}), Rc::new(OperatorSpec {
symbol: "%".to_string(),
left_bp: 15,
right_bp: 16,
binop: Some(BinOp::Mod),
algebra_field: None,
}), Rc::new(OperatorSpec {
symbol: "|>".to_string(),
left_bp: 17,
Expand All @@ -271,6 +285,30 @@ pub fn dag_operators() -> Rc<Vec<Rc<OperatorSpec>>> {
CACHED.with(|c| c.clone())
}

pub fn v3_supported_dag_operators() -> Rc<HashMap<String, bool>> {
thread_local! {
static CACHED: Rc<HashMap<String, bool>> = {
let mut __m = HashMap::new();
__m.insert("||".to_string(), true);
__m.insert("&&".to_string(), true);
__m.insert("==".to_string(), true);
__m.insert("!=".to_string(), true);
__m.insert("<".to_string(), true);
__m.insert(">".to_string(), true);
__m.insert("<=".to_string(), true);
__m.insert(">=".to_string(), true);
__m.insert("+".to_string(), true);
__m.insert("-".to_string(), true);
__m.insert("*".to_string(), true);
__m.insert("/".to_string(), true);
__m.insert("|>".to_string(), true);
__m.insert(".".to_string(), true);
Rc::new(__m)
};
}
CACHED.with(|c| c.clone())
}

pub fn dag_syntax_spec() -> Rc<SyntaxSpec> {
thread_local! {
static CACHED: Rc<SyntaxSpec> = {
Expand Down
53 changes: 36 additions & 17 deletions src/v3/compiler/src/bin/regen_tokenize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,8 @@ fn collect_punct_rows(dag: &Dag, shared_syntax: &SharedSyntaxAuthority) -> Vec<(
let mut covered_kinds = BTreeSet::new();

for pattern in &shared_syntax.operators {
match classify_shared_operator_for_tokenizer(pattern) {
match classify_shared_operator_for_tokenizer(pattern, &shared_syntax.v3_supported_operators)
{
SharedOperatorTokenizerBoundary::Tokenized { kind } => {
assert!(
punct_variants.contains(kind),
Expand Down Expand Up @@ -610,16 +611,24 @@ fn keyword_spelling_for_token_kind(kind: &str) -> String {
.to_ascii_lowercase()
}

// SG-1a operator bridge: shared operators still lower through raw-source reads,
// so every `dag_operators` symbol must be classified explicitly here as either
// tokenizer punctuation or parser-only debt. Unknown symbols panic so upstream
// authority edits cannot silently disappear.
// SG-1a operator bridge: shared operators still lower through raw-source reads.
// `v3_supported_dag_operators` is the single support/exclusion projection; this
// table only maps supported symbols to their current tokenizer variant.
enum SharedOperatorTokenizerBoundary {
Tokenized { kind: &'static str },
ParserOnlyDebt { reason: &'static str },
}

fn classify_shared_operator_for_tokenizer(pattern: &str) -> SharedOperatorTokenizerBoundary {
fn classify_shared_operator_for_tokenizer(
pattern: &str,
v3_supported: &BTreeSet<String>,
) -> SharedOperatorTokenizerBoundary {
if !v3_supported.contains(pattern) {
return SharedOperatorTokenizerBoundary::ParserOnlyDebt {
reason: "operator is declared in external dag_operators but excluded from \
v3_supported_dag_operators until v3 parses it end-to-end",
};
}
match pattern {
"==" => SharedOperatorTokenizerBoundary::Tokenized { kind: "EqEq" },
"!=" => SharedOperatorTokenizerBoundary::Tokenized { kind: "NotEq" },
Expand All @@ -635,25 +644,18 @@ fn classify_shared_operator_for_tokenizer(pattern: &str) -> SharedOperatorTokeni
"||" => SharedOperatorTokenizerBoundary::Tokenized { kind: "PipePipe" },
"|>" => SharedOperatorTokenizerBoundary::Tokenized { kind: "PipeArrow" },
"." => SharedOperatorTokenizerBoundary::Tokenized { kind: "Dot" },
"??" => SharedOperatorTokenizerBoundary::ParserOnlyDebt {
reason: "null-coalescing is declared in shared syntax but the v3 tokenizer/parser \
surface does not yet admit it as punctuation",
},
"%" => SharedOperatorTokenizerBoundary::ParserOnlyDebt {
reason: "modulo is declared in shared syntax but the v3 tokenizer/parser surface \
does not yet admit it as punctuation",
},
other => panic!(
"shared syntax operator `{other}` has no SG-1a tokenizer bridge classification. \
Update `classify_shared_operator_for_tokenizer` to mark it as tokenizer-owned \
punctuation or explicit parser-only debt so the authority boundary stays fail-closed."
"`v3_supported_dag_operators` includes `{other}`, but the SG-1a tokenizer bridge has \
no TokenKind mapping for it. Add tokenizer/parser/operator support or remove it from \
the v3 projection."
),
}
}

struct SharedSyntaxAuthority {
keywords: Vec<String>,
operators: Vec<String>,
v3_supported_operators: BTreeSet<String>,
}

impl SharedSyntaxAuthority {
Expand All @@ -670,9 +672,15 @@ impl SharedSyntaxAuthority {
extract_balanced_section(source, "data dag_operators", '[', ']'),
"symbol",
);
let v3_supported_operators: BTreeSet<_> = parse_all_string_literals(
extract_balanced_section(source, "data v3_supported_dag_operators", '{', '}'),
)
.into_iter()
.collect();
Self {
keywords,
operators,
v3_supported_operators,
}
}
}
Expand Down Expand Up @@ -730,6 +738,17 @@ fn parse_named_string_fields(section: &str, field_name: &str) -> Vec<String> {
out
}

fn parse_all_string_literals(section: &str) -> Vec<String> {
let mut out = Vec::new();
let mut rest = section;
while let Some(idx) = rest.find('"') {
let (value, consumed) = parse_string_literal(&rest[idx..]);
out.push(value);
rest = &rest[idx + consumed..];
}
out
}

fn parse_string_literal(source: &str) -> (String, usize) {
assert!(
source.starts_with('"'),
Expand Down
Loading
Loading