Begin adding function calls

This commit is contained in:
Jeff 2024-03-09 07:34:34 -05:00
parent b9190514c4
commit eba12b13a3
4 changed files with 72 additions and 1 deletions

View File

@ -3,10 +3,11 @@ use crate::{
error::{RuntimeError, ValidationError}, 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)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
pub enum Expression { pub enum Expression {
FunctionCall(FunctionCall),
Identifier(Identifier), Identifier(Identifier),
Index(Box<Index>), Index(Box<Index>),
Logic(Box<Logic>), Logic(Box<Logic>),
@ -17,6 +18,7 @@ pub enum Expression {
impl AbstractTree for Expression { impl AbstractTree for Expression {
fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> { fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
match self { match self {
Expression::FunctionCall(function_call) => function_call.expected_type(_context),
Expression::Identifier(identifier) => identifier.expected_type(_context), Expression::Identifier(identifier) => identifier.expected_type(_context),
Expression::Index(index) => index.expected_type(_context), Expression::Index(index) => index.expected_type(_context),
Expression::Logic(logic) => logic.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> { fn validate(&self, _context: &Context) -> Result<(), ValidationError> {
match self { match self {
Expression::FunctionCall(function_call) => function_call.validate(_context),
Expression::Identifier(identifier) => identifier.validate(_context), Expression::Identifier(identifier) => identifier.validate(_context),
Expression::Index(index) => index.validate(_context), Expression::Index(index) => index.validate(_context),
Expression::Logic(logic) => logic.validate(_context), Expression::Logic(logic) => logic.validate(_context),
@ -37,6 +40,7 @@ impl AbstractTree for Expression {
fn run(self, _context: &Context) -> Result<Action, RuntimeError> { fn run(self, _context: &Context) -> Result<Action, RuntimeError> {
match self { match self {
Expression::FunctionCall(function_call) => function_call.run(_context),
Expression::Identifier(identifier) => identifier.run(_context), Expression::Identifier(identifier) => identifier.run(_context),
Expression::Index(index) => index.run(_context), Expression::Index(index) => index.run(_context),
Expression::Logic(logic) => logic.run(_context), Expression::Logic(logic) => logic.run(_context),

View File

@ -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<Expression>,
arguments: Vec<Expression>,
}
impl FunctionCall {
pub fn new(function: Expression, arguments: Vec<Expression>) -> Self {
FunctionCall {
function: Box::new(function),
arguments,
}
}
}
impl AbstractTree for FunctionCall {
fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
todo!()
}
fn validate(&self, _context: &Context) -> Result<(), ValidationError> {
todo!()
}
fn run(self, _context: &Context) -> Result<Action, RuntimeError> {
todo!()
}
}

View File

@ -1,6 +1,7 @@
pub mod assignment; pub mod assignment;
pub mod block; pub mod block;
pub mod expression; pub mod expression;
pub mod function_call;
pub mod identifier; pub mod identifier;
pub mod if_else; pub mod if_else;
pub mod index; pub mod index;
@ -15,6 +16,7 @@ pub use self::{
assignment::{Assignment, AssignmentOperator}, assignment::{Assignment, AssignmentOperator},
block::Block, block::Block,
expression::Expression, expression::Expression,
function_call::FunctionCall,
identifier::Identifier, identifier::Identifier,
if_else::IfElse, if_else::IfElse,
index::Index, index::Index,

View File

@ -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(( choice((
function_call,
assignment, assignment,
expression_statement, expression_statement,
r#break, r#break,
@ -327,6 +346,17 @@ mod tests {
use super::*; 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] #[test]
fn range() { fn range() {
assert_eq!( assert_eq!(