diff --git a/forge-script-lang/src/parser/ast.rs b/forge-script-lang/src/parser/ast.rs index 739cacb5a1623d5bad9ec1259b199233bff32121..460fc416539abae3deb2b68d7812f2247fd3bec6 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 65f96779a7b98c7375193a801e9343430a18a1ef..3d8117f7f1b5a673246efc6b14d6ee4999886f34 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 52a0627a04a2e3162686fbe0d4b629a0d2b0d3ff..eaec0bc7daa1fbed20bc338e7f87dc6102d2272c 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 0c05b5de9599b556b3220556d9687b6f6a4d0a33..078f8a29a6ed91405361cbf66d20ed3fc20bd8e3 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(")"); + } } }