Run type definitions before other statements
This commit is contained in:
parent
fd0204fefa
commit
d7d8fd2499
@ -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 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 {
|
if let Statement::StructureDefinition(_) = statement.node {
|
||||||
match validation {
|
let run = statement.node.run(context);
|
||||||
Ok(_) => {
|
|
||||||
let run_result = statement.node.run(context);
|
|
||||||
|
|
||||||
match run_result {
|
if let Err(runtime_error) = run {
|
||||||
Ok(_) => {}
|
errors.push(Error::Runtime {
|
||||||
Err(runtime_error) => {
|
|
||||||
return Err(vec![Error::Runtime {
|
|
||||||
error: runtime_error,
|
error: runtime_error,
|
||||||
position: statement.position,
|
position: statement.position,
|
||||||
}]);
|
});
|
||||||
}
|
|
||||||
}
|
return Err(errors);
|
||||||
}
|
|
||||||
Err(validation_error) => errors.push(Error::Validation {
|
|
||||||
error: validation_error,
|
|
||||||
position: statement.position,
|
|
||||||
}),
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
match validation {
|
valid_statements.push(statement)
|
||||||
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user