Compare commits
No commits in common. "8c02dbd672e7624df982ac092fd489e6e20b68f7" and "474324726a740e1576a0b7b1930448d1d14564af" have entirely different histories.
8c02dbd672
...
474324726a
8 changed files with 53 additions and 318 deletions
|
|
@ -1,12 +1,9 @@
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use winnow::Parser;
|
use winnow::Parser;
|
||||||
use winnow::RecoverableParser;
|
use winnow::RecoverableParser;
|
||||||
use winnow::combinator::Infix::Left;
|
|
||||||
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::dispatch;
|
|
||||||
use winnow::combinator::expression;
|
|
||||||
use winnow::combinator::not;
|
use winnow::combinator::not;
|
||||||
use winnow::combinator::opt;
|
use winnow::combinator::opt;
|
||||||
use winnow::combinator::peek;
|
use winnow::combinator::peek;
|
||||||
|
|
@ -27,9 +24,7 @@ use winnow::token::any;
|
||||||
use crate::SourceSpan;
|
use crate::SourceSpan;
|
||||||
use crate::parser::TemplateToken;
|
use crate::parser::TemplateToken;
|
||||||
use crate::parser::TokenKind;
|
use crate::parser::TokenKind;
|
||||||
use crate::parser::TokenOperator;
|
|
||||||
use crate::resume_after_cut;
|
use crate::resume_after_cut;
|
||||||
use crate::value::NomoValue;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct TemplateAst<'input> {
|
pub struct TemplateAst<'input> {
|
||||||
|
|
@ -258,16 +253,7 @@ pub enum TemplateAstExpr<'input> {
|
||||||
expression: Option<Box<TemplateAstExpr<'input>>>,
|
expression: Option<Box<TemplateAstExpr<'input>>>,
|
||||||
},
|
},
|
||||||
Invalid(&'input [TemplateToken]),
|
Invalid(&'input [TemplateToken]),
|
||||||
Operation {
|
|
||||||
op: TokenOperator,
|
|
||||||
lhs: Box<TemplateAstExpr<'input>>,
|
|
||||||
rhs: Box<TemplateAstExpr<'input>>,
|
|
||||||
},
|
|
||||||
EndBlock,
|
EndBlock,
|
||||||
Literal {
|
|
||||||
source: TemplateToken,
|
|
||||||
value: NomoValue,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_asts<'input>(input: &mut Input<'input>) -> Result<Vec<TemplateAstExpr<'input>>, AstError> {
|
fn parse_asts<'input>(input: &mut Input<'input>) -> Result<Vec<TemplateAstExpr<'input>>, AstError> {
|
||||||
|
|
@ -289,7 +275,7 @@ 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(
|
||||||
parse_expression,
|
parse_value_expression,
|
||||||
repeat_till(
|
repeat_till(
|
||||||
0..,
|
0..,
|
||||||
any,
|
any,
|
||||||
|
|
@ -411,7 +397,7 @@ fn parse_for_loop<'input>(input: &mut Input<'input>) -> Result<TemplateAstExpr<'
|
||||||
ws,
|
ws,
|
||||||
TokenKind::In,
|
TokenKind::In,
|
||||||
ws,
|
ws,
|
||||||
parse_expression.map(Box::new),
|
parse_value_expression.map(Box::new),
|
||||||
)
|
)
|
||||||
.map(|(_, _for, _, value_ident, _, _in, _, value_expression)| {
|
.map(|(_, _for, _, value_ident, _, _in, _, value_expression)| {
|
||||||
TemplateAstExpr::For {
|
TemplateAstExpr::For {
|
||||||
|
|
@ -503,7 +489,7 @@ fn parse_conditional_if<'input>(
|
||||||
preceded(
|
preceded(
|
||||||
TokenKind::ConditionalIf,
|
TokenKind::ConditionalIf,
|
||||||
cut_err(
|
cut_err(
|
||||||
surrounded(ws, parse_expression)
|
surrounded(ws, parse_value_expression)
|
||||||
.map(Box::new)
|
.map(Box::new)
|
||||||
.context(AstError::ctx().msg("Expected an expression after 'if'")),
|
.context(AstError::ctx().msg("Expected an expression after 'if'")),
|
||||||
),
|
),
|
||||||
|
|
@ -524,7 +510,7 @@ fn parse_conditional_else<'input>(
|
||||||
surrounded(ws, TokenKind::ConditionalElse),
|
surrounded(ws, TokenKind::ConditionalElse),
|
||||||
opt(preceded(
|
opt(preceded(
|
||||||
TokenKind::ConditionalIf,
|
TokenKind::ConditionalIf,
|
||||||
cut_err(surrounded(ws, parse_expression)).map(Box::new),
|
cut_err(surrounded(ws, parse_value_expression)).map(Box::new),
|
||||||
)),
|
)),
|
||||||
)
|
)
|
||||||
.map(|else_expr| TemplateAstExpr::ElseConditional {
|
.map(|else_expr| TemplateAstExpr::ElseConditional {
|
||||||
|
|
@ -559,6 +545,12 @@ fn parse_end<'input>(input: &mut Input<'input>) -> Result<TemplateAstExpr<'input
|
||||||
.parse_next(input)
|
.parse_next(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_value_expression<'input>(
|
||||||
|
input: &mut Input<'input>,
|
||||||
|
) -> Result<TemplateAstExpr<'input>, AstError> {
|
||||||
|
trace("value_expression", alt((parse_variable_access,))).parse_next(input)
|
||||||
|
}
|
||||||
|
|
||||||
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> {
|
||||||
|
|
@ -619,55 +611,6 @@ where
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_operand<'input>(input: &mut Input<'input>) -> Result<TemplateAstExpr<'input>, AstError> {
|
|
||||||
trace("operand", alt((parse_variable_access, parse_literal))).parse_next(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_literal<'input>(input: &mut Input<'input>) -> Result<TemplateAstExpr<'input>, AstError> {
|
|
||||||
trace(
|
|
||||||
"literal",
|
|
||||||
any.verify_map(|token: &TemplateToken| match token.kind() {
|
|
||||||
TokenKind::Literal(literal) => Some(TemplateAstExpr::Literal {
|
|
||||||
source: token.clone(),
|
|
||||||
value: match literal {
|
|
||||||
crate::parser::TokenLiteral::Bool(bool) => NomoValue::Bool { value: bool },
|
|
||||||
crate::parser::TokenLiteral::Integer(int) => NomoValue::Integer { value: int },
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
_ => None,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.parse_next(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_operator<'input>(input: &mut Input<'input>) -> Result<TokenOperator, AstError> {
|
|
||||||
trace(
|
|
||||||
"operator",
|
|
||||||
any.verify_map(|t: &'input TemplateToken| match t.kind() {
|
|
||||||
TokenKind::Operator(op) => Some(op),
|
|
||||||
_ => None,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.parse_next(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_expression<'input>(
|
|
||||||
input: &mut Input<'input>,
|
|
||||||
) -> Result<TemplateAstExpr<'input>, AstError> {
|
|
||||||
trace(
|
|
||||||
"expression",
|
|
||||||
expression(surrounded(ws, parse_operand)).infix(dispatch! { surrounded(ws, parse_operator);
|
|
||||||
TokenOperator::Plus => Left(5, |_, lhs, rhs| Ok(TemplateAstExpr::Operation { op: TokenOperator::Plus, lhs: Box::new(lhs), rhs: Box::new(rhs) })),
|
|
||||||
TokenOperator::Minus => Left(5, |_, lhs, rhs| Ok(TemplateAstExpr::Operation { op: TokenOperator::Minus, lhs: Box::new(lhs), rhs: Box::new(rhs) })),
|
|
||||||
TokenOperator::Times => Left(7, |_, lhs, rhs| Ok(TemplateAstExpr::Operation { op: TokenOperator::Times, lhs: Box::new(lhs), rhs: Box::new(rhs) })),
|
|
||||||
TokenOperator::Divide => Left(7, |_, lhs, rhs| Ok(TemplateAstExpr::Operation { op: TokenOperator::Divide, lhs: Box::new(lhs), rhs: Box::new(rhs) })),
|
|
||||||
TokenOperator::And => Left(7, |_, lhs, rhs| Ok(TemplateAstExpr::Operation { op: TokenOperator::And, lhs: Box::new(lhs), rhs: Box::new(rhs) })),
|
|
||||||
TokenOperator::Or => Left(5, |_, lhs, rhs| Ok(TemplateAstExpr::Operation { op: TokenOperator::Or, lhs: Box::new(lhs), rhs: Box::new(rhs) })),
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.parse_next(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn ws<'input>(input: &mut Input<'input>) -> Result<(), AstError> {
|
fn ws<'input>(input: &mut Input<'input>) -> Result<(), AstError> {
|
||||||
repeat(.., TokenKind::Whitespace).parse_next(input)
|
repeat(.., TokenKind::Whitespace).parse_next(input)
|
||||||
}
|
}
|
||||||
|
|
@ -969,15 +912,4 @@ mod tests {
|
||||||
|
|
||||||
insta::assert_debug_snapshot!(ast);
|
insta::assert_debug_snapshot!(ast);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn check_math_expression() {
|
|
||||||
let input = "{{= 5 * 3 + 2 / 3 }}";
|
|
||||||
|
|
||||||
let parsed = crate::parser::parse(input.into()).unwrap();
|
|
||||||
|
|
||||||
let ast = panic_pretty(input, parse(parsed.tokens()));
|
|
||||||
|
|
||||||
insta::assert_debug_snapshot!(ast);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
---
|
|
||||||
source: src/ast/mod.rs
|
|
||||||
expression: ast
|
|
||||||
---
|
|
||||||
TemplateAst {
|
|
||||||
root: [
|
|
||||||
Interpolation {
|
|
||||||
prev_whitespace_content: None,
|
|
||||||
expression: Operation {
|
|
||||||
op: Plus,
|
|
||||||
lhs: Operation {
|
|
||||||
op: Times,
|
|
||||||
lhs: Literal {
|
|
||||||
source: [Literal(Integer(5))]"5" (4..5),
|
|
||||||
value: Integer {
|
|
||||||
value: 5,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
rhs: Literal {
|
|
||||||
source: [Literal(Integer(3))]"3" (8..9),
|
|
||||||
value: Integer {
|
|
||||||
value: 3,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
rhs: Operation {
|
|
||||||
op: Divide,
|
|
||||||
lhs: Literal {
|
|
||||||
source: [Literal(Integer(2))]"2" (12..13),
|
|
||||||
value: Integer {
|
|
||||||
value: 2,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
rhs: Literal {
|
|
||||||
source: [Literal(Integer(3))]"3" (16..17),
|
|
||||||
value: Integer {
|
|
||||||
value: 3,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
post_whitespace_content: None,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
@ -402,8 +402,6 @@ fn emit_ast_expr(
|
||||||
| TemplateAstExpr::For { .. }
|
| TemplateAstExpr::For { .. }
|
||||||
| TemplateAstExpr::ForElse
|
| TemplateAstExpr::ForElse
|
||||||
| TemplateAstExpr::Invalid { .. }
|
| TemplateAstExpr::Invalid { .. }
|
||||||
| TemplateAstExpr::Literal { .. }
|
|
||||||
| TemplateAstExpr::Operation { .. }
|
|
||||||
| TemplateAstExpr::VariableAccess { .. } => eval.push(Instruction::Abort),
|
| TemplateAstExpr::VariableAccess { .. } => eval.push(Instruction::Abort),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -432,8 +430,6 @@ fn emit_expr_load(
|
||||||
TemplateAstExpr::ForChain { .. } => todo!(),
|
TemplateAstExpr::ForChain { .. } => todo!(),
|
||||||
TemplateAstExpr::For { .. } => todo!(),
|
TemplateAstExpr::For { .. } => todo!(),
|
||||||
TemplateAstExpr::ForElse => todo!(),
|
TemplateAstExpr::ForElse => todo!(),
|
||||||
TemplateAstExpr::Operation { .. } => todo!(),
|
|
||||||
TemplateAstExpr::Literal { .. } => todo!(),
|
|
||||||
|
|
||||||
TemplateAstExpr::IfConditional { .. } => todo!(),
|
TemplateAstExpr::IfConditional { .. } => todo!(),
|
||||||
TemplateAstExpr::ConditionalContent { .. } => todo!(),
|
TemplateAstExpr::ConditionalContent { .. } => todo!(),
|
||||||
|
|
|
||||||
|
|
@ -8,16 +8,11 @@ use thiserror::Error;
|
||||||
use winnow::LocatingSlice;
|
use winnow::LocatingSlice;
|
||||||
use winnow::Parser;
|
use winnow::Parser;
|
||||||
use winnow::RecoverableParser;
|
use winnow::RecoverableParser;
|
||||||
use winnow::ascii::alpha1;
|
|
||||||
use winnow::ascii::digit1;
|
|
||||||
use winnow::ascii::multispace0;
|
use winnow::ascii::multispace0;
|
||||||
use winnow::ascii::multispace1;
|
use winnow::ascii::multispace1;
|
||||||
use winnow::combinator::alt;
|
use winnow::combinator::alt;
|
||||||
use winnow::combinator::cut_err;
|
use winnow::combinator::cut_err;
|
||||||
use winnow::combinator::dispatch;
|
|
||||||
use winnow::combinator::empty;
|
|
||||||
use winnow::combinator::eof;
|
use winnow::combinator::eof;
|
||||||
use winnow::combinator::fail;
|
|
||||||
use winnow::combinator::not;
|
use winnow::combinator::not;
|
||||||
use winnow::combinator::opt;
|
use winnow::combinator::opt;
|
||||||
use winnow::combinator::peek;
|
use winnow::combinator::peek;
|
||||||
|
|
@ -33,7 +28,6 @@ use winnow::stream::Location;
|
||||||
use winnow::stream::Recoverable;
|
use winnow::stream::Recoverable;
|
||||||
use winnow::stream::Stream;
|
use winnow::stream::Stream;
|
||||||
use winnow::token::any;
|
use winnow::token::any;
|
||||||
use winnow::token::literal;
|
|
||||||
use winnow::token::one_of;
|
use winnow::token::one_of;
|
||||||
use winnow::token::rest;
|
use winnow::token::rest;
|
||||||
use winnow::token::take_until;
|
use winnow::token::take_until;
|
||||||
|
|
@ -219,23 +213,11 @@ pub enum TokenKind {
|
||||||
In,
|
In,
|
||||||
End,
|
End,
|
||||||
Literal(TokenLiteral),
|
Literal(TokenLiteral),
|
||||||
Operator(TokenOperator),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
|
||||||
pub enum TokenOperator {
|
|
||||||
Plus,
|
|
||||||
Minus,
|
|
||||||
Times,
|
|
||||||
Divide,
|
|
||||||
And,
|
|
||||||
Or,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
pub enum TokenLiteral {
|
pub enum TokenLiteral {
|
||||||
Bool(bool),
|
Bool(bool),
|
||||||
Integer(u64),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq<TokenKind> for TemplateToken {
|
impl PartialEq<TokenKind> for TemplateToken {
|
||||||
|
|
@ -327,13 +309,6 @@ impl TemplateToken {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn operator(operator: TokenOperator, source: NomoInput) -> Self {
|
|
||||||
TemplateToken {
|
|
||||||
kind: TokenKind::Operator(operator),
|
|
||||||
source,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn kind(&self) -> TokenKind {
|
pub fn kind(&self) -> TokenKind {
|
||||||
self.kind
|
self.kind
|
||||||
}
|
}
|
||||||
|
|
@ -410,7 +385,7 @@ fn parse_interpolate<'input>(input: &mut Input<'input>) -> PResult<'input, Vec<T
|
||||||
fn parse_block_token<'input>(input: &mut Input<'input>) -> PResult<'input, TemplateToken> {
|
fn parse_block_token<'input>(input: &mut Input<'input>) -> PResult<'input, TemplateToken> {
|
||||||
trace(
|
trace(
|
||||||
"parse_block_token",
|
"parse_block_token",
|
||||||
alt((parse_ident, parse_keyword, parse_whitespace, parse_operator)),
|
alt((parse_ident, parse_keyword, parse_whitespace)),
|
||||||
)
|
)
|
||||||
.parse_next(input)
|
.parse_next(input)
|
||||||
}
|
}
|
||||||
|
|
@ -418,20 +393,13 @@ fn parse_block_token<'input>(input: &mut Input<'input>) -> PResult<'input, Templ
|
||||||
fn parse_literal<'input>(input: &mut Input<'input>) -> PResult<'input, TemplateToken> {
|
fn parse_literal<'input>(input: &mut Input<'input>) -> PResult<'input, TemplateToken> {
|
||||||
trace(
|
trace(
|
||||||
"parse_literal",
|
"parse_literal",
|
||||||
alt((parse_boolean, parse_number))
|
alt((parse_boolean,))
|
||||||
.with_taken()
|
.with_taken()
|
||||||
.map(|(lit, span)| TemplateToken::literal(lit, span)),
|
.map(|(lit, span)| TemplateToken::literal(lit, span)),
|
||||||
)
|
)
|
||||||
.parse_next(input)
|
.parse_next(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_number<'input>(input: &mut Input<'input>) -> PResult<'input, TokenLiteral> {
|
|
||||||
digit1
|
|
||||||
.verify_map(|digits: NomoInput| digits.parse::<u64>().ok())
|
|
||||||
.map(TokenLiteral::Integer)
|
|
||||||
.parse_next(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_boolean<'input>(input: &mut Input<'input>) -> PResult<'input, TokenLiteral> {
|
fn parse_boolean<'input>(input: &mut Input<'input>) -> PResult<'input, TokenLiteral> {
|
||||||
alt((
|
alt((
|
||||||
"true".value(TokenLiteral::Bool(true)),
|
"true".value(TokenLiteral::Bool(true)),
|
||||||
|
|
@ -506,44 +474,12 @@ fn parse_ident<'input>(input: &mut Input<'input>) -> PResult<'input, TemplateTok
|
||||||
.parse_next(input)
|
.parse_next(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_operator<'input>(input: &mut Input<'input>) -> PResult<'input, TemplateToken> {
|
|
||||||
let (operator, source) = trace(
|
|
||||||
"operator",
|
|
||||||
dispatch! {any;
|
|
||||||
'+' => empty.value(TokenOperator::Plus),
|
|
||||||
'-' => empty.value(TokenOperator::Minus),
|
|
||||||
'*' => empty.value(TokenOperator::Times),
|
|
||||||
'/' => empty.value(TokenOperator::Divide),
|
|
||||||
'&' => alt((
|
|
||||||
"&".value(TokenOperator::And),
|
|
||||||
cut_err(fail),
|
|
||||||
)),
|
|
||||||
'|' => alt((
|
|
||||||
"|".value(TokenOperator::Or),
|
|
||||||
cut_err(fail),
|
|
||||||
)),
|
|
||||||
_ => fail,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.with_taken()
|
|
||||||
.parse_next(input)?;
|
|
||||||
|
|
||||||
Ok(TemplateToken::operator(operator, source))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn ident<'input>(input: &mut Input<'input>) -> PResult<'input, NomoInput> {
|
fn ident<'input>(input: &mut Input<'input>) -> PResult<'input, NomoInput> {
|
||||||
peek(not(parse_keyword))
|
peek(not(parse_keyword))
|
||||||
.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)?;
|
||||||
|
|
||||||
let literal_start = alt((alpha1, "_"));
|
take_while(1.., |c: char| c.is_alphanumeric() || "_".contains(c)).parse_next(input)
|
||||||
|
|
||||||
(
|
|
||||||
literal_start,
|
|
||||||
take_while(0.., |c: char| c.is_alphanumeric() || "_".contains(c)),
|
|
||||||
)
|
|
||||||
.take()
|
|
||||||
.parse_next(input)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bad_ident<'input>(input: &mut Input<'input>) -> PResult<'input, ()> {
|
fn bad_ident<'input>(input: &mut Input<'input>) -> PResult<'input, ()> {
|
||||||
|
|
@ -744,61 +680,4 @@ mod tests {
|
||||||
)
|
)
|
||||||
"#);
|
"#);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn parse_operations() {
|
|
||||||
let input = "{{= 5 * 14 + 3 / 2 - 1 }}{{ if foo && bar || baz }}{{ end }}";
|
|
||||||
let output = parse(input.into());
|
|
||||||
|
|
||||||
insta::assert_debug_snapshot!(output, @r#"
|
|
||||||
Ok(
|
|
||||||
ParsedTemplate {
|
|
||||||
tokens: [
|
|
||||||
[LeftDelim]"{{" (0..2),
|
|
||||||
[WantsOutput]"=" (2..3),
|
|
||||||
[Whitespace]" " (3..4),
|
|
||||||
[Literal(Integer(5))]"5" (4..5),
|
|
||||||
[Whitespace]" " (5..6),
|
|
||||||
[Operator(Times)]"*" (6..7),
|
|
||||||
[Whitespace]" " (7..8),
|
|
||||||
[Literal(Integer(14))]"14" (8..10),
|
|
||||||
[Whitespace]" " (10..11),
|
|
||||||
[Operator(Plus)]"+" (11..12),
|
|
||||||
[Whitespace]" " (12..13),
|
|
||||||
[Literal(Integer(3))]"3" (13..14),
|
|
||||||
[Whitespace]" " (14..15),
|
|
||||||
[Operator(Divide)]"/" (15..16),
|
|
||||||
[Whitespace]" " (16..17),
|
|
||||||
[Literal(Integer(2))]"2" (17..18),
|
|
||||||
[Whitespace]" " (18..19),
|
|
||||||
[Operator(Minus)]"-" (19..20),
|
|
||||||
[Whitespace]" " (20..21),
|
|
||||||
[Literal(Integer(1))]"1" (21..22),
|
|
||||||
[Whitespace]" " (22..23),
|
|
||||||
[RightDelim]"}}" (23..25),
|
|
||||||
[LeftDelim]"{{" (25..27),
|
|
||||||
[Whitespace]" " (27..28),
|
|
||||||
[ConditionalIf]"if" (28..30),
|
|
||||||
[Whitespace]" " (30..31),
|
|
||||||
[Ident]"foo" (31..34),
|
|
||||||
[Whitespace]" " (34..35),
|
|
||||||
[Operator(And)]"&&" (35..37),
|
|
||||||
[Whitespace]" " (37..38),
|
|
||||||
[Ident]"bar" (38..41),
|
|
||||||
[Whitespace]" " (41..42),
|
|
||||||
[Operator(Or)]"||" (42..44),
|
|
||||||
[Whitespace]" " (44..45),
|
|
||||||
[Ident]"baz" (45..48),
|
|
||||||
[Whitespace]" " (48..49),
|
|
||||||
[RightDelim]"}}" (49..51),
|
|
||||||
[LeftDelim]"{{" (51..53),
|
|
||||||
[Whitespace]" " (53..54),
|
|
||||||
[End]"end" (54..57),
|
|
||||||
[Whitespace]" " (57..58),
|
|
||||||
[RightDelim]"}}" (58..60),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
)
|
|
||||||
"#);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,6 @@
|
||||||
---
|
---
|
||||||
source: tests/file_tests.rs
|
source: tests/file_tests.rs
|
||||||
expression: parsed
|
expression: parsed
|
||||||
info:
|
|
||||||
input: "{{= _name }}\n{{= a_name }}\n{{= name }}\n{{= _name1 }}\n{{= _namE }}\n{{= name1 }}"
|
|
||||||
context:
|
|
||||||
_namE: Foo
|
|
||||||
name1: Foo
|
|
||||||
name: Foo
|
|
||||||
_name: Foo
|
|
||||||
a_name: Foo
|
|
||||||
_name1: Foo
|
|
||||||
input_file: tests/cases/identifiers.nomo
|
input_file: tests/cases/identifiers.nomo
|
||||||
---
|
---
|
||||||
ParsedTemplate {
|
ParsedTemplate {
|
||||||
|
|
@ -31,29 +22,29 @@ ParsedTemplate {
|
||||||
[LeftDelim]"{{" (27..29),
|
[LeftDelim]"{{" (27..29),
|
||||||
[WantsOutput]"=" (29..30),
|
[WantsOutput]"=" (29..30),
|
||||||
[Whitespace]" " (30..31),
|
[Whitespace]" " (30..31),
|
||||||
[Ident]"name" (31..35),
|
[Ident]"1name" (31..36),
|
||||||
[Whitespace]" " (35..36),
|
[Whitespace]" " (36..37),
|
||||||
[RightDelim]"}}" (36..38),
|
[RightDelim]"}}" (37..39),
|
||||||
[Whitespace]"\n" (38..39),
|
[Whitespace]"\n" (39..40),
|
||||||
[LeftDelim]"{{" (39..41),
|
[LeftDelim]"{{" (40..42),
|
||||||
[WantsOutput]"=" (41..42),
|
[WantsOutput]"=" (42..43),
|
||||||
[Whitespace]" " (42..43),
|
[Whitespace]" " (43..44),
|
||||||
[Ident]"_name1" (43..49),
|
[Ident]"_name1" (44..50),
|
||||||
[Whitespace]" " (49..50),
|
[Whitespace]" " (50..51),
|
||||||
[RightDelim]"}}" (50..52),
|
[RightDelim]"}}" (51..53),
|
||||||
[Whitespace]"\n" (52..53),
|
[Whitespace]"\n" (53..54),
|
||||||
[LeftDelim]"{{" (53..55),
|
[LeftDelim]"{{" (54..56),
|
||||||
[WantsOutput]"=" (55..56),
|
[WantsOutput]"=" (56..57),
|
||||||
[Whitespace]" " (56..57),
|
[Whitespace]" " (57..58),
|
||||||
[Ident]"_namE" (57..62),
|
[Ident]"_namE" (58..63),
|
||||||
[Whitespace]" " (62..63),
|
[Whitespace]" " (63..64),
|
||||||
[RightDelim]"}}" (63..65),
|
[RightDelim]"}}" (64..66),
|
||||||
[Whitespace]"\n" (65..66),
|
[Whitespace]"\n" (66..67),
|
||||||
[LeftDelim]"{{" (66..68),
|
[LeftDelim]"{{" (67..69),
|
||||||
[WantsOutput]"=" (68..69),
|
[WantsOutput]"=" (69..70),
|
||||||
[Whitespace]" " (69..70),
|
[Whitespace]" " (70..71),
|
||||||
[Ident]"name1" (70..75),
|
[Ident]"name1" (71..76),
|
||||||
[Whitespace]" " (75..76),
|
[Whitespace]" " (76..77),
|
||||||
[RightDelim]"}}" (76..78),
|
[RightDelim]"}}" (77..79),
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,6 @@
|
||||||
---
|
---
|
||||||
source: tests/file_tests.rs
|
source: tests/file_tests.rs
|
||||||
expression: ast
|
expression: ast
|
||||||
info:
|
|
||||||
input: "{{= _name }}\n{{= a_name }}\n{{= name }}\n{{= _name1 }}\n{{= _namE }}\n{{= name1 }}"
|
|
||||||
context:
|
|
||||||
_namE: Foo
|
|
||||||
name1: Foo
|
|
||||||
name: Foo
|
|
||||||
_name: Foo
|
|
||||||
a_name: Foo
|
|
||||||
_name1: Foo
|
|
||||||
input_file: tests/cases/identifiers.nomo
|
input_file: tests/cases/identifiers.nomo
|
||||||
---
|
---
|
||||||
TemplateAst {
|
TemplateAst {
|
||||||
|
|
@ -35,34 +26,34 @@ TemplateAst {
|
||||||
Interpolation {
|
Interpolation {
|
||||||
prev_whitespace_content: None,
|
prev_whitespace_content: None,
|
||||||
expression: VariableAccess(
|
expression: VariableAccess(
|
||||||
[Ident]"name" (31..35),
|
[Ident]"1name" (31..36),
|
||||||
),
|
),
|
||||||
post_whitespace_content: Some(
|
post_whitespace_content: Some(
|
||||||
[Whitespace]"\n" (38..39),
|
[Whitespace]"\n" (39..40),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
Interpolation {
|
Interpolation {
|
||||||
prev_whitespace_content: None,
|
prev_whitespace_content: None,
|
||||||
expression: VariableAccess(
|
expression: VariableAccess(
|
||||||
[Ident]"_name1" (43..49),
|
[Ident]"_name1" (44..50),
|
||||||
),
|
),
|
||||||
post_whitespace_content: Some(
|
post_whitespace_content: Some(
|
||||||
[Whitespace]"\n" (52..53),
|
[Whitespace]"\n" (53..54),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
Interpolation {
|
Interpolation {
|
||||||
prev_whitespace_content: None,
|
prev_whitespace_content: None,
|
||||||
expression: VariableAccess(
|
expression: VariableAccess(
|
||||||
[Ident]"_namE" (57..62),
|
[Ident]"_namE" (58..63),
|
||||||
),
|
),
|
||||||
post_whitespace_content: Some(
|
post_whitespace_content: Some(
|
||||||
[Whitespace]"\n" (65..66),
|
[Whitespace]"\n" (66..67),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
Interpolation {
|
Interpolation {
|
||||||
prev_whitespace_content: None,
|
prev_whitespace_content: None,
|
||||||
expression: VariableAccess(
|
expression: VariableAccess(
|
||||||
[Ident]"name1" (70..75),
|
[Ident]"name1" (71..76),
|
||||||
),
|
),
|
||||||
post_whitespace_content: None,
|
post_whitespace_content: None,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,6 @@
|
||||||
---
|
---
|
||||||
source: tests/file_tests.rs
|
source: tests/file_tests.rs
|
||||||
expression: emit
|
expression: emit
|
||||||
info:
|
|
||||||
input: "{{= _name }}\n{{= a_name }}\n{{= name }}\n{{= _name1 }}\n{{= _namE }}\n{{= name1 }}"
|
|
||||||
context:
|
|
||||||
_namE: Foo
|
|
||||||
name1: Foo
|
|
||||||
name: Foo
|
|
||||||
_name: Foo
|
|
||||||
a_name: Foo
|
|
||||||
_name1: Foo
|
|
||||||
input_file: tests/cases/identifiers.nomo
|
input_file: tests/cases/identifiers.nomo
|
||||||
---
|
---
|
||||||
VMInstructions {
|
VMInstructions {
|
||||||
|
|
@ -44,7 +35,7 @@ VMInstructions {
|
||||||
content: "\n" (26..27),
|
content: "\n" (26..27),
|
||||||
},
|
},
|
||||||
LoadFromContextToSlot {
|
LoadFromContextToSlot {
|
||||||
name: "name" (31..35),
|
name: "1name" (31..36),
|
||||||
slot: VariableSlot {
|
slot: VariableSlot {
|
||||||
index: 2,
|
index: 2,
|
||||||
},
|
},
|
||||||
|
|
@ -55,10 +46,10 @@ VMInstructions {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
AppendContent {
|
AppendContent {
|
||||||
content: "\n" (38..39),
|
content: "\n" (39..40),
|
||||||
},
|
},
|
||||||
LoadFromContextToSlot {
|
LoadFromContextToSlot {
|
||||||
name: "_name1" (43..49),
|
name: "_name1" (44..50),
|
||||||
slot: VariableSlot {
|
slot: VariableSlot {
|
||||||
index: 3,
|
index: 3,
|
||||||
},
|
},
|
||||||
|
|
@ -69,10 +60,10 @@ VMInstructions {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
AppendContent {
|
AppendContent {
|
||||||
content: "\n" (52..53),
|
content: "\n" (53..54),
|
||||||
},
|
},
|
||||||
LoadFromContextToSlot {
|
LoadFromContextToSlot {
|
||||||
name: "_namE" (57..62),
|
name: "_namE" (58..63),
|
||||||
slot: VariableSlot {
|
slot: VariableSlot {
|
||||||
index: 4,
|
index: 4,
|
||||||
},
|
},
|
||||||
|
|
@ -83,10 +74,10 @@ VMInstructions {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
AppendContent {
|
AppendContent {
|
||||||
content: "\n" (65..66),
|
content: "\n" (66..67),
|
||||||
},
|
},
|
||||||
LoadFromContextToSlot {
|
LoadFromContextToSlot {
|
||||||
name: "name1" (70..75),
|
name: "name1" (71..76),
|
||||||
slot: VariableSlot {
|
slot: VariableSlot {
|
||||||
index: 5,
|
index: 5,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"_name": "Foo",
|
"_name": "Foo",
|
||||||
"a_name": "Foo",
|
"a_name": "Foo",
|
||||||
"name": "Foo",
|
"1name": "Foo",
|
||||||
"_name1": "Foo",
|
"_name1": "Foo",
|
||||||
"_namE": "Foo",
|
"_namE": "Foo",
|
||||||
"name1": "Foo"
|
"name1": "Foo"
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
---
|
---
|
||||||
{{= _name }}
|
{{= _name }}
|
||||||
{{= a_name }}
|
{{= a_name }}
|
||||||
{{= name }}
|
{{= 1name }}
|
||||||
{{= _name1 }}
|
{{= _name1 }}
|
||||||
{{= _namE }}
|
{{= _namE }}
|
||||||
{{= name1 }}
|
{{= name1 }}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue