Add emitting of function calls

Signed-off-by: Marcel Müller <neikos@neikos.email>
This commit is contained in:
Marcel Müller 2026-03-14 10:52:29 +01:00
parent cb55c00739
commit 52a63a7066
5 changed files with 116 additions and 11 deletions

View file

@ -270,7 +270,7 @@ pub enum TemplateAstExpr<'input> {
value: NomoValue,
},
FunctionCall {
name: Box<TemplateAstExpr<'input>>,
name: TemplateToken,
args: Vec<TemplateAstExpr<'input>>,
},
}
@ -568,9 +568,7 @@ fn parse_function<'input>(input: &mut Input<'input>) -> Result<TemplateAstExpr<'
trace(
"variable_access",
(
TokenKind::Ident
.map(TemplateAstExpr::VariableAccess)
.map(Box::new),
TokenKind::Ident,
TokenKind::LeftArgList,
separated(0.., parse_expression, TokenKind::ArgSeperator),
TokenKind::RightArgList,

View file

@ -7,9 +7,7 @@ TemplateAst {
Interpolation {
prev_whitespace_content: None,
expression: FunctionCall {
name: VariableAccess(
[Ident]"foo" (4..7),
),
name: [Ident]"foo" (4..7),
args: [
Operation {
op: Times,
@ -27,9 +25,7 @@ TemplateAst {
},
},
FunctionCall {
name: VariableAccess(
[Ident]"bar" (15..18),
),
name: [Ident]"bar" (15..18),
args: [
Operation {
op: Plus,

View file

@ -102,6 +102,11 @@ pub enum Instruction {
right_slot: VariableSlot,
result_slot: VariableSlot,
},
FunctionCall {
name: NomoInput,
args: Vec<VariableSlot>,
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);
}
}

View file

@ -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,
],
}

View file

@ -208,6 +208,7 @@ pub fn execute(vm: &VMInstructions, global_context: &Context) -> Result<String,
scopes.insert_into_slot(*result_slot, result.unwrap());
}
Instruction::FunctionCall { .. } => todo!(),
}
ip += 1;