From eba12b13a3a7f8bf298e1eb0045bcbf9141348c7 Mon Sep 17 00:00:00 2001 From: Jeff Date: Sat, 9 Mar 2024 07:34:34 -0500 Subject: [PATCH] Begin adding function calls --- src/abstract_tree/expression.rs | 6 ++++- src/abstract_tree/function_call.rs | 35 ++++++++++++++++++++++++++++++ src/abstract_tree/mod.rs | 2 ++ src/parser.rs | 30 +++++++++++++++++++++++++ 4 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 src/abstract_tree/function_call.rs diff --git a/src/abstract_tree/expression.rs b/src/abstract_tree/expression.rs index 42dd988..a0062ea 100644 --- a/src/abstract_tree/expression.rs +++ b/src/abstract_tree/expression.rs @@ -3,10 +3,11 @@ use crate::{ error::{RuntimeError, ValidationError}, }; -use super::{AbstractTree, Action, Identifier, Index, Logic, Math, Type, ValueNode}; +use super::{AbstractTree, Action, FunctionCall, Identifier, Index, Logic, Math, Type, ValueNode}; #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] pub enum Expression { + FunctionCall(FunctionCall), Identifier(Identifier), Index(Box), Logic(Box), @@ -17,6 +18,7 @@ pub enum Expression { impl AbstractTree for Expression { fn expected_type(&self, _context: &Context) -> Result { match self { + Expression::FunctionCall(function_call) => function_call.expected_type(_context), Expression::Identifier(identifier) => identifier.expected_type(_context), Expression::Index(index) => index.expected_type(_context), Expression::Logic(logic) => logic.expected_type(_context), @@ -27,6 +29,7 @@ impl AbstractTree for Expression { fn validate(&self, _context: &Context) -> Result<(), ValidationError> { match self { + Expression::FunctionCall(function_call) => function_call.validate(_context), Expression::Identifier(identifier) => identifier.validate(_context), Expression::Index(index) => index.validate(_context), Expression::Logic(logic) => logic.validate(_context), @@ -37,6 +40,7 @@ impl AbstractTree for Expression { fn run(self, _context: &Context) -> Result { match self { + Expression::FunctionCall(function_call) => function_call.run(_context), Expression::Identifier(identifier) => identifier.run(_context), Expression::Index(index) => index.run(_context), Expression::Logic(logic) => logic.run(_context), diff --git a/src/abstract_tree/function_call.rs b/src/abstract_tree/function_call.rs new file mode 100644 index 0000000..bb50c17 --- /dev/null +++ b/src/abstract_tree/function_call.rs @@ -0,0 +1,35 @@ +use crate::{ + context::Context, + error::{RuntimeError, ValidationError}, +}; + +use super::{AbstractTree, Action, Expression, Type}; + +#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord)] +pub struct FunctionCall { + function: Box, + arguments: Vec, +} + +impl FunctionCall { + pub fn new(function: Expression, arguments: Vec) -> Self { + FunctionCall { + function: Box::new(function), + arguments, + } + } +} + +impl AbstractTree for FunctionCall { + fn expected_type(&self, _context: &Context) -> Result { + todo!() + } + + fn validate(&self, _context: &Context) -> Result<(), ValidationError> { + todo!() + } + + fn run(self, _context: &Context) -> Result { + todo!() + } +} diff --git a/src/abstract_tree/mod.rs b/src/abstract_tree/mod.rs index f5215a4..20342af 100644 --- a/src/abstract_tree/mod.rs +++ b/src/abstract_tree/mod.rs @@ -1,6 +1,7 @@ pub mod assignment; pub mod block; pub mod expression; +pub mod function_call; pub mod identifier; pub mod if_else; pub mod index; @@ -15,6 +16,7 @@ pub use self::{ assignment::{Assignment, AssignmentOperator}, block::Block, expression::Expression, + function_call::FunctionCall, identifier::Identifier, if_else::IfElse, index::Index, diff --git a/src/parser.rs b/src/parser.rs index 3cb3e6d..47468e3 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -302,7 +302,26 @@ pub fn parser<'src>() -> DustParser<'src> { })) }); + let function_call = expression + .clone() + .then( + expression + .clone() + .separated_by(just(Token::Control(Control::Comma))) + .collect() + .delimited_by( + just(Token::Control(Control::ParenOpen)), + just(Token::Control(Control::ParenClose)), + ), + ) + .map(|(function, arguments)| { + Statement::Expression(Expression::FunctionCall(FunctionCall::new( + function, arguments, + ))) + }); + choice(( + function_call, assignment, expression_statement, r#break, @@ -327,6 +346,17 @@ mod tests { use super::*; + #[test] + fn function_call() { + assert_eq!( + parse(&lex("output()").unwrap()).unwrap()[0].0, + Statement::Expression(Expression::FunctionCall(FunctionCall::new( + Expression::Identifier(Identifier::new("output")), + Vec::with_capacity(0), + ))) + ) + } + #[test] fn range() { assert_eq!(