Add deep access

Signed-off-by: Marcel Müller <neikos@neikos.email>
This commit is contained in:
Marcel Müller 2026-03-15 14:31:46 +01:00
parent 4f770c1f24
commit ffd9baf90f
9 changed files with 669 additions and 5 deletions

View file

@ -0,0 +1,74 @@
---
source: tests/file_tests.rs
expression: parsed
info:
input: "{{ if world?.active }}\nHello {{= world.name }}\n{{ end }}\n\n{{ if world?.foo?.bar?.active }}\n Weird!\n{{ else }}\n Deep access is working :)\n{{ end }}"
context:
world:
active: true
name: World!
---
ParsedTemplate {
tokens: [
[LeftDelim]"{{" (0..2),
[Whitespace]" " (2..3),
[ConditionalIf]"if" (3..5),
[Whitespace]" " (5..6),
[Ident]"world" (6..11),
[Operator(QuestionMark)]"?" (11..12),
[Operator(Dot)]"." (12..13),
[Ident]"active" (13..19),
[Whitespace]" " (19..20),
[RightDelim]"}}" (20..22),
[Whitespace]"\n" (22..23),
[Content]"Hello" (23..28),
[Whitespace]" " (28..29),
[LeftDelim]"{{" (29..31),
[WantsOutput]"=" (31..32),
[Whitespace]" " (32..33),
[Ident]"world" (33..38),
[Operator(Dot)]"." (38..39),
[Ident]"name" (39..43),
[Whitespace]" " (43..44),
[RightDelim]"}}" (44..46),
[Whitespace]"\n" (46..47),
[LeftDelim]"{{" (47..49),
[Whitespace]" " (49..50),
[End]"end" (50..53),
[Whitespace]" " (53..54),
[RightDelim]"}}" (54..56),
[Whitespace]"\n\n" (56..58),
[LeftDelim]"{{" (58..60),
[Whitespace]" " (60..61),
[ConditionalIf]"if" (61..63),
[Whitespace]" " (63..64),
[Ident]"world" (64..69),
[Operator(QuestionMark)]"?" (69..70),
[Operator(Dot)]"." (70..71),
[Ident]"foo" (71..74),
[Operator(QuestionMark)]"?" (74..75),
[Operator(Dot)]"." (75..76),
[Ident]"bar" (76..79),
[Operator(QuestionMark)]"?" (79..80),
[Operator(Dot)]"." (80..81),
[Ident]"active" (81..87),
[Whitespace]" " (87..88),
[RightDelim]"}}" (88..90),
[Whitespace]"\n " (90..95),
[Content]"Weird!" (95..101),
[Whitespace]"\n" (101..102),
[LeftDelim]"{{" (102..104),
[Whitespace]" " (104..105),
[ConditionalElse]"else" (105..109),
[Whitespace]" " (109..110),
[RightDelim]"}}" (110..112),
[Whitespace]"\n " (112..117),
[Content]"Deep access is working :)" (117..142),
[Whitespace]"\n" (142..143),
[LeftDelim]"{{" (143..145),
[Whitespace]" " (145..146),
[End]"end" (146..149),
[Whitespace]" " (149..150),
[RightDelim]"}}" (150..152),
],
}

View file

