From 285e9e72172edd67854b424fa07fb2e8005a7c5b Mon Sep 17 00:00:00 2001 From: Jeff Date: Wed, 7 Aug 2024 18:43:24 -0400 Subject: [PATCH] Implement is_odd and length functions; Pass all tests --- dust-lang/src/abstract_tree.rs | 32 ++++++++++++++++-- dust-lang/src/parse.rs | 60 ++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 2 deletions(-) diff --git a/dust-lang/src/abstract_tree.rs b/dust-lang/src/abstract_tree.rs index b86683d..b20bd06 100644 --- a/dust-lang/src/abstract_tree.rs +++ b/dust-lang/src/abstract_tree.rs @@ -207,8 +207,36 @@ impl BuiltInFunction { Err(BuiltInFunctionError::WrongNumberOfValueArguments) } } - BuiltInFunction::IsOdd => todo!(), - BuiltInFunction::Length => todo!(), + BuiltInFunction::IsOdd => { + if let Some(value_arguments) = value_arguments { + if value_arguments.len() == 1 { + if let Some(integer) = value_arguments[0].as_integer() { + Ok(Value::boolean(integer % 2 != 0)) + } else { + Err(BuiltInFunctionError::ExpectedInteger) + } + } else { + Err(BuiltInFunctionError::WrongNumberOfValueArguments) + } + } else { + Err(BuiltInFunctionError::WrongNumberOfValueArguments) + } + } + BuiltInFunction::Length => { + if let Some(value_arguments) = value_arguments { + if value_arguments.len() == 1 { + if let Some(list) = value_arguments[0].as_list() { + Ok(Value::integer(list.len() as i64)) + } else { + Err(BuiltInFunctionError::ExpectedInteger) + } + } else { + Err(BuiltInFunctionError::WrongNumberOfValueArguments) + } + } else { + Err(BuiltInFunctionError::WrongNumberOfValueArguments) + } + } } } diff --git a/dust-lang/src/parse.rs b/dust-lang/src/parse.rs index 2437146..026f523 100644 --- a/dust-lang/src/parse.rs +++ b/dust-lang/src/parse.rs @@ -283,6 +283,66 @@ impl<'src> Parser<'src> { left_span, )) } + (Token::IsOdd, left_span) => { + self.next_token()?; + + if let (Token::LeftParenthesis, _) = self.current { + self.next_token()?; + } else { + return Err(ParseError::ExpectedOpeningParenthesis { + actual: self.current.0.clone(), + span: self.current.1, + }); + } + + if let (Token::RightParenthesis, _) = self.current { + self.next_token()?; + } else { + return Err(ParseError::ExpectedClosingParenthesis { + actual: self.current.0.clone(), + span: self.current.1, + }); + } + + Ok(Node::new( + Statement::BuiltInFunctionCall { + function: BuiltInFunction::IsOdd, + type_arguments: None, + value_arguments: None, + }, + left_span, + )) + } + (Token::Length, left_span) => { + self.next_token()?; + + if let (Token::LeftParenthesis, _) = self.current { + self.next_token()?; + } else { + return Err(ParseError::ExpectedOpeningParenthesis { + actual: self.current.0.clone(), + span: self.current.1, + }); + } + + if let (Token::RightParenthesis, _) = self.current { + self.next_token()?; + } else { + return Err(ParseError::ExpectedClosingParenthesis { + actual: self.current.0.clone(), + span: self.current.1, + }); + } + + Ok(Node::new( + Statement::BuiltInFunctionCall { + function: BuiltInFunction::Length, + type_arguments: None, + value_arguments: None, + }, + left_span, + )) + } _ => Err(ParseError::UnexpectedToken(self.current.0.clone())), } }