From d7d8fd24990d0ee46fe8967c754859b43efa6eed Mon Sep 17 00:00:00 2001 From: Jeff Date: Wed, 20 Mar 2024 22:58:13 -0400 Subject: [PATCH] Run type definitions before other statements --- dust-lang/src/abstract_tree/mod.rs | 71 +++++++++++++++--------------- dust-lang/src/parser.rs | 52 +++++++++++----------- 2 files changed, 62 insertions(+), 61 deletions(-) diff --git a/dust-lang/src/abstract_tree/mod.rs b/dust-lang/src/abstract_tree/mod.rs index 1412355..413a30d 100644 --- a/dust-lang/src/abstract_tree/mod.rs +++ b/dust-lang/src/abstract_tree/mod.rs @@ -16,7 +16,7 @@ pub mod r#type; pub mod value_node; pub mod r#while; -use std::ops::Index; +use std::{cmp::Ordering, ops::Index}; use chumsky::span::{SimpleSpan, Span}; @@ -77,44 +77,43 @@ pub enum Action { pub struct AbstractTree(Vec>); impl AbstractTree { - pub fn new(statements: Vec>) -> Self { + pub fn new(mut statements: Vec>) -> Self { + statements.sort_by(|left, right| match (&left.node, &right.node) { + (Statement::StructureDefinition(_), _) => Ordering::Less, + (_, Statement::StructureDefinition(_)) => Ordering::Greater, + (_, _) => Ordering::Equal, + }); + + println!("{:?}", statements); AbstractTree(statements) } pub fn run(self, context: &Context) -> Result, Vec> { - let mut valid_statements = Vec::with_capacity(self.0.len()); let mut errors = Vec::new(); + let mut valid_statements = Vec::new(); for statement in self.0 { let validation = statement.node.validate(context); - if let Statement::StructureDefinition(_) = statement.node { - match validation { - Ok(_) => { - let run_result = statement.node.run(context); + if let Err(validation_error) = validation { + errors.push(Error::Validation { + error: validation_error, + position: statement.position, + }) + } else if errors.is_empty() { + if let Statement::StructureDefinition(_) = statement.node { + let run = statement.node.run(context); - match run_result { - Ok(_) => {} - Err(runtime_error) => { - return Err(vec![Error::Runtime { - error: runtime_error, - position: statement.position, - }]); - } - } + if let Err(runtime_error) = run { + errors.push(Error::Runtime { + error: runtime_error, + position: statement.position, + }); + + return Err(errors); } - Err(validation_error) => errors.push(Error::Validation { - error: validation_error, - position: statement.position, - }), - } - } else { - match validation { - Ok(_) => valid_statements.push(statement), - Err(validation_error) => errors.push(Error::Validation { - error: validation_error, - position: statement.position, - }), + } else { + valid_statements.push(statement) } } } @@ -123,26 +122,28 @@ impl AbstractTree { return Err(errors); } - let mut previous = None; + let mut previous_value = None; for statement in valid_statements { - let run_result = statement.node.run(context); + let run = statement.node.run(context); - match run_result { + match run { Ok(action) => match action { - Action::Return(value) => previous = Some(value), + Action::Return(value) => previous_value = Some(value), _ => {} }, Err(runtime_error) => { - return Err(vec![Error::Runtime { + errors.push(Error::Runtime { error: runtime_error, position: statement.position, - }]); + }); + + return Err(errors); } } } - Ok(previous) + Ok(previous_value) } } diff --git a/dust-lang/src/parser.rs b/dust-lang/src/parser.rs index 251f99d..0f5c455 100644 --- a/dust-lang/src/parser.rs +++ b/dust-lang/src/parser.rs @@ -125,6 +125,32 @@ pub fn parser<'src>() -> impl Parser< let type_specification = just(Token::Control(Control::Colon)).ignore_then(r#type.clone()); + let structure_field_definition = identifier.clone().then(type_specification.clone()); + + let structure_definition = just(Token::Keyword(Keyword::Struct)) + .ignore_then(identifier.clone()) + .then( + structure_field_definition + .separated_by(just(Token::Control(Control::Comma))) + .allow_trailing() + .collect::)>>() + .delimited_by( + just(Token::Control(Control::CurlyOpen)), + just(Token::Control(Control::CurlyClose)), + ), + ) + .map_with(move |(name, fields), state| { + let definition = StructureDefinition::new(name.clone(), fields.clone()); + let r#type = Type::Structure { + name: name.clone(), + fields, + }; + + custom_types.1.borrow_mut().insert(name, r#type); + + Statement::StructureDefinition(definition).with_position(state.span()) + }); + let positioned_statement = recursive(|positioned_statement| { let block = positioned_statement .clone() @@ -473,32 +499,6 @@ pub fn parser<'src>() -> impl Parser< .with_position(state.span()) }); - let structure_field_definition = identifier.clone().then(type_specification.clone()); - - let structure_definition = just(Token::Keyword(Keyword::Struct)) - .ignore_then(identifier.clone()) - .then( - structure_field_definition - .separated_by(just(Token::Control(Control::Comma))) - .allow_trailing() - .collect::)>>() - .delimited_by( - just(Token::Control(Control::CurlyOpen)), - just(Token::Control(Control::CurlyClose)), - ), - ) - .map_with(move |(name, fields), state| { - let definition = StructureDefinition::new(name.clone(), fields.clone()); - let r#type = Type::Structure { - name: name.clone(), - fields, - }; - - custom_types.1.borrow_mut().insert(name, r#type); - - Statement::StructureDefinition(definition).with_position(state.span()) - }); - choice(( async_block, structure_definition,