diff --git a/crates/plotnik-lib/src/emit/codegen_tests.rs b/crates/plotnik-lib/src/emit/codegen_tests.rs index 6abd7b2d..78ae4b00 100644 --- a/crates/plotnik-lib/src/emit/codegen_tests.rs +++ b/crates/plotnik-lib/src/emit/codegen_tests.rs @@ -320,6 +320,14 @@ fn alternations_captured_tagged() { "#}); } +#[test] +fn alternations_tagged_with_definition_ref() { + snap!(indoc! {r#" + Inner = (identifier) @name + Test = [A: (Inner) B: (number) @b] @item + "#}); +} + #[test] fn alternations_in_quantifier() { snap!(indoc! {r#" diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__codegen_tests__alternations_tagged_with_definition_ref.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__codegen_tests__alternations_tagged_with_definition_ref.snap new file mode 100644 index 00000000..074d0baf --- /dev/null +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__codegen_tests__alternations_tagged_with_definition_ref.snap @@ -0,0 +1,65 @@ +--- +source: crates/plotnik-lib/src/emit/codegen_tests.rs +--- +Inner = (identifier) @name +Test = [A: (Inner) B: (number) @b] @item +--- +[flags] +linked = false + +[strings] +S0 "Beauty will save the world" +S1 "name" +S2 "b" +S3 "A" +S4 "B" +S5 "item" +S6 "Inner" +S7 "Test" +S8 "identifier" +S9 "number" + +[type_defs] +T0 = +T1 = Struct M0:1 ; { name } +T2 = Struct M1:1 ; { b } +T3 = Enum M2:2 ; A | B +T4 = Struct M4:1 ; { item } + +[type_members] +M0: S1 → T0 ; name: +M1: S2 → T0 ; b: +M2: S3 → T1 ; A: Inner +M3: S4 → T2 ; B: T2 +M4: S5 → T3 ; item: T3 + +[type_names] +N0: S6 → T1 ; Inner +N1: S7 → T4 ; Test + +[entrypoints] +Inner = 01 :: T1 +Test = 09 :: T4 + +[transitions] + 00 ε ◼ + +Inner: + 01 ε 02 + 02 ε [Obj] 04 + 04 (identifier) [Node Set(M0)] 06 + 06 ε [EndObj] 08 + 08 ▶ + +Test: + 09 ε 10 + 10 ε [Obj] 12 + 12 ε 20, 26 + 14 ▶ + 15 ε [EndObj] 14 + 17 ε [EndEnum Set(M4)] 15 + 19 (Inner) 17 ⯇ + 20 ε [Enum(M2)] 19 + 22 ε [EndEnum Set(M4)] 15 + 24 (number) [Node Set(M1)] 22 + 26 ε [Enum(M3)] 24 diff --git a/crates/plotnik-lib/src/engine/materializer.rs b/crates/plotnik-lib/src/engine/materializer.rs index 264c88ed..5b8a982d 100644 --- a/crates/plotnik-lib/src/engine/materializer.rs +++ b/crates/plotnik-lib/src/engine/materializer.rs @@ -139,9 +139,12 @@ impl<'t> Materializer<'t> for ValueMaterializer<'_> { } RuntimeEffect::EndEnum => { if let Some(Builder::Tagged { tag, fields }) = stack.pop() { + // If inner returned a structured value (via Obj/EndObj), use it as data + // Otherwise use fields collected from direct Set effects + let data = pending.take().unwrap_or(Value::Object(fields)); pending = Some(Value::Tagged { tag, - data: Box::new(Value::Object(fields)), + data: Box::new(data), }); } }