diff --git a/src/ast/mod.rs b/src/ast/mod.rs index a9ca5ce..3a94816 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -270,7 +270,7 @@ pub enum TemplateAstExpr<'input> { value: NomoValue, }, FunctionCall { - name: Box>, + name: TemplateToken, args: Vec>, }, } @@ -568,9 +568,7 @@ fn parse_function<'input>(input: &mut Input<'input>) -> Result, + slot: VariableSlot, + }, } #[derive(Debug, Clone)] @@ -456,11 +461,24 @@ fn emit_expr_load( result_slot: emit_slot, }); } + TemplateAstExpr::FunctionCall { name, args } => { + let mut arg_slots = vec![]; + for arg in args { + let slot = machine.reserve_slot(); + emit_expr_load(machine, eval, slot, arg); + arg_slots.push(slot); + } + + eval.push(Instruction::FunctionCall { + name: name.source(), + args: arg_slots, + slot: emit_slot, + }); + } TemplateAstExpr::Invalid { .. } => eval.push(Instruction::Abort), TemplateAstExpr::StaticContent { .. } | TemplateAstExpr::Interpolation { .. } => { unreachable!("Invalid AST here") } - TemplateAstExpr::FunctionCall { .. } => todo!(), TemplateAstExpr::ConditionalChain { .. } => todo!(), TemplateAstExpr::ElseConditional { .. } => todo!(), TemplateAstExpr::EndBlock => todo!(), @@ -526,4 +544,17 @@ mod tests { insta::assert_debug_snapshot!(emit); } + + #[test] + fn check_function_call() { + let input = "{{ if foo(23) }} bar {{ else }} foobar {{ end }}"; + + let parsed = crate::parser::parse(input.into()).unwrap(); + + let ast = crate::ast::parse(parsed.tokens()).unwrap(); + + let emit = emit_machine(ast); + + insta::assert_debug_snapshot!(emit); + } } diff --git a/src/emit/snapshots/nomo__emit__tests__check_function_call.snap b/src/emit/snapshots/nomo__emit__tests__check_function_call.snap new file mode 100644 index 0000000..3594efe --- /dev/null +++ b/src/emit/snapshots/nomo__emit__tests__check_function_call.snap @@ -0,0 +1,79 @@ +--- +source: src/emit/mod.rs +expression: emit +--- +VMInstructions { + labels: { + LabelSlot { + index: 0, + }: 13, + LabelSlot { + index: 3, + }: 8, + }, + instructions: [ + LoadLiteralToSlot { + source: [Literal(Integer(23))]"23" (10..12), + value: Integer { + value: 23, + }, + slot: VariableSlot { + index: 2, + }, + }, + FunctionCall { + name: "foo" (6..9), + args: [ + VariableSlot { + index: 2, + }, + ], + slot: VariableSlot { + index: 1, + }, + }, + JumpIfNotTrue { + emit_slot: VariableSlot { + index: 1, + }, + jump: LabelSlot { + index: 3, + }, + }, + AppendContent { + content: " " (16..17), + }, + AppendContent { + content: "bar" (17..20), + }, + AppendContent { + content: " " (20..21), + }, + Jump { + jump: LabelSlot { + index: 0, + }, + }, + AppendContent { + content: " " (16..17), + }, + AppendContent { + content: " " (31..32), + }, + AppendContent { + content: "foobar" (32..38), + }, + AppendContent { + content: " " (38..39), + }, + Jump { + jump: LabelSlot { + index: 0, + }, + }, + AppendContent { + content: " " (31..32), + }, + NoOp, + ], +} diff --git a/src/eval/mod.rs b/src/eval/mod.rs index 8d32123..7617380 100644 --- a/src/eval/mod.rs +++ b/src/eval/mod.rs @@ -208,6 +208,7 @@ pub fn execute(vm: &VMInstructions, global_context: &Context) -> Result todo!(), } ip += 1;