Allow identifiers to contain underscore

Signed-off-by: Marcel Müller <neikos@neikos.email>
This commit is contained in:
Marcel Müller 2026-03-06 15:45:39 +01:00
parent e158450d18
commit 10a33dc935
6 changed files with 428 additions and 1 deletions

View file

@ -396,7 +396,7 @@ fn parse_ident<'input>(input: &mut Input<'input>) -> PResult<'input, TemplateTok
}
fn ident<'input>(input: &mut Input<'input>) -> PResult<'input, TempleInput> {
take_while(1.., char::is_alphanumeric).parse_next(input)
take_while(1.., |c: char| c.is_alphanumeric() || "_".contains(c)).parse_next(input)
}
fn bad_ident<'input>(input: &mut Input<'input>) -> PResult<'input, ()> {

View file

@ -0,0 +1,178 @@
---
source: tests/file_tests.rs
expression: parsed
input_file: tests/cases/identifiers.temple
---
ParsedTemplate {
tokens: [
TemplateToken {
kind: LeftDelim,
source: "{{",
},
TemplateToken {
kind: WantsOutput,
source: "=",
},
TemplateToken {
kind: Whitespace,
source: " ",
},
TemplateToken {
kind: Ident,
source: "_name",
},
TemplateToken {
kind: Whitespace,
source: " ",
},
TemplateToken {
kind: RightDelim,
source: "}}",
},
TemplateToken {
kind: Whitespace,
source: "
",
},
TemplateToken {
kind: LeftDelim,
source: "{{",
},
TemplateToken {
kind: WantsOutput,
source: "=",
},
TemplateToken {
kind: Whitespace,
source: " ",
},
TemplateToken {
kind: Ident,
source: "a_name",
},
TemplateToken {
kind: Whitespace,
source: " ",
},
TemplateToken {
kind: RightDelim,
source: "}}",
},
TemplateToken {
kind: Whitespace,
source: "
",
},
TemplateToken {
kind: LeftDelim,
source: "{{",
},
TemplateToken {
kind: WantsOutput,
source: "=",
},
TemplateToken {
kind: Whitespace,
source: " ",
},
TemplateToken {
kind: Ident,
source: "1name",
},
TemplateToken {
kind: Whitespace,
source: " ",
},
TemplateToken {
kind: RightDelim,
source: "}}",
},
TemplateToken {
kind: Whitespace,
source: "
",
},
TemplateToken {
kind: LeftDelim,
source: "{{",
},
TemplateToken {
kind: WantsOutput,
source: "=",
},
TemplateToken {
kind: Whitespace,
source: " ",
},
TemplateToken {
kind: Ident,
source: "_name1",
},
TemplateToken {
kind: Whitespace,
source: " ",
},
TemplateToken {
kind: RightDelim,
source: "}}",
},
TemplateToken {
kind: Whitespace,
source: "
",
},
TemplateToken {
kind: LeftDelim,
source: "{{",
},
TemplateToken {
kind: WantsOutput,
source: "=",
},
TemplateToken {
kind: Whitespace,
source: " ",
},
TemplateToken {
kind: Ident,
source: "_namE",
},
TemplateToken {
kind: Whitespace,
source: " ",
},
TemplateToken {
kind: RightDelim,
source: "}}",
},
TemplateToken {
kind: Whitespace,
source: "
",
},
TemplateToken {
kind: LeftDelim,
source: "{{",
},
TemplateToken {
kind: WantsOutput,
source: "=",
},
TemplateToken {
kind: Whitespace,
source: " ",
},
TemplateToken {
kind: Ident,
source: "name1",
},
TemplateToken {
kind: Whitespace,
source: " ",
},
TemplateToken {
kind: RightDelim,
source: "}}",
},
],
}

View file