@ -0,0 +1,131 @@
---
source: tests/file_tests.rs
expression: ast
info:
input: "{{ if world?.active }}\nHello {{= world.name }}\n{{ end }}\n\n{{ if world?.foo?.bar?.active }}\n Weird!\n{{ else }}\n Deep access is working :)\n{{ end }}"
context:
world:
active: true
name: World!
---
TemplateAst {
root: [
ConditionalChain {
chain: [
Block {
prev_whitespace_content: None,
expression: IfConditional {
expression: AccessOperation {
op: Dot,
lhs: ConditionalAccess(
[Ident]"world" (6..11),
),
rhs: VariableAccess(
[Ident]"active" (13..19),
),
},
},
post_whitespace_content: Some(
[Whitespace]"\n" (22..23),
),
},
ConditionalContent {
content: [
StaticContent(
[Content]"Hello" (23..28),
),
Interpolation {
prev_whitespace_content: Some(
[Whitespace]" " (28..29),
),
expression: AccessOperation {
op: Dot,
lhs: VariableAccess(
[Ident]"world" (33..38),
),
rhs: VariableAccess(
[Ident]"name" (39..43),
),
},
post_whitespace_content: Some(
[Whitespace]"\n" (46..47),
),
},
],
},
Block {
prev_whitespace_content: None,
expression: EndBlock,
post_whitespace_content: Some(
[Whitespace]"\n\n" (56..58),
),
},
],
},
ConditionalChain {
chain: [
Block {
prev_whitespace_content: None,
expression: IfConditional {
expression: AccessOperation {
op: Dot,
lhs: AccessOperation {
op: Dot,
lhs: AccessOperation {
op: Dot,
lhs: ConditionalAccess(
[Ident]"world" (64..69),
),
rhs: ConditionalAccess(
[Ident]"foo" (71..74),
),
},
rhs: ConditionalAccess(
[Ident]"bar" (76..79),
),
},
rhs: VariableAccess(
[Ident]"active" (81..87),
),
},
},
post_whitespace_content: Some(
[Whitespace]"\n " (90..95),
),
},
ConditionalContent {
content: [
StaticContent(
[Content]"Weird!" (95..101),
),
],
},
Block {
prev_whitespace_content: Some(
[Whitespace]"\n" (101..102),
),
expression: ElseConditional {
expression: None,
},
post_whitespace_content: Some(
[Whitespace]"\n " (112..117),
),
},
ConditionalContent {
content: [
StaticContent(
[Content]"Deep access is working :)" (117..142),
),
],
},
Block {
prev_whitespace_content: Some(
[Whitespace]"\n" (142..143),
),
expression: EndBlock,
post_whitespace_content: None,
},
],
},
],
}

View file

