Run type definitions before other statements

This commit is contained in:
Jeff 2024-03-20 22:58:13 -04:00
parent fd0204fefa
commit d7d8fd2499
2 changed files with 62 additions and 61 deletions

View File

@ -16,7 +16,7 @@ pub mod r#type;
pub mod value_node; pub mod value_node;
pub mod r#while; pub mod r#while;
use std::ops::Index; use std::{cmp::Ordering, ops::Index};
use chumsky::span::{SimpleSpan, Span}; use chumsky::span::{SimpleSpan, Span};
@ -77,44 +77,43 @@ pub enum Action {
pub struct AbstractTree(Vec<WithPosition<Statement>>); pub struct AbstractTree(Vec<WithPosition<Statement>>);
impl AbstractTree { impl AbstractTree {
pub fn new(statements: Vec<WithPosition<Statement>>) -> Self { pub fn new(mut statements: Vec<WithPosition<Statement>>) -> 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) AbstractTree(statements)
} }
pub fn run(self, context: &Context) -> Result<Option<Value>, Vec<Error>> { pub fn run(self, context: &Context) -> Result<Option<Value>, Vec<Error>> {
let mut valid_statements = Vec::with_capacity(self.0.len());
let mut errors = Vec::new(); let mut errors = Vec::new();
let mut valid_statements = Vec::new();
for statement in self.0 { for statement in self.0 {
let validation = statement.node.validate(context); let validation = statement.node.validate(context);
if let Statement::StructureDefinition(_) = statement.node { if let Err(validation_error) = validation {
match validation { errors.push(Error::Validation {
Ok(_) => { error: validation_error,
let run_result = statement.node.run(context); position: statement.position,
})
} else if errors.is_empty() {
if let Statement::StructureDefinition(_) = statement.node {
let run = statement.node.run(context);
match run_result { if let Err(runtime_error) = run {
Ok(_) => {} errors.push(Error::Runtime {
Err(runtime_error) => { error: runtime_error,
return Err(vec![Error::Runtime { position: statement.position,
error: runtime_error, });
position: statement.position,
}]); return Err(errors);
}
}
} }
Err(validation_error) => errors.push(Error::Validation { } else {
error: validation_error, valid_statements.push(statement)
position: statement.position,
}),
}
} else {
match validation {
Ok(_) => valid_statements.push(statement),
Err(validation_error) => errors.push(Error::Validation {
error: validation_error,
position: statement.position,
}),
} }
} }
} }
@ -123,26 +122,28 @@ impl AbstractTree {
return Err(errors); return Err(errors);
} }
let mut previous = None; let mut previous_value = None;
for statement in valid_statements { 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 { Ok(action) => match action {
Action::Return(value) => previous = Some(value), Action::Return(value) => previous_value = Some(value),
_ => {} _ => {}
}, },
Err(runtime_error) => { Err(runtime_error) => {
return Err(vec![Error::Runtime { errors.push(Error::Runtime {
error: runtime_error, error: runtime_error,
position: statement.position, position: statement.position,
}]); });
return Err(errors);
} }
} }
} }
Ok(previous) Ok(previous_value)
} }
} }

View File

@ -125,6 +125,32 @@ pub fn parser<'src>() -> impl Parser<
let type_specification = just(Token::Control(Control::Colon)).ignore_then(r#type.clone()); 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::<Vec<(Identifier, WithPosition<Type>)>>()
.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 positioned_statement = recursive(|positioned_statement| {
let block = positioned_statement let block = positioned_statement
.clone() .clone()
@ -473,32 +499,6 @@ pub fn parser<'src>() -> impl Parser<
.with_position(state.span()) .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::<Vec<(Identifier, WithPosition<Type>)>>()
.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(( choice((
async_block, async_block,
structure_definition, structure_definition,