diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 1d483a7..fa78ccc 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -1,12 +1,9 @@ use thiserror::Error; use winnow::Parser; use winnow::RecoverableParser; -use winnow::combinator::Infix::Left; use winnow::combinator::alt; use winnow::combinator::cut_err; use winnow::combinator::delimited; -use winnow::combinator::dispatch; -use winnow::combinator::expression; use winnow::combinator::not; use winnow::combinator::opt; use winnow::combinator::peek; @@ -27,9 +24,7 @@ use winnow::token::any; use crate::SourceSpan; use crate::parser::TemplateToken; use crate::parser::TokenKind; -use crate::parser::TokenOperator; use crate::resume_after_cut; -use crate::value::NomoValue; #[derive(Debug, Clone)] pub struct TemplateAst<'input> { @@ -258,16 +253,7 @@ pub enum TemplateAstExpr<'input> { expression: Option>>, }, Invalid(&'input [TemplateToken]), - Operation { - op: TokenOperator, - lhs: Box>, - rhs: Box>, - }, EndBlock, - Literal { - source: TemplateToken, - value: NomoValue, - }, } fn parse_asts<'input>(input: &mut Input<'input>) -> Result>, AstError> { @@ -289,7 +275,7 @@ fn parse_interpolation<'input>( input: &mut Input<'input>, ) -> Result, AstError> { let expr_parser = resume_after_cut( - parse_expression, + parse_value_expression, repeat_till( 0.., any, @@ -411,7 +397,7 @@ fn parse_for_loop<'input>(input: &mut Input<'input>) -> Result( preceded( TokenKind::ConditionalIf, cut_err( - surrounded(ws, parse_expression) + surrounded(ws, parse_value_expression) .map(Box::new) .context(AstError::ctx().msg("Expected an expression after 'if'")), ), @@ -524,7 +510,7 @@ fn parse_conditional_else<'input>( surrounded(ws, TokenKind::ConditionalElse), opt(preceded( 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 { @@ -559,6 +545,12 @@ fn parse_end<'input>(input: &mut Input<'input>) -> Result( + input: &mut Input<'input>, +) -> Result, AstError> { + trace("value_expression", alt((parse_variable_access,))).parse_next(input) +} + fn parse_variable_access<'input>( input: &mut Input<'input>, ) -> Result, AstError> { @@ -619,55 +611,6 @@ where ) } -fn parse_operand<'input>(input: &mut Input<'input>) -> Result, AstError> { - trace("operand", alt((parse_variable_access, parse_literal))).parse_next(input) -} - -fn parse_literal<'input>(input: &mut Input<'input>) -> Result, 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 { - 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, 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> { repeat(.., TokenKind::Whitespace).parse_next(input) } @@ -969,15 +912,4 @@ mod tests { 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); - } } diff --git a/src/ast/snapshots/nomo__ast__tests__check_math_expression.snap b/src/ast/snapshots/nomo__ast__tests__check_math_expression.snap deleted file mode 100644 index 7265e0a..0000000 --- a/src/ast/snapshots/nomo__ast__tests__check_math_expression.snap +++ /dev/null @@ -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, - }, - ], -} diff --git a/src/emit/mod.rs b/src/emit/mod.rs index afaa4cd..b34d4cf 100644 --- a/src/emit/mod.rs +++ b/src/emit/mod.rs @@ -402,8 +402,6 @@ fn emit_ast_expr( | TemplateAstExpr::For { .. } | TemplateAstExpr::ForElse | TemplateAstExpr::Invalid { .. } - | TemplateAstExpr::Literal { .. } - | TemplateAstExpr::Operation { .. } | TemplateAstExpr::VariableAccess { .. } => eval.push(Instruction::Abort), } } @@ -432,8 +430,6 @@ fn emit_expr_load( TemplateAstExpr::ForChain { .. } => todo!(), TemplateAstExpr::For { .. } => todo!(), TemplateAstExpr::ForElse => todo!(), - TemplateAstExpr::Operation { .. } => todo!(), - TemplateAstExpr::Literal { .. } => todo!(), TemplateAstExpr::IfConditional { .. } => todo!(), TemplateAstExpr::ConditionalContent { .. } => todo!(), diff --git a/src/parser/mod.rs b/src/parser/mod.rs index a5474c4..de0ba97 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -8,16 +8,11 @@ use thiserror::Error; use winnow::LocatingSlice; use winnow::Parser; use winnow::RecoverableParser; -use winnow::ascii::alpha1; -use winnow::ascii::digit1; use winnow::ascii::multispace0; use winnow::ascii::multispace1; use winnow::combinator::alt; use winnow::combinator::cut_err; -use winnow::combinator::dispatch; -use winnow::combinator::empty; use winnow::combinator::eof; -use winnow::combinator::fail; use winnow::combinator::not; use winnow::combinator::opt; use winnow::combinator::peek; @@ -33,7 +28,6 @@ use winnow::stream::Location; use winnow::stream::Recoverable; use winnow::stream::Stream; use winnow::token::any; -use winnow::token::literal; use winnow::token::one_of; use winnow::token::rest; use winnow::token::take_until; @@ -219,23 +213,11 @@ pub enum TokenKind { In, End, 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)] pub enum TokenLiteral { Bool(bool), - Integer(u64), } impl PartialEq 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 { self.kind } @@ -410,7 +385,7 @@ fn parse_interpolate<'input>(input: &mut Input<'input>) -> PResult<'input, Vec(input: &mut Input<'input>) -> PResult<'input, TemplateToken> { trace( "parse_block_token", - alt((parse_ident, parse_keyword, parse_whitespace, parse_operator)), + alt((parse_ident, parse_keyword, parse_whitespace)), ) .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> { trace( "parse_literal", - alt((parse_boolean, parse_number)) + alt((parse_boolean,)) .with_taken() .map(|(lit, span)| TemplateToken::literal(lit, span)), ) .parse_next(input) } -fn parse_number<'input>(input: &mut Input<'input>) -> PResult<'input, TokenLiteral> { - digit1 - .verify_map(|digits: NomoInput| digits.parse::().ok()) - .map(TokenLiteral::Integer) - .parse_next(input) -} - fn parse_boolean<'input>(input: &mut Input<'input>) -> PResult<'input, TokenLiteral> { alt(( "true".value(TokenLiteral::Bool(true)), @@ -506,44 +474,12 @@ fn parse_ident<'input>(input: &mut Input<'input>) -> PResult<'input, TemplateTok .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> { peek(not(parse_keyword)) .context(ParseError::ctx().msg("Expected an ident, but found a literal instead")) .parse_next(input)?; - let literal_start = alt((alpha1, "_")); - - ( - literal_start, - take_while(0.., |c: char| c.is_alphanumeric() || "_".contains(c)), - ) - .take() - .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, ()> { @@ -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), - ], - }, - ) - "#); - } } diff --git a/tests/cases/1-parsed@identifiers.snap b/tests/cases/1-parsed@identifiers.snap index 31760f1..66a2da0 100644 --- a/tests/cases/1-parsed@identifiers.snap +++ b/tests/cases/1-parsed@identifiers.snap @@ -1,15 +1,6 @@ --- source: tests/file_tests.rs 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 --- ParsedTemplate { @@ -31,29 +22,29 @@ ParsedTemplate { [LeftDelim]"{{" (27..29), [WantsOutput]"=" (29..30), [Whitespace]" " (30..31), - [Ident]"name" (31..35), - [Whitespace]" " (35..36), - [RightDelim]"}}" (36..38), - [Whitespace]"\n" (38..39), - [LeftDelim]"{{" (39..41), - [WantsOutput]"=" (41..42), - [Whitespace]" " (42..43), - [Ident]"_name1" (43..49), - [Whitespace]" " (49..50), - [RightDelim]"}}" (50..52), - [Whitespace]"\n" (52..53), - [LeftDelim]"{{" (53..55), - [WantsOutput]"=" (55..56), - [Whitespace]" " (56..57), - [Ident]"_namE" (57..62), - [Whitespace]" " (62..63), - [RightDelim]"}}" (63..65), - [Whitespace]"\n" (65..66), - [LeftDelim]"{{" (66..68), - [WantsOutput]"=" (68..69), - [Whitespace]" " (69..70), - [Ident]"name1" (70..75), - [Whitespace]" " (75..76), - [RightDelim]"}}" (76..78), + [Ident]"1name" (31..36), + [Whitespace]" " (36..37), + [RightDelim]"}}" (37..39), + [Whitespace]"\n" (39..40), + [LeftDelim]"{{" (40..42), + [WantsOutput]"=" (42..43), + [Whitespace]" " (43..44), + [Ident]"_name1" (44..50), + [Whitespace]" " (50..51), + [RightDelim]"}}" (51..53), + [Whitespace]"\n" (53..54), + [LeftDelim]"{{" (54..56), + [WantsOutput]"=" (56..57), + [Whitespace]" " (57..58), + [Ident]"_namE" (58..63), + [Whitespace]" " (63..64), + [RightDelim]"}}" (64..66), + [Whitespace]"\n" (66..67), + [LeftDelim]"{{" (67..69), + [WantsOutput]"=" (69..70), + [Whitespace]" " (70..71), + [Ident]"name1" (71..76), + [Whitespace]" " (76..77), + [RightDelim]"}}" (77..79), ], } diff --git a/tests/cases/2-ast@identifiers.snap b/tests/cases/2-ast@identifiers.snap index 4333d9d..ddcc251 100644 --- a/tests/cases/2-ast@identifiers.snap +++ b/tests/cases/2-ast@identifiers.snap @@ -1,15 +1,6 @@ --- source: tests/file_tests.rs 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 --- TemplateAst { @@ -35,34 +26,34 @@ TemplateAst { Interpolation { prev_whitespace_content: None, expression: VariableAccess( - [Ident]"name" (31..35), + [Ident]"1name" (31..36), ), post_whitespace_content: Some( - [Whitespace]"\n" (38..39), + [Whitespace]"\n" (39..40), ), }, Interpolation { prev_whitespace_content: None, expression: VariableAccess( - [Ident]"_name1" (43..49), + [Ident]"_name1" (44..50), ), post_whitespace_content: Some( - [Whitespace]"\n" (52..53), + [Whitespace]"\n" (53..54), ), }, Interpolation { prev_whitespace_content: None, expression: VariableAccess( - [Ident]"_namE" (57..62), + [Ident]"_namE" (58..63), ), post_whitespace_content: Some( - [Whitespace]"\n" (65..66), + [Whitespace]"\n" (66..67), ), }, Interpolation { prev_whitespace_content: None, expression: VariableAccess( - [Ident]"name1" (70..75), + [Ident]"name1" (71..76), ), post_whitespace_content: None, }, diff --git a/tests/cases/3-instructions@identifiers.snap b/tests/cases/3-instructions@identifiers.snap index 9556d23..01ec3a8 100644 --- a/tests/cases/3-instructions@identifiers.snap +++ b/tests/cases/3-instructions@identifiers.snap @@ -1,15 +1,6 @@ --- source: tests/file_tests.rs 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 --- VMInstructions { @@ -44,7 +35,7 @@ VMInstructions { content: "\n" (26..27), }, LoadFromContextToSlot { - name: "name" (31..35), + name: "1name" (31..36), slot: VariableSlot { index: 2, }, @@ -55,10 +46,10 @@ VMInstructions { }, }, AppendContent { - content: "\n" (38..39), + content: "\n" (39..40), }, LoadFromContextToSlot { - name: "_name1" (43..49), + name: "_name1" (44..50), slot: VariableSlot { index: 3, }, @@ -69,10 +60,10 @@ VMInstructions { }, }, AppendContent { - content: "\n" (52..53), + content: "\n" (53..54), }, LoadFromContextToSlot { - name: "_namE" (57..62), + name: "_namE" (58..63), slot: VariableSlot { index: 4, }, @@ -83,10 +74,10 @@ VMInstructions { }, }, AppendContent { - content: "\n" (65..66), + content: "\n" (66..67), }, LoadFromContextToSlot { - name: "name1" (70..75), + name: "name1" (71..76), slot: VariableSlot { index: 5, }, diff --git a/tests/cases/identifiers.nomo b/tests/cases/identifiers.nomo index da49414..570a7b2 100644 --- a/tests/cases/identifiers.nomo +++ b/tests/cases/identifiers.nomo @@ -1,7 +1,7 @@ { "_name": "Foo", "a_name": "Foo", - "name": "Foo", + "1name": "Foo", "_name1": "Foo", "_namE": "Foo", "name1": "Foo" @@ -9,7 +9,7 @@ --- {{= _name }} {{= a_name }} -{{= name }} +{{= 1name }} {{= _name1 }} {{= _namE }} {{= name1 }} \ No newline at end of file