Add function asting
Signed-off-by: Marcel Müller <neikos@neikos.email>
This commit is contained in:
parent
70f616d60c
commit
cb55c00739
4 changed files with 97 additions and 4 deletions
|
|
@ -13,6 +13,7 @@ use winnow::combinator::peek;
|
||||||
use winnow::combinator::preceded;
|
use winnow::combinator::preceded;
|
||||||
use winnow::combinator::repeat;
|
use winnow::combinator::repeat;
|
||||||
use winnow::combinator::repeat_till;
|
use winnow::combinator::repeat_till;
|
||||||
|
use winnow::combinator::separated;
|
||||||
use winnow::combinator::trace;
|
use winnow::combinator::trace;
|
||||||
use winnow::error::AddContext;
|
use winnow::error::AddContext;
|
||||||
use winnow::error::FromRecoverableError;
|
use winnow::error::FromRecoverableError;
|
||||||
|
|
@ -268,6 +269,10 @@ pub enum TemplateAstExpr<'input> {
|
||||||
source: TemplateToken,
|
source: TemplateToken,
|
||||||
value: NomoValue,
|
value: NomoValue,
|
||||||
},
|
},
|
||||||
|
FunctionCall {
|
||||||
|
name: Box<TemplateAstExpr<'input>>,
|
||||||
|
args: Vec<TemplateAstExpr<'input>>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
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> {
|
||||||
|
|
@ -559,6 +564,22 @@ fn parse_end<'input>(input: &mut Input<'input>) -> Result<TemplateAstExpr<'input
|
||||||
.parse_next(input)
|
.parse_next(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_function<'input>(input: &mut Input<'input>) -> Result<TemplateAstExpr<'input>, AstError> {
|
||||||
|
trace(
|
||||||
|
"variable_access",
|
||||||
|
(
|
||||||
|
TokenKind::Ident
|
||||||
|
.map(TemplateAstExpr::VariableAccess)
|
||||||
|
.map(Box::new),
|
||||||
|
TokenKind::LeftArgList,
|
||||||
|
separated(0.., parse_expression, TokenKind::ArgSeperator),
|
||||||
|
TokenKind::RightArgList,
|
||||||
|
)
|
||||||
|
.map(|(name, _left, args, _right)| TemplateAstExpr::FunctionCall { name, args }),
|
||||||
|
)
|
||||||
|
.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> {
|
||||||
|
|
@ -620,7 +641,11 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_operand<'input>(input: &mut Input<'input>) -> Result<TemplateAstExpr<'input>, AstError> {
|
fn parse_operand<'input>(input: &mut Input<'input>) -> Result<TemplateAstExpr<'input>, AstError> {
|
||||||
trace("operand", alt((parse_variable_access, parse_literal))).parse_next(input)
|
trace(
|
||||||
|
"operand",
|
||||||
|
alt((parse_function, parse_variable_access, parse_literal)),
|
||||||
|
)
|
||||||
|
.parse_next(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_literal<'input>(input: &mut Input<'input>) -> Result<TemplateAstExpr<'input>, AstError> {
|
fn parse_literal<'input>(input: &mut Input<'input>) -> Result<TemplateAstExpr<'input>, AstError> {
|
||||||
|
|
@ -658,7 +683,11 @@ fn parse_expression<'input>(
|
||||||
($parser:expr => [ $($side:tt $val:tt => $prec:expr),* $(,)? ]) => {
|
($parser:expr => [ $($side:tt $val:tt => $prec:expr),* $(,)? ]) => {
|
||||||
dispatch! { surrounded(ws, parse_operator);
|
dispatch! { surrounded(ws, parse_operator);
|
||||||
$(
|
$(
|
||||||
TokenOperator::$val => $side($prec, |_, lhs, rhs| Ok(TemplateAstExpr::Operation { op: TokenOperator::$val, lhs: Box::new(lhs), rhs: Box::new(rhs) }))
|
TokenOperator::$val => $side($prec, |_, lhs, rhs| Ok(TemplateAstExpr::Operation {
|
||||||
|
op: TokenOperator::$val,
|
||||||
|
lhs: Box::new(lhs),
|
||||||
|
rhs: Box::new(rhs)
|
||||||
|
}))
|
||||||
),*
|
),*
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -1008,4 +1037,15 @@ mod tests {
|
||||||
|
|
||||||
insta::assert_debug_snapshot!(ast);
|
insta::assert_debug_snapshot!(ast);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_function_call() {
|
||||||
|
let input = "{{= foo(2 * 3, bar(2 + baz)) }}";
|
||||||
|
|
||||||
|
let parsed = crate::parser::parse(input.into()).unwrap();
|
||||||
|
|
||||||
|
let ast = panic_pretty(input, parse(parsed.tokens()));
|
||||||
|
|
||||||
|
insta::assert_debug_snapshot!(ast);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
53
src/ast/snapshots/nomo__ast__tests__check_function_call.snap
Normal file
53
src/ast/snapshots/nomo__ast__tests__check_function_call.snap
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
---
|
||||||
|
source: src/ast/mod.rs
|
||||||
|
expression: ast
|
||||||
|
---
|
||||||
|
TemplateAst {
|
||||||
|
root: [
|
||||||
|
Interpolation {
|
||||||
|
prev_whitespace_content: None,
|
||||||
|
expression: FunctionCall {
|
||||||
|
name: VariableAccess(
|
||||||
|
[Ident]"foo" (4..7),
|
||||||
|
),
|
||||||
|
args: [
|
||||||
|
Operation {
|
||||||
|
op: Times,
|
||||||
|
lhs: Literal {
|
||||||
|
source: [Literal(Integer(2))]"2" (8..9),
|
||||||
|
value: Integer {
|
||||||
|
value: 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
rhs: Literal {
|
||||||
|
source: [Literal(Integer(3))]"3" (12..13),
|
||||||
|
value: Integer {
|
||||||
|
value: 3,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
FunctionCall {
|
||||||
|
name: VariableAccess(
|
||||||
|
[Ident]"bar" (15..18),
|
||||||
|
),
|
||||||
|
args: [
|
||||||
|
Operation {
|
||||||
|
op: Plus,
|
||||||
|
lhs: Literal {
|
||||||
|
source: [Literal(Integer(2))]"2" (19..20),
|
||||||
|
value: Integer {
|
||||||
|
value: 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
rhs: VariableAccess(
|
||||||
|
[Ident]"baz" (23..26),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
post_whitespace_content: None,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
@ -417,6 +417,7 @@ fn emit_ast_expr(
|
||||||
| TemplateAstExpr::ForElse
|
| TemplateAstExpr::ForElse
|
||||||
| TemplateAstExpr::Invalid { .. }
|
| TemplateAstExpr::Invalid { .. }
|
||||||
| TemplateAstExpr::Literal { .. }
|
| TemplateAstExpr::Literal { .. }
|
||||||
|
| TemplateAstExpr::FunctionCall { .. }
|
||||||
| TemplateAstExpr::Operation { .. }
|
| TemplateAstExpr::Operation { .. }
|
||||||
| TemplateAstExpr::VariableAccess { .. } => eval.push(Instruction::Abort),
|
| TemplateAstExpr::VariableAccess { .. } => eval.push(Instruction::Abort),
|
||||||
}
|
}
|
||||||
|
|
@ -459,6 +460,7 @@ fn emit_expr_load(
|
||||||
TemplateAstExpr::StaticContent { .. } | TemplateAstExpr::Interpolation { .. } => {
|
TemplateAstExpr::StaticContent { .. } | TemplateAstExpr::Interpolation { .. } => {
|
||||||
unreachable!("Invalid AST here")
|
unreachable!("Invalid AST here")
|
||||||
}
|
}
|
||||||
|
TemplateAstExpr::FunctionCall { .. } => todo!(),
|
||||||
TemplateAstExpr::ConditionalChain { .. } => todo!(),
|
TemplateAstExpr::ConditionalChain { .. } => todo!(),
|
||||||
TemplateAstExpr::ElseConditional { .. } => todo!(),
|
TemplateAstExpr::ElseConditional { .. } => todo!(),
|
||||||
TemplateAstExpr::EndBlock => todo!(),
|
TemplateAstExpr::EndBlock => todo!(),
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,6 @@ use std::collections::BTreeMap;
|
||||||
use displaydoc::Display;
|
use displaydoc::Display;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use crate::Nomo;
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum NomoValue {
|
pub enum NomoValue {
|
||||||
String {
|
String {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue