From fbb650cb5afdbfec1026463f02d16dbb98acc1e9 Mon Sep 17 00:00:00 2001 From: Louis Capitanchik <contact@louiscap.co> Date: Tue, 16 May 2023 03:13:50 +0100 Subject: [PATCH] Support function calls --- forge-script-lang/src/parser/ast.rs | 11 ++++++++++- forge-script-lang/src/parser/grammar.rs | 5 +++-- forge-script-lang/src/parser/test_suite.rs | 9 +++++++++ .../src/runtime/executor/printer.rs | 18 ++++++++++++++++++ 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/forge-script-lang/src/parser/ast.rs b/forge-script-lang/src/parser/ast.rs index 739cacb..460fc41 100644 --- a/forge-script-lang/src/parser/ast.rs +++ b/forge-script-lang/src/parser/ast.rs @@ -167,6 +167,7 @@ pub enum ValueExpression { Assignment(Assignment), ConditionalBlock(Conditional), Identifier(Identifier), + FunctionCall(FunctionCall), } #[derive(Clone)] @@ -238,7 +239,7 @@ impl From<ValueExpression> for Print { } pub type IdentifierList = Vec<IdentifierNode>; -pub type ParameterList = Vec<IdentifierNode>; +pub type ParameterList = Vec<ValueExpression>; #[derive(Clone)] #[cfg_attr(feature = "debug-ast", derive(Debug))] @@ -342,3 +343,11 @@ pub enum DeclareIdent { WithValue(Assignment), WithoutValue(Identifier), } + +#[derive(Clone)] +#[cfg_attr(feature = "debug-ast", derive(Debug))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct FunctionCall { + pub name: Identifier, + pub params: ParameterList, +} diff --git a/forge-script-lang/src/parser/grammar.rs b/forge-script-lang/src/parser/grammar.rs index 65f9677..3d8117f 100644 --- a/forge-script-lang/src/parser/grammar.rs +++ b/forge-script-lang/src/parser/grammar.rs @@ -33,6 +33,8 @@ peg::parser! { = "(" ex:value_expression() ")" { ValueExpression::Grouped(GroupedExpression { inner: Box::new(ex) }) } / co:conditional() { ValueExpression::ConditionalBlock(co) } / decl:declare_variable() { ValueExpression::DeclareIdentifier(decl) } + / name:bare_identifier() "(" params:param_list()? ")" + { ValueExpression::FunctionCall(FunctionCall { name, params: params.unwrap_or_default() }) } / left:value_expression() op:binary_operator() right:value_expression() { ValueExpression::Binary { lhs: Box::new(left), rhs: Box::new(right), operator: op } } / op:unary_operator() operand:value_expression() @@ -85,8 +87,7 @@ peg::parser! { = identifier() ++ "," rule param_list() -> ParameterList - = ids:bare_identifier() ++ "," - { ids.iter().cloned().map(IdentifierNode::Direct).collect() } + = ids:value_expression() ++ "," rule identifier() -> IdentifierNode = id:alias_identifier() { IdentifierNode::Alias(id) } diff --git a/forge-script-lang/src/parser/test_suite.rs b/forge-script-lang/src/parser/test_suite.rs index 52a0627..eaec0bc 100644 --- a/forge-script-lang/src/parser/test_suite.rs +++ b/forge-script-lang/src/parser/test_suite.rs @@ -49,3 +49,12 @@ fn expression_list() { parse_program("if flop { 123 + 2323 } else { let boo = false }; let glob = \"swarmp\"") .expect("Failed simple expression list"); } + +#[test] +fn function_calls() { + parse_program("some_func()").expect("Failed empty function params"); + parse_program("some_func(123)").expect("Failed single function param"); + parse_program("some_func(false, 2929)").expect("Failed multiple function params"); + parse_program("some_func(250, if true { \"some val\" } else { \"123\" })") + .expect("Failed complex function params"); +} diff --git a/forge-script-lang/src/runtime/executor/printer.rs b/forge-script-lang/src/runtime/executor/printer.rs index 0c05b5d..078f8a2 100644 --- a/forge-script-lang/src/runtime/executor/printer.rs +++ b/forge-script-lang/src/runtime/executor/printer.rs @@ -143,6 +143,24 @@ impl Visitor for TreePrinter { ValueExpression::Identifier(ident) => { self.write(ident); } + ValueExpression::FunctionCall(call) => { + self.write(&call.name); + self.write("("); + let list = call + .params + .iter() + .map(|param| { + let mut inner = TreePrinter { + indent: self.indent, + buffer: String::new(), + }; + inner.evaluate_value_expression(param); + inner.take_value() + }) + .collect::<Vec<String>>(); + self.write(list.as_slice().join(", ")); + self.write(")"); + } } } -- GitLab