@ -0,0 +1,135 @@
---
source: tests/file_tests.rs
expression: ast
input_file: tests/cases/identifiers.temple
---
TemplateAst {
root: [
Interpolation {
prev_whitespace: None,
wants_output: Some(
TemplateToken {
kind: WantsOutput,
source: "=",
},
),
expression: VariableAccess(
TemplateToken {
kind: Ident,
source: "_name",
},
),
post_whitespace: Some(
TemplateToken {
kind: Whitespace,
source: "
",
},
),
},
Interpolation {
prev_whitespace: None,
wants_output: Some(
TemplateToken {
kind: WantsOutput,
source: "=",
},
),
expression: VariableAccess(
TemplateToken {
kind: Ident,
source: "a_name",
},
),
post_whitespace: Some(
TemplateToken {
kind: Whitespace,
source: "
",
},
),
},
Interpolation {
prev_whitespace: None,
wants_output: Some(
TemplateToken {
kind: WantsOutput,
source: "=",
},
),
expression: VariableAccess(
TemplateToken {
kind: Ident,
source: "1name",
},
),
post_whitespace: Some(
TemplateToken {
kind: Whitespace,
source: "
",
},
),
},
Interpolation {
prev_whitespace: None,
wants_output: Some(
TemplateToken {
kind: WantsOutput,
source: "=",
},
),
expression: VariableAccess(
TemplateToken {
kind: Ident,
source: "_name1",
},
),
post_whitespace: Some(
TemplateToken {
kind: Whitespace,
source: "
",
},
),
},
Interpolation {
prev_whitespace: None,
wants_output: Some(
TemplateToken {
kind: WantsOutput,
source: "=",
},
),
expression: VariableAccess(
TemplateToken {
kind: Ident,
source: "_namE",
},
),
post_whitespace: Some(
TemplateToken {
kind: Whitespace,
source: "
",
},
),
},
Interpolation {
prev_whitespace: None,
wants_output: Some(
TemplateToken {
kind: WantsOutput,
source: "=",
},
),
expression: VariableAccess(
TemplateToken {
kind: Ident,
source: "name1",
},
),
post_whitespace: None,
},
],
}

View file

@ -0,0 +1,93 @@
---
source: tests/file_tests.rs
expression: emit
input_file: tests/cases/identifiers.temple
---
[
LoadFromContextToSlot {
name: "_name",
slot: VariableSlot {
index: 0,
},
},
EmitFromSlot {
slot: VariableSlot {
index: 0,
},
},
AppendContent {
content: "
",
},
LoadFromContextToSlot {
name: "a_name",
slot: VariableSlot {
index: 1,
},
},
EmitFromSlot {
slot: VariableSlot {
index: 1,
},
},
AppendContent {
content: "
",
},
LoadFromContextToSlot {
name: "1name",
slot: VariableSlot {
index: 2,
},
},
EmitFromSlot {
slot: VariableSlot {
index: 2,
},
},
AppendContent {
content: "
",
},
LoadFromContextToSlot {
name: "_name1",
slot: VariableSlot {
index: 3,
},
},
EmitFromSlot {
slot: VariableSlot {
index: 3,
},
},
AppendContent {
content: "
",
},
LoadFromContextToSlot {
name: "_namE",
slot: VariableSlot {
index: 4,
},
},
EmitFromSlot {
slot: VariableSlot {
index: 4,
},
},
AppendContent {
content: "
",
},
LoadFromContextToSlot {
name: "name1",
slot: VariableSlot {
index: 5,
},
},
EmitFromSlot {
slot: VariableSlot {
index: 5,
},
},
]

View file

@ -0,0 +1,6 @@
---
source: tests/file_tests.rs
expression: output
input_file: tests/cases/identifiers.temple
---
"Foo\nFoo\nFoo\nFoo\nFoo\nFoo"

View file

@ -0,0 +1,15 @@
{
"_name": "Foo",
"a_name": "Foo",
"1name": "Foo",
"_name1": "Foo",
"_namE": "Foo",
"name1": "Foo"
}
---
{{= _name }}
{{= a_name }}
{{= 1name }}
{{= _name1 }}
{{= _namE }}
{{= name1 }}