Add emitting of function calls
Signed-off-by: Marcel Müller <neikos@neikos.email>
This commit is contained in:
parent
cb55c00739
commit
52a63a7066
5 changed files with 116 additions and 11 deletions
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
],
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue