From 7b78250eca79298d90e23ad4a5daf14988bde909 Mon Sep 17 00:00:00 2001 From: Jeff Date: Tue, 21 May 2024 19:27:33 -0400 Subject: [PATCH] Continue implementing as expression --- dust-lang/src/abstract_tree/as.rs | 32 +++++++++++++++++++--- dust-lang/src/abstract_tree/expression.rs | 4 ++- dust-lang/src/lexer.rs | 2 +- dust-lang/src/parser.rs | 33 ++++++++++++++++++----- 4 files changed, 59 insertions(+), 12 deletions(-) diff --git a/dust-lang/src/abstract_tree/as.rs b/dust-lang/src/abstract_tree/as.rs index 7db6383..b6da716 100644 --- a/dust-lang/src/abstract_tree/as.rs +++ b/dust-lang/src/abstract_tree/as.rs @@ -1,12 +1,38 @@ -use super::{Expression, Type}; +use super::{AbstractNode, Expression, Type, WithPosition}; +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] pub struct As { expression: Expression, - r#type: Type, + r#type: WithPosition, } impl As { - pub fn new(expression: Expression, r#type: Type) -> Self { + pub fn new(expression: Expression, r#type: WithPosition) -> Self { Self { expression, r#type } } } + +impl AbstractNode for As { + fn expected_type( + &self, + context: &mut crate::context::Context, + ) -> Result { + todo!() + } + + fn validate( + &self, + context: &mut crate::context::Context, + manage_memory: bool, + ) -> Result<(), crate::error::ValidationError> { + todo!() + } + + fn run( + self, + context: &mut crate::context::Context, + manage_memory: bool, + ) -> Result { + todo!() + } +} diff --git a/dust-lang/src/abstract_tree/expression.rs b/dust-lang/src/abstract_tree/expression.rs index f00b44d..e862d59 100644 --- a/dust-lang/src/abstract_tree/expression.rs +++ b/dust-lang/src/abstract_tree/expression.rs @@ -41,6 +41,7 @@ impl Expression { impl AbstractNode for Expression { fn expected_type(&self, _context: &mut Context) -> Result { match self { + Expression::As(r#as) => r#as.item.expected_type(_context), Expression::FunctionCall(function_call) => function_call.item.expected_type(_context), Expression::Identifier(identifier) => { if let Some(r#type) = _context.get_type(&identifier.item)? { @@ -60,12 +61,12 @@ impl AbstractNode for Expression { Expression::BuiltInFunctionCall(built_in_function_call) => { built_in_function_call.item.expected_type(_context) } - Expression::As(_) => todo!(), } } fn validate(&self, context: &mut Context, manage_memory: bool) -> Result<(), ValidationError> { match self { + Expression::As(r#as) => r#as.item.validate(context, manage_memory), Expression::FunctionCall(function_call) => { function_call.item.validate(context, manage_memory) } @@ -98,6 +99,7 @@ impl AbstractNode for Expression { fn run(self, context: &mut Context, manage_memory: bool) -> Result { match self { + Expression::As(r#as) => r#as.item.run(context, manage_memory), Expression::FunctionCall(function_call) => { function_call.item.run(context, manage_memory) } diff --git a/dust-lang/src/lexer.rs b/dust-lang/src/lexer.rs index 0812cbe..446546e 100644 --- a/dust-lang/src/lexer.rs +++ b/dust-lang/src/lexer.rs @@ -258,8 +258,8 @@ pub fn lexer<'src>() -> impl Parser< let identifier_and_keyword = text::ident().map(|text: &str| match text { "any" => Token::Keyword(Keyword::Any), - "as" => Token::Keyword(Keyword::As), "async" => Token::Keyword(Keyword::Async), + "as" => Token::Keyword(Keyword::As), "bool" => Token::Keyword(Keyword::Bool), "break" => Token::Keyword(Keyword::Break), "else" => Token::Keyword(Keyword::Else), diff --git a/dust-lang/src/parser.rs b/dust-lang/src/parser.rs index 48c2c3e..cffb0ec 100644 --- a/dust-lang/src/parser.rs +++ b/dust-lang/src/parser.rs @@ -335,12 +335,6 @@ pub fn parser<'src>( just(Token::Control(Control::DoubleColon)), ); - let r#as = expression - .clone() - .then_ignore(just(Token::Keyword(Keyword::As))) - .then(r#type.clone()) - .map_with(|(expression, r#type), state| todo!()); - let atom = choice(( range.clone(), parsed_function.clone(), @@ -511,9 +505,20 @@ pub fn parser<'src>( ), )); + let r#as = choice(( + basic_value.clone(), + identifier_expression.clone(), + logic_math_indexes_and_function_calls.clone(), + )) + .then_ignore(just(Token::Keyword(Keyword::As))) + .then(r#type.clone()) + .map_with(|(expression, r#type), state| { + Expression::As(Box::new(As::new(expression, r#type)).with_position(state.span())) + }); + choice(( - logic_math_indexes_and_function_calls, r#as, + logic_math_indexes_and_function_calls, built_in_function_call, range, structure_instance, @@ -630,6 +635,20 @@ mod tests { use super::*; + #[test] + fn r#as() { + assert_eq!( + parse(&lex("1 as str").unwrap()).unwrap()[0], + Statement::Expression(Expression::As( + Box::new(As::new( + Expression::Value(ValueNode::Integer(1).with_position((0, 1))), + Type::String.with_position((5, 8)) + )) + .with_position((0, 8)) + )) + ) + } + #[test] fn built_in_function() { let tokens = lex("READ_LINE").unwrap();