@ -0,0 +1,313 @@
---
source: tests/file_tests.rs
expression: emit
info:
input: "{{ if world?.active }}\nHello {{= world.name }}\n{{ end }}\n\n{{ if world?.foo?.bar?.active }}\n Weird!\n{{ else }}\n Deep access is working :)\n{{ end }}"
context:
world:
active: true
name: World!
---
VMInstructions {
labels: {
LabelSlot {
index: 0,
}: 18,
LabelSlot {
index: 2,
}: 4,
LabelSlot {
index: 4,
}: 18,
LabelSlot {
index: 6,
}: 13,
LabelSlot {
index: 8,
}: 43,
LabelSlot {
index: 10,
}: 31,
LabelSlot {
index: 12,
}: 27,
LabelSlot {
index: 14,
}: 23,
LabelSlot {
index: 16,
}: 38,
},
instructions: [
LoadFromContextToSlot {
name: "world" (6..11),
slot: VariableSlot {
index: 3,
},
fail_on_not_found: false,
},
JumpIfUndefined {
slot: VariableSlot {
index: 3,
},
jump: LabelSlot {
index: 2,
},
},
IndexSlotToSlot {
name: "active" (13..19),
from_slot: VariableSlot {
index: 3,
},
to_slot: VariableSlot {
index: 3,
},
fail_on_not_found: true,
},
JumpIfUndefined {
slot: VariableSlot {
index: 3,
},
jump: LabelSlot {
index: 2,
},
},
LoadFromSlotToSlot {
from_slot: VariableSlot {
index: 3,
},
to_slot: VariableSlot {
index: 1,
},
},
JumpIfNotTrue {
emit_slot: VariableSlot {
index: 1,
},
jump: LabelSlot {
index: 4,
},
},
AppendContent {
content: "\n" (22..23),
},
AppendContent {
content: "Hello" (23..28),
},
AppendContent {
content: " " (28..29),
},
LoadFromContextToSlot {
name: "world" (33..38),
slot: VariableSlot {
index: 7,
},
fail_on_not_found: true,
},
JumpIfUndefined {
slot: VariableSlot {
index: 7,
},
jump: LabelSlot {
index: 6,
},
},
IndexSlotToSlot {
name: "name" (39..43),
from_slot: VariableSlot {
index: 7,
},
to_slot: VariableSlot {
index: 7,
},
fail_on_not_found: true,
},
JumpIfUndefined {
slot: VariableSlot {
index: 7,
},
jump: LabelSlot {
index: 6,
},
},
LoadFromSlotToSlot {
from_slot: VariableSlot {
index: 7,
},
to_slot: VariableSlot {
index: 5,
},
},
EmitFromSlot {
slot: VariableSlot {
index: 5,
},
},
AppendContent {
content: "\n" (46..47),
},
Jump {
jump: LabelSlot {
index: 0,
},
},
AppendContent {
content: "\n" (22..23),
},
AppendContent {
content: "\n\n" (56..58),
},
LoadFromContextToSlot {
name: "world" (64..69),
slot: VariableSlot {
index: 15,
},
fail_on_not_found: false,
},
JumpIfUndefined {
slot: VariableSlot {
index: 15,
},
jump: LabelSlot {
index: 14,
},
},
IndexSlotToSlot {
name: "foo" (71..74),
from_slot: VariableSlot {
index: 15,
},
to_slot: VariableSlot {
index: 15,
},
fail_on_not_found: false,
},
JumpIfUndefined {
slot: VariableSlot {
index: 15,
},
jump: LabelSlot {
index: 14,
},
},
LoadFromSlotToSlot {
from_slot: VariableSlot {
index: 15,
},
to_slot: VariableSlot {
index: 13,
},
},
JumpIfUndefined {
slot: VariableSlot {
index: 13,
},
jump: LabelSlot {
index: 12,
},
},
IndexSlotToSlot {
name: "bar" (76..79),
from_slot: VariableSlot {
index: 13,
},
to_slot: VariableSlot {
index: 13,
},
fail_on_not_found: false,
},
JumpIfUndefined {
slot: VariableSlot {
index: 13,
},
jump: LabelSlot {
index: 12,
},
},
LoadFromSlotToSlot {
from_slot: VariableSlot {
index: 13,
},
to_slot: VariableSlot {
index: 11,
},
},
JumpIfUndefined {
slot: VariableSlot {
index: 11,
},
jump: LabelSlot {
index: 10,
},
},
IndexSlotToSlot {
name: "active" (81..87),
from_slot: VariableSlot {
index: 11,
},
to_slot: VariableSlot {
index: 11,
},
fail_on_not_found: true,
},
JumpIfUndefined {
slot: VariableSlot {
index: 11,
},
jump: LabelSlot {
index: 10,
},
},
LoadFromSlotToSlot {
from_slot: VariableSlot {
index: 11,
},
to_slot: VariableSlot {
index: 9,
},
},
JumpIfNotTrue {
emit_slot: VariableSlot {
index: 9,
},
jump: LabelSlot {
index: 16,
},
},
AppendContent {
content: "\n " (90..95),
},
AppendContent {
content: "Weird!" (95..101),
},
AppendContent {
content: "\n" (101..102),
},
Jump {
jump: LabelSlot {
index: 8,
},
},
AppendContent {
content: "\n " (90..95),
},
AppendContent {
content: "\n " (112..117),
},
AppendContent {
content: "Deep access is working :)" (117..142),
},
AppendContent {
content: "\n" (142..143),
},
Jump {
jump: LabelSlot {
index: 8,
},
},
AppendContent {
content: "\n " (112..117),
},
NoOp,
],
}

View file

@ -0,0 +1,11 @@
---
source: tests/file_tests.rs
expression: output
info:
input: "{{ if world?.active }}\nHello {{= world.name }}\n{{ end }}\n\n{{ if world?.foo?.bar?.active }}\n Weird!\n{{ else }}\n Deep access is working :)\n{{ end }}"
context:
world:
active: true
name: World!
---
"\nHello World!\n\n\n\n Deep access is working :)\n"

View file

@ -0,0 +1,16 @@
{
"world": {
"active": true,
"name": "World!"
}
}
---
{{ if world?.active }}
Hello {{= world.name }}
{{ end }}
{{ if world?.foo?.bar?.active }}
Weird!
{{ else }}
Deep access is working :)
{{ end }}