diff --git a/src/compiler/mod.rs b/src/compiler/mod.rs index eb06315..6f5c945 100644 --- a/src/compiler/mod.rs +++ b/src/compiler/mod.rs @@ -1,9 +1,9 @@ use std::collections::BTreeMap; -use crate::parser::TemplateAstExpr; use crate::input::NomoInput; use crate::lexer::TemplateToken; use crate::lexer::TokenOperator; +use crate::parser::TemplateAstExpr; use crate::value::NomoValue; pub struct EmitMachine { @@ -424,6 +424,7 @@ fn emit_ast_expr( | TemplateAstExpr::Literal { .. } | TemplateAstExpr::FunctionCall { .. } | TemplateAstExpr::Operation { .. } + | TemplateAstExpr::ConditionalAccess { .. } | TemplateAstExpr::VariableAccess { .. } => eval.push(Instruction::Abort), } } @@ -475,6 +476,7 @@ fn emit_expr_load( slot: emit_slot, }); } + TemplateAstExpr::ConditionalAccess { .. } => todo!(), TemplateAstExpr::Invalid { .. } => eval.push(Instruction::Abort), TemplateAstExpr::StaticContent { .. } | TemplateAstExpr::Interpolation { .. } => { unreachable!("Invalid AST here") diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 8c12ffb..d45eea7 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -2,6 +2,7 @@ use thiserror::Error; use winnow::Parser; use winnow::RecoverableParser; use winnow::combinator::Infix::Left; +use winnow::combinator::Postfix; use winnow::combinator::alt; use winnow::combinator::cut_err; use winnow::combinator::delimited; @@ -249,6 +250,7 @@ pub enum TemplateAstExpr<'input> { value_expression: Box>, }, ForElse, + ConditionalAccess(TemplateToken), VariableAccess(TemplateToken), IfConditional { expression: Box>, @@ -709,6 +711,16 @@ fn parse_expression<'input>( Left Lesser => 15, Left LesserOrEqual => 15, ] + }).postfix(dispatch! { surrounded(ws, parse_operator); + TokenOperator::QuestionMark => Postfix(22, |input, rhs| { + match rhs { + TemplateAstExpr::VariableAccess(access) => Ok(TemplateAstExpr::ConditionalAccess(access)), + _ => Err(AstError::from_input(input)), + } + + + }), + _ => fail }), ) .parse_next(input) @@ -1048,4 +1060,15 @@ mod tests { insta::assert_debug_snapshot!(ast); } + + #[test] + fn check_conditional_access() { + let input = "{{= foo? }}"; + + let parsed = crate::lexer::parse(input.into()).unwrap(); + + let ast = panic_pretty(input, parse(parsed.tokens())); + + insta::assert_debug_snapshot!(ast); + } } diff --git a/src/parser/snapshots/nomo__parser__tests__check_conditional_access.snap b/src/parser/snapshots/nomo__parser__tests__check_conditional_access.snap new file mode 100644 index 0000000..f575f85 --- /dev/null +++ b/src/parser/snapshots/nomo__parser__tests__check_conditional_access.snap @@ -0,0 +1,15 @@ +--- +source: src/parser/mod.rs +expression: ast +--- +TemplateAst { + root: [ + Interpolation { + prev_whitespace_content: None, + expression: ConditionalAccess( + [Ident]"foo" (4..7), + ), + post_whitespace_content: None, + }, + ], +}