Add parsing of simple conditionals
Signed-off-by: Marcel Müller <neikos@neikos.email>
This commit is contained in:
parent
ffb5c92b89
commit
974086a877
7 changed files with 392 additions and 119 deletions
221
src/ast/mod.rs
221
src/ast/mod.rs
|
|
@ -4,7 +4,9 @@ use winnow::RecoverableParser;
|
||||||
use winnow::combinator::alt;
|
use winnow::combinator::alt;
|
||||||
use winnow::combinator::cut_err;
|
use winnow::combinator::cut_err;
|
||||||
use winnow::combinator::delimited;
|
use winnow::combinator::delimited;
|
||||||
|
use winnow::combinator::not;
|
||||||
use winnow::combinator::opt;
|
use winnow::combinator::opt;
|
||||||
|
use winnow::combinator::preceded;
|
||||||
use winnow::combinator::repeat;
|
use winnow::combinator::repeat;
|
||||||
use winnow::combinator::repeat_till;
|
use winnow::combinator::repeat_till;
|
||||||
use winnow::error::AddContext;
|
use winnow::error::AddContext;
|
||||||
|
|
@ -140,7 +142,7 @@ impl<'input> Parser<Input<'input>, TemplateToken, AstError> for TokenKind {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse(input: &[TemplateToken]) -> Result<TemplateAst<'_>, AstFailure> {
|
pub fn parse(input: &[TemplateToken]) -> Result<TemplateAst<'_>, AstFailure> {
|
||||||
let (_remaining, val, errors) = parse_ast.recoverable_parse(TokenSlice::new(input));
|
let (_remaining, val, errors) = parse_asts.recoverable_parse(TokenSlice::new(input));
|
||||||
|
|
||||||
if errors.is_empty()
|
if errors.is_empty()
|
||||||
&& let Some(val) = val
|
&& let Some(val) = val
|
||||||
|
|
@ -155,23 +157,46 @@ pub fn parse(input: &[TemplateToken]) -> Result<TemplateAst<'_>, AstFailure> {
|
||||||
pub enum TemplateAstExpr<'input> {
|
pub enum TemplateAstExpr<'input> {
|
||||||
StaticContent(TemplateToken),
|
StaticContent(TemplateToken),
|
||||||
Interpolation {
|
Interpolation {
|
||||||
prev_whitespace: Option<TemplateToken>,
|
prev_whitespace_content: Option<TemplateToken>,
|
||||||
wants_output: Option<TemplateToken>,
|
wants_output: TemplateToken,
|
||||||
expression: Box<TemplateAstExpr<'input>>,
|
expression: Box<TemplateAstExpr<'input>>,
|
||||||
post_whitespace: Option<TemplateToken>,
|
post_whitespace_content: Option<TemplateToken>,
|
||||||
|
},
|
||||||
|
Action {
|
||||||
|
prev_whitespace_content: Option<TemplateToken>,
|
||||||
|
expression: Box<TemplateAstExpr<'input>>,
|
||||||
|
post_whitespace_content: Option<TemplateToken>,
|
||||||
},
|
},
|
||||||
VariableAccess(TemplateToken),
|
VariableAccess(TemplateToken),
|
||||||
|
ConditionalChain {
|
||||||
|
chain: Vec<TemplateAstExpr<'input>>,
|
||||||
|
},
|
||||||
|
IfConditional {
|
||||||
|
expression: Box<TemplateAstExpr<'input>>,
|
||||||
|
content: Vec<TemplateAstExpr<'input>>,
|
||||||
|
end_block: Box<TemplateAstExpr<'input>>,
|
||||||
|
},
|
||||||
|
ElseConditional {
|
||||||
|
expression: Vec<TemplateAstExpr<'input>>,
|
||||||
|
},
|
||||||
Invalid(&'input [TemplateToken]),
|
Invalid(&'input [TemplateToken]),
|
||||||
|
EndBlock,
|
||||||
|
Block {
|
||||||
|
prev_whitespace_content: Option<TemplateToken>,
|
||||||
|
expression: Box<TemplateAstExpr<'input>>,
|
||||||
|
post_whitespace_content: Option<TemplateToken>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_ast<'input>(input: &mut Input<'input>) -> Result<Vec<TemplateAstExpr<'input>>, AstError> {
|
fn parse_asts<'input>(input: &mut Input<'input>) -> Result<Vec<TemplateAstExpr<'input>>, AstError> {
|
||||||
repeat(
|
repeat(0.., parse_ast).parse_next(input)
|
||||||
0..,
|
}
|
||||||
|
fn parse_ast<'input>(input: &mut Input<'input>) -> Result<TemplateAstExpr<'input>, AstError> {
|
||||||
alt((
|
alt((
|
||||||
TokenKind::Content.map(TemplateAstExpr::StaticContent),
|
TokenKind::Content.map(TemplateAstExpr::StaticContent),
|
||||||
parse_interpolation,
|
parse_interpolation,
|
||||||
)),
|
parse_action,
|
||||||
)
|
))
|
||||||
.parse_next(input)
|
.parse_next(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -179,16 +204,16 @@ fn parse_interpolation<'input>(
|
||||||
input: &mut Input<'input>,
|
input: &mut Input<'input>,
|
||||||
) -> Result<TemplateAstExpr<'input>, AstError> {
|
) -> Result<TemplateAstExpr<'input>, AstError> {
|
||||||
let expr_parser = resume_after_cut(
|
let expr_parser = resume_after_cut(
|
||||||
alt((parse_variable_access,)),
|
parse_value_expression,
|
||||||
repeat_till(1.., any, TokenKind::RightDelim).map(|((), _)| ()),
|
repeat_till(1.., any, TokenKind::RightDelim).map(|((), _)| ()),
|
||||||
)
|
)
|
||||||
.with_taken()
|
.with_taken()
|
||||||
.map(|(expr, taken)| expr.unwrap_or(TemplateAstExpr::Invalid(taken)));
|
.map(|(expr, taken)| expr.unwrap_or(TemplateAstExpr::Invalid(taken)));
|
||||||
let (prev_whitespace, _left, (wants_output, expression, _right, post_whitespace)) = (
|
let (prev_whitespace, _left, wants_output, (expression, _right, post_whitespace)) = (
|
||||||
opt(TokenKind::Whitespace),
|
opt(TokenKind::Whitespace),
|
||||||
TokenKind::LeftDelim,
|
TokenKind::LeftDelim,
|
||||||
|
TokenKind::WantsOutput,
|
||||||
cut_err((
|
cut_err((
|
||||||
opt(TokenKind::WantsOutput),
|
|
||||||
delimited(ignore_ws, expr_parser, ignore_ws).map(Box::new),
|
delimited(ignore_ws, expr_parser, ignore_ws).map(Box::new),
|
||||||
TokenKind::RightDelim,
|
TokenKind::RightDelim,
|
||||||
opt(TokenKind::Whitespace),
|
opt(TokenKind::Whitespace),
|
||||||
|
|
@ -197,13 +222,89 @@ fn parse_interpolation<'input>(
|
||||||
.parse_next(input)?;
|
.parse_next(input)?;
|
||||||
|
|
||||||
Ok(TemplateAstExpr::Interpolation {
|
Ok(TemplateAstExpr::Interpolation {
|
||||||
prev_whitespace,
|
prev_whitespace_content: prev_whitespace,
|
||||||
wants_output,
|
wants_output,
|
||||||
expression,
|
expression,
|
||||||
post_whitespace,
|
post_whitespace_content: post_whitespace,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_value_expression<'input>(
|
||||||
|
input: &mut Input<'input>,
|
||||||
|
) -> Result<TemplateAstExpr<'input>, AstError> {
|
||||||
|
alt((parse_variable_access,)).parse_next(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_action<'input>(input: &mut Input<'input>) -> Result<TemplateAstExpr<'input>, AstError> {
|
||||||
|
alt((parse_conditional_chain,)).parse_next(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_conditional_chain<'input>(
|
||||||
|
input: &mut Input<'input>,
|
||||||
|
) -> Result<TemplateAstExpr<'input>, AstError> {
|
||||||
|
let if_expression = parse_conditional.parse_next(input)?;
|
||||||
|
let mut chain = vec![];
|
||||||
|
|
||||||
|
let (content, end_block): (Vec<_>, _) =
|
||||||
|
repeat_till(1.., parse_ast, parse_end).parse_next(input)?;
|
||||||
|
|
||||||
|
chain.push(TemplateAstExpr::IfConditional {
|
||||||
|
expression: Box::new(if_expression),
|
||||||
|
content,
|
||||||
|
end_block: Box::new(end_block),
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(TemplateAstExpr::ConditionalChain { chain })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_conditional<'input>(
|
||||||
|
input: &mut Input<'input>,
|
||||||
|
) -> Result<TemplateAstExpr<'input>, AstError> {
|
||||||
|
parse_block(preceded(
|
||||||
|
TokenKind::ConditionalIf,
|
||||||
|
surrounded(ignore_ws, parse_value_expression),
|
||||||
|
))
|
||||||
|
.parse_next(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_end<'input>(input: &mut Input<'input>) -> Result<TemplateAstExpr<'input>, AstError> {
|
||||||
|
parse_block(TokenKind::End.value(TemplateAstExpr::EndBlock)).parse_next(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_block<'input, ParseNext>(
|
||||||
|
parser: ParseNext,
|
||||||
|
) -> impl Parser<Input<'input>, TemplateAstExpr<'input>, AstError>
|
||||||
|
where
|
||||||
|
ParseNext: Parser<Input<'input>, TemplateAstExpr<'input>, AstError>,
|
||||||
|
{
|
||||||
|
let expr_parser = resume_after_cut(
|
||||||
|
parser,
|
||||||
|
repeat_till(1.., any, TokenKind::RightDelim).map(|((), _)| ()),
|
||||||
|
)
|
||||||
|
.with_taken()
|
||||||
|
.map(|(expr, taken)| expr.unwrap_or(TemplateAstExpr::Invalid(taken)));
|
||||||
|
|
||||||
|
(
|
||||||
|
opt(TokenKind::Whitespace),
|
||||||
|
TokenKind::LeftDelim,
|
||||||
|
not(TokenKind::WantsOutput),
|
||||||
|
cut_err((
|
||||||
|
delimited(ignore_ws, expr_parser.map(Box::new), ignore_ws),
|
||||||
|
TokenKind::RightDelim,
|
||||||
|
opt(TokenKind::Whitespace),
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
.map(
|
||||||
|
|(prev_whitespace, _left, _not_token, (expression, _right, post_whitespace))| {
|
||||||
|
TemplateAstExpr::Block {
|
||||||
|
prev_whitespace_content: prev_whitespace,
|
||||||
|
expression,
|
||||||
|
post_whitespace_content: post_whitespace,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_variable_access<'input>(
|
fn parse_variable_access<'input>(
|
||||||
input: &mut Input<'input>,
|
input: &mut Input<'input>,
|
||||||
) -> Result<TemplateAstExpr<'input>, AstError> {
|
) -> Result<TemplateAstExpr<'input>, AstError> {
|
||||||
|
|
@ -216,6 +317,20 @@ fn ignore_ws<'input>(input: &mut Input<'input>) -> Result<(), AstError> {
|
||||||
repeat(.., TokenKind::Whitespace).parse_next(input)
|
repeat(.., TokenKind::Whitespace).parse_next(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn surrounded<Input, IgnoredParser, Ignored1, Output, Error, ParseNext>(
|
||||||
|
ignored: IgnoredParser,
|
||||||
|
parser: ParseNext,
|
||||||
|
) -> impl Parser<Input, Output, Error>
|
||||||
|
where
|
||||||
|
Input: Stream,
|
||||||
|
Error: ParserError<Input>,
|
||||||
|
IgnoredParser: Parser<Input, Ignored1, Error>,
|
||||||
|
IgnoredParser: Clone,
|
||||||
|
ParseNext: Parser<Input, Output, Error>,
|
||||||
|
{
|
||||||
|
delimited(ignored.clone(), parser, ignored)
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::ast::parse;
|
use crate::ast::parse;
|
||||||
|
|
@ -260,28 +375,96 @@ mod tests {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
Interpolation {
|
Interpolation {
|
||||||
prev_whitespace: Some(
|
prev_whitespace_content: Some(
|
||||||
TemplateToken {
|
TemplateToken {
|
||||||
kind: Whitespace,
|
kind: Whitespace,
|
||||||
source: " ",
|
source: " ",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
wants_output: Some(
|
wants_output: TemplateToken {
|
||||||
TemplateToken {
|
|
||||||
kind: WantsOutput,
|
kind: WantsOutput,
|
||||||
source: "=",
|
source: "=",
|
||||||
},
|
},
|
||||||
),
|
|
||||||
expression: VariableAccess(
|
expression: VariableAccess(
|
||||||
TemplateToken {
|
TemplateToken {
|
||||||
kind: Ident,
|
kind: Ident,
|
||||||
source: "world",
|
source: "world",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
post_whitespace: None,
|
post_whitespace_content: None,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
"#);
|
"#);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_simple_if() {
|
||||||
|
let input = "{{ if foo }} Hiii {{ end }}";
|
||||||
|
|
||||||
|
let parsed = crate::parser::parse(input.into()).unwrap();
|
||||||
|
|
||||||
|
let ast = parse(parsed.tokens()).unwrap();
|
||||||
|
|
||||||
|
insta::assert_debug_snapshot!(ast, @r#"
|
||||||
|
TemplateAst {
|
||||||
|
root: [
|
||||||
|
ConditionalChain {
|
||||||
|
chain: [
|
||||||
|
IfConditional {
|
||||||
|
expression: Block {
|
||||||
|
prev_whitespace_content: None,
|
||||||
|
expression: VariableAccess(
|
||||||
|
TemplateToken {
|
||||||
|
kind: Ident,
|
||||||
|
source: "foo",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
post_whitespace_content: Some(
|
||||||
|
TemplateToken {
|
||||||
|
kind: Whitespace,
|
||||||
|
source: " ",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
content: [
|
||||||
|
StaticContent(
|
||||||
|
TemplateToken {
|
||||||
|
kind: Content,
|
||||||
|
source: "Hiii",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
end_block: Block {
|
||||||
|
prev_whitespace_content: Some(
|
||||||
|
TemplateToken {
|
||||||
|
kind: Whitespace,
|
||||||
|
source: " ",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
expression: EndBlock,
|
||||||
|
post_whitespace_content: None,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
"#);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_nested_simple_if() {
|
||||||
|
let input = r#"{{ if foo }}
|
||||||
|
{{ if bar }}
|
||||||
|
Hiii
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}"#;
|
||||||
|
|
||||||
|
let parsed = crate::parser::parse(input.into()).unwrap();
|
||||||
|
|
||||||
|
let ast = parse(parsed.tokens()).unwrap();
|
||||||
|
|
||||||
|
insta::assert_debug_snapshot!(ast);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,84 @@
|
||||||
|
---
|
||||||
|
source: src/ast/mod.rs
|
||||||
|
expression: ast
|
||||||
|
---
|
||||||
|
TemplateAst {
|
||||||
|
root: [
|
||||||
|
ConditionalChain {
|
||||||
|
chain: [
|
||||||
|
IfConditional {
|
||||||
|
expression: Block {
|
||||||
|
prev_whitespace_content: None,
|
||||||
|
expression: VariableAccess(
|
||||||
|
TemplateToken {
|
||||||
|
kind: Ident,
|
||||||
|
source: "foo",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
post_whitespace_content: Some(
|
||||||
|
TemplateToken {
|
||||||
|
kind: Whitespace,
|
||||||
|
source: "
|
||||||
|
",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
content: [
|
||||||
|
ConditionalChain {
|
||||||
|
chain: [
|
||||||
|
IfConditional {
|
||||||
|
expression: Block {
|
||||||
|
prev_whitespace_content: None,
|
||||||
|
expression: VariableAccess(
|
||||||
|
TemplateToken {
|
||||||
|
kind: Ident,
|
||||||
|
source: "bar",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
post_whitespace_content: Some(
|
||||||
|
TemplateToken {
|
||||||
|
kind: Whitespace,
|
||||||
|
source: "
|
||||||
|
",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
content: [
|
||||||
|
StaticContent(
|
||||||
|
TemplateToken {
|
||||||
|
kind: Content,
|
||||||
|
source: "Hiii",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
end_block: Block {
|
||||||
|
prev_whitespace_content: Some(
|
||||||
|
TemplateToken {
|
||||||
|
kind: Whitespace,
|
||||||
|
source: "
|
||||||
|
",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
expression: EndBlock,
|
||||||
|
post_whitespace_content: Some(
|
||||||
|
TemplateToken {
|
||||||
|
kind: Whitespace,
|
||||||
|
source: "
|
||||||
|
",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
end_block: Block {
|
||||||
|
prev_whitespace_content: None,
|
||||||
|
expression: EndBlock,
|
||||||
|
post_whitespace_content: None,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
@ -24,19 +24,10 @@ pub struct VariableSlot {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Instruction {
|
pub enum Instruction {
|
||||||
AppendContent {
|
AppendContent { content: NomoInput },
|
||||||
content: NomoInput,
|
LoadFromContextToSlot { name: NomoInput, slot: VariableSlot },
|
||||||
},
|
EmitFromSlot { slot: VariableSlot },
|
||||||
LoadFromContextToSlot {
|
PushScope { inherit_parent: bool },
|
||||||
name: NomoInput,
|
|
||||||
slot: VariableSlot,
|
|
||||||
},
|
|
||||||
EmitFromSlot {
|
|
||||||
slot: VariableSlot,
|
|
||||||
},
|
|
||||||
PushScope {
|
|
||||||
inherit_parent: bool,
|
|
||||||
},
|
|
||||||
Abort,
|
Abort,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -64,10 +55,10 @@ fn emit_ast_expr(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
TemplateAstExpr::Interpolation {
|
TemplateAstExpr::Interpolation {
|
||||||
prev_whitespace,
|
prev_whitespace_content: prev_whitespace,
|
||||||
wants_output,
|
wants_output,
|
||||||
expression,
|
expression,
|
||||||
post_whitespace,
|
post_whitespace_content: post_whitespace,
|
||||||
} => {
|
} => {
|
||||||
if let Some(ws) = prev_whitespace {
|
if let Some(ws) = prev_whitespace {
|
||||||
eval.push(Instruction::AppendContent {
|
eval.push(Instruction::AppendContent {
|
||||||
|
|
@ -77,10 +68,7 @@ fn emit_ast_expr(
|
||||||
|
|
||||||
let emit_slot = machine.reserve_slot();
|
let emit_slot = machine.reserve_slot();
|
||||||
emit_expr(machine, eval, emit_slot, expression);
|
emit_expr(machine, eval, emit_slot, expression);
|
||||||
|
|
||||||
if wants_output.is_some() {
|
|
||||||
eval.push(Instruction::EmitFromSlot { slot: emit_slot });
|
eval.push(Instruction::EmitFromSlot { slot: emit_slot });
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(ws) = post_whitespace {
|
if let Some(ws) = post_whitespace {
|
||||||
eval.push(Instruction::AppendContent {
|
eval.push(Instruction::AppendContent {
|
||||||
|
|
@ -91,6 +79,24 @@ fn emit_ast_expr(
|
||||||
TemplateAstExpr::Invalid { .. } | TemplateAstExpr::VariableAccess { .. } => {
|
TemplateAstExpr::Invalid { .. } | TemplateAstExpr::VariableAccess { .. } => {
|
||||||
eval.push(Instruction::Abort)
|
eval.push(Instruction::Abort)
|
||||||
}
|
}
|
||||||
|
TemplateAstExpr::ConditionalChain { chain } => todo!(),
|
||||||
|
TemplateAstExpr::ElseConditional { expression } => todo!(),
|
||||||
|
TemplateAstExpr::Action {
|
||||||
|
prev_whitespace_content,
|
||||||
|
expression,
|
||||||
|
post_whitespace_content,
|
||||||
|
} => todo!(),
|
||||||
|
TemplateAstExpr::EndBlock => todo!(),
|
||||||
|
TemplateAstExpr::Block {
|
||||||
|
prev_whitespace_content,
|
||||||
|
expression,
|
||||||
|
post_whitespace_content,
|
||||||
|
} => todo!(),
|
||||||
|
TemplateAstExpr::IfConditional {
|
||||||
|
expression,
|
||||||
|
content,
|
||||||
|
end_block,
|
||||||
|
} => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -111,6 +117,24 @@ fn emit_expr(
|
||||||
TemplateAstExpr::StaticContent { .. } | TemplateAstExpr::Interpolation { .. } => {
|
TemplateAstExpr::StaticContent { .. } | TemplateAstExpr::Interpolation { .. } => {
|
||||||
unreachable!("Invalid AST here")
|
unreachable!("Invalid AST here")
|
||||||
}
|
}
|
||||||
|
TemplateAstExpr::ConditionalChain { chain } => todo!(),
|
||||||
|
TemplateAstExpr::ElseConditional { expression } => todo!(),
|
||||||
|
TemplateAstExpr::Action {
|
||||||
|
prev_whitespace_content,
|
||||||
|
expression,
|
||||||
|
post_whitespace_content,
|
||||||
|
} => todo!(),
|
||||||
|
TemplateAstExpr::EndBlock => todo!(),
|
||||||
|
TemplateAstExpr::Block {
|
||||||
|
prev_whitespace_content,
|
||||||
|
expression,
|
||||||
|
post_whitespace_content,
|
||||||
|
} => todo!(),
|
||||||
|
TemplateAstExpr::IfConditional {
|
||||||
|
expression,
|
||||||
|
content,
|
||||||
|
end_block,
|
||||||
|
} => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -420,7 +420,7 @@ fn parse_ident<'input>(input: &mut Input<'input>) -> PResult<'input, TemplateTok
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ident<'input>(input: &mut Input<'input>) -> PResult<'input, NomoInput> {
|
fn ident<'input>(input: &mut Input<'input>) -> PResult<'input, NomoInput> {
|
||||||
peek(not(parse_literal))
|
peek(not(alt((parse_literal, parse_condition, parse_end))))
|
||||||
.context(ParseError::ctx().msg("Expected an ident, but found a literal instead"))
|
.context(ParseError::ctx().msg("Expected an ident, but found a literal instead"))
|
||||||
.parse_next(input)?;
|
.parse_next(input)?;
|
||||||
|
|
||||||
|
|
@ -564,7 +564,7 @@ mod tests {
|
||||||
source: " ",
|
source: " ",
|
||||||
},
|
},
|
||||||
TemplateToken {
|
TemplateToken {
|
||||||
kind: Ident,
|
kind: ConditionalIf,
|
||||||
source: "if",
|
source: "if",
|
||||||
},
|
},
|
||||||
TemplateToken {
|
TemplateToken {
|
||||||
|
|
@ -608,7 +608,7 @@ mod tests {
|
||||||
source: " ",
|
source: " ",
|
||||||
},
|
},
|
||||||
TemplateToken {
|
TemplateToken {
|
||||||
kind: Ident,
|
kind: End,
|
||||||
source: "end",
|
source: "end",
|
||||||
},
|
},
|
||||||
TemplateToken {
|
TemplateToken {
|
||||||
|
|
|
||||||
|
|
@ -6,20 +6,18 @@ input_file: tests/cases/identifiers.nomo
|
||||||
TemplateAst {
|
TemplateAst {
|
||||||
root: [
|
root: [
|
||||||
Interpolation {
|
Interpolation {
|
||||||
prev_whitespace: None,
|
prev_whitespace_content: None,
|
||||||
wants_output: Some(
|
wants_output: TemplateToken {
|
||||||
TemplateToken {
|
|
||||||
kind: WantsOutput,
|
kind: WantsOutput,
|
||||||
source: "=",
|
source: "=",
|
||||||
},
|
},
|
||||||
),
|
|
||||||
expression: VariableAccess(
|
expression: VariableAccess(
|
||||||
TemplateToken {
|
TemplateToken {
|
||||||
kind: Ident,
|
kind: Ident,
|
||||||
source: "_name",
|
source: "_name",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
post_whitespace: Some(
|
post_whitespace_content: Some(
|
||||||
TemplateToken {
|
TemplateToken {
|
||||||
kind: Whitespace,
|
kind: Whitespace,
|
||||||
source: "
|
source: "
|
||||||
|
|
@ -28,20 +26,18 @@ TemplateAst {
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
Interpolation {
|
Interpolation {
|
||||||
prev_whitespace: None,
|
prev_whitespace_content: None,
|
||||||
wants_output: Some(
|
wants_output: TemplateToken {
|
||||||
TemplateToken {
|
|
||||||
kind: WantsOutput,
|
kind: WantsOutput,
|
||||||
source: "=",
|
source: "=",
|
||||||
},
|
},
|
||||||
),
|
|
||||||
expression: VariableAccess(
|
expression: VariableAccess(
|
||||||
TemplateToken {
|
TemplateToken {
|
||||||
kind: Ident,
|
kind: Ident,
|
||||||
source: "a_name",
|
source: "a_name",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
post_whitespace: Some(
|
post_whitespace_content: Some(
|
||||||
TemplateToken {
|
TemplateToken {
|
||||||
kind: Whitespace,
|
kind: Whitespace,
|
||||||
source: "
|
source: "
|
||||||
|
|
@ -50,20 +46,18 @@ TemplateAst {
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
Interpolation {
|
Interpolation {
|
||||||
prev_whitespace: None,
|
prev_whitespace_content: None,
|
||||||
wants_output: Some(
|
wants_output: TemplateToken {
|
||||||
TemplateToken {
|
|
||||||
kind: WantsOutput,
|
kind: WantsOutput,
|
||||||
source: "=",
|
source: "=",
|
||||||
},
|
},
|
||||||
),
|
|
||||||
expression: VariableAccess(
|
expression: VariableAccess(
|
||||||
TemplateToken {
|
TemplateToken {
|
||||||
kind: Ident,
|
kind: Ident,
|
||||||
source: "1name",
|
source: "1name",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
post_whitespace: Some(
|
post_whitespace_content: Some(
|
||||||
TemplateToken {
|
TemplateToken {
|
||||||
kind: Whitespace,
|
kind: Whitespace,
|
||||||
source: "
|
source: "
|
||||||
|
|
@ -72,20 +66,18 @@ TemplateAst {
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
Interpolation {
|
Interpolation {
|
||||||
prev_whitespace: None,
|
prev_whitespace_content: None,
|
||||||
wants_output: Some(
|
wants_output: TemplateToken {
|
||||||
TemplateToken {
|
|
||||||
kind: WantsOutput,
|
kind: WantsOutput,
|
||||||
source: "=",
|
source: "=",
|
||||||
},
|
},
|
||||||
),
|
|
||||||
expression: VariableAccess(
|
expression: VariableAccess(
|
||||||
TemplateToken {
|
TemplateToken {
|
||||||
kind: Ident,
|
kind: Ident,
|
||||||
source: "_name1",
|
source: "_name1",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
post_whitespace: Some(
|
post_whitespace_content: Some(
|
||||||
TemplateToken {
|
TemplateToken {
|
||||||
kind: Whitespace,
|
kind: Whitespace,
|
||||||
source: "
|
source: "
|
||||||
|
|
@ -94,20 +86,18 @@ TemplateAst {
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
Interpolation {
|
Interpolation {
|
||||||
prev_whitespace: None,
|
prev_whitespace_content: None,
|
||||||
wants_output: Some(
|
wants_output: TemplateToken {
|
||||||
TemplateToken {
|
|
||||||
kind: WantsOutput,
|
kind: WantsOutput,
|
||||||
source: "=",
|
source: "=",
|
||||||
},
|
},
|
||||||
),
|
|
||||||
expression: VariableAccess(
|
expression: VariableAccess(
|
||||||
TemplateToken {
|
TemplateToken {
|
||||||
kind: Ident,
|
kind: Ident,
|
||||||
source: "_namE",
|
source: "_namE",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
post_whitespace: Some(
|
post_whitespace_content: Some(
|
||||||
TemplateToken {
|
TemplateToken {
|
||||||
kind: Whitespace,
|
kind: Whitespace,
|
||||||
source: "
|
source: "
|
||||||
|
|
@ -116,20 +106,18 @@ TemplateAst {
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
Interpolation {
|
Interpolation {
|
||||||
prev_whitespace: None,
|
prev_whitespace_content: None,
|
||||||
wants_output: Some(
|
wants_output: TemplateToken {
|
||||||
TemplateToken {
|
|
||||||
kind: WantsOutput,
|
kind: WantsOutput,
|
||||||
source: "=",
|
source: "=",
|
||||||
},
|
},
|
||||||
),
|
|
||||||
expression: VariableAccess(
|
expression: VariableAccess(
|
||||||
TemplateToken {
|
TemplateToken {
|
||||||
kind: Ident,
|
kind: Ident,
|
||||||
source: "name1",
|
source: "name1",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
post_whitespace: None,
|
post_whitespace_content: None,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,25 +12,23 @@ TemplateAst {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
Interpolation {
|
Interpolation {
|
||||||
prev_whitespace: Some(
|
prev_whitespace_content: Some(
|
||||||
TemplateToken {
|
TemplateToken {
|
||||||
kind: Whitespace,
|
kind: Whitespace,
|
||||||
source: " ",
|
source: " ",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
wants_output: Some(
|
wants_output: TemplateToken {
|
||||||
TemplateToken {
|
|
||||||
kind: WantsOutput,
|
kind: WantsOutput,
|
||||||
source: "=",
|
source: "=",
|
||||||
},
|
},
|
||||||
),
|
|
||||||
expression: VariableAccess(
|
expression: VariableAccess(
|
||||||
TemplateToken {
|
TemplateToken {
|
||||||
kind: Ident,
|
kind: Ident,
|
||||||
source: "name",
|
source: "name",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
post_whitespace: None,
|
post_whitespace_content: None,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,25 +12,23 @@ TemplateAst {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
Interpolation {
|
Interpolation {
|
||||||
prev_whitespace: Some(
|
prev_whitespace_content: Some(
|
||||||
TemplateToken {
|
TemplateToken {
|
||||||
kind: Whitespace,
|
kind: Whitespace,
|
||||||
source: " ",
|
source: " ",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
wants_output: Some(
|
wants_output: TemplateToken {
|
||||||
TemplateToken {
|
|
||||||
kind: WantsOutput,
|
kind: WantsOutput,
|
||||||
source: "=",
|
source: "=",
|
||||||
},
|
},
|
||||||
),
|
|
||||||
expression: VariableAccess(
|
expression: VariableAccess(
|
||||||
TemplateToken {
|
TemplateToken {
|
||||||
kind: Ident,
|
kind: Ident,
|
||||||
source: "name",
|
source: "name",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
post_whitespace: Some(
|
post_whitespace_content: Some(
|
||||||
TemplateToken {
|
TemplateToken {
|
||||||
kind: Whitespace,
|
kind: Whitespace,
|
||||||
source: " ",
|
source: " ",
|
||||||
|
|
@ -38,20 +36,18 @@ TemplateAst {
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
Interpolation {
|
Interpolation {
|
||||||
prev_whitespace: None,
|
prev_whitespace_content: None,
|
||||||
wants_output: Some(
|
wants_output: TemplateToken {
|
||||||
TemplateToken {
|
|
||||||
kind: WantsOutput,
|
kind: WantsOutput,
|
||||||
source: "=",
|
source: "=",
|
||||||
},
|
},
|
||||||
),
|
|
||||||
expression: VariableAccess(
|
expression: VariableAccess(
|
||||||
TemplateToken {
|
TemplateToken {
|
||||||
kind: Ident,
|
kind: Ident,
|
||||||
source: "lastname",
|
source: "lastname",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
post_whitespace: None,
|
post_whitespace_content: None,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue