Combine define and verify functions on AST nodes
This commit is contained in:
parent
db94fbdb5b
commit
9bd39338d5
@ -30,12 +30,13 @@ impl As {
|
||||
}
|
||||
|
||||
impl AbstractNode for As {
|
||||
fn define_types(&self, _context: &Context) -> Result<(), ValidationError> {
|
||||
self.expression.define_types(_context)
|
||||
}
|
||||
|
||||
fn validate(&self, _context: &Context, _manage_memory: bool) -> Result<(), ValidationError> {
|
||||
self.expression.validate(_context, _manage_memory)?;
|
||||
fn define_and_validate(
|
||||
&self,
|
||||
_context: &Context,
|
||||
_manage_memory: bool,
|
||||
) -> Result<(), ValidationError> {
|
||||
self.expression
|
||||
.define_and_validate(_context, _manage_memory)?;
|
||||
|
||||
match self.constructor {
|
||||
TypeConstructor::Raw(_) => {}
|
||||
|
@ -43,9 +43,11 @@ impl Assignment {
|
||||
}
|
||||
|
||||
impl AbstractNode for Assignment {
|
||||
fn define_types(&self, context: &Context) -> Result<(), ValidationError> {
|
||||
self.statement.define_types(context)?;
|
||||
|
||||
fn define_and_validate(
|
||||
&self,
|
||||
context: &Context,
|
||||
manage_memory: bool,
|
||||
) -> Result<(), ValidationError> {
|
||||
if let Some(constructor) = &self.constructor {
|
||||
let r#type = constructor.construct(&context)?;
|
||||
|
||||
@ -58,11 +60,7 @@ impl AbstractNode for Assignment {
|
||||
));
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn validate(&self, context: &Context, manage_memory: bool) -> Result<(), ValidationError> {
|
||||
self.statement.validate(context, manage_memory)?;
|
||||
self.statement.define_and_validate(context, manage_memory)?;
|
||||
|
||||
let statement_type = self.statement.expected_type(context)?;
|
||||
|
||||
|
@ -25,17 +25,13 @@ impl AsyncBlock {
|
||||
}
|
||||
|
||||
impl AbstractNode for AsyncBlock {
|
||||
fn define_types(&self, _context: &Context) -> Result<(), ValidationError> {
|
||||
fn define_and_validate(
|
||||
&self,
|
||||
_context: &Context,
|
||||
manage_memory: bool,
|
||||
) -> Result<(), ValidationError> {
|
||||
for statement in &self.statements {
|
||||
statement.define_types(_context)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn validate(&self, _context: &Context, manage_memory: bool) -> Result<(), ValidationError> {
|
||||
for statement in &self.statements {
|
||||
statement.validate(_context, manage_memory)?;
|
||||
statement.define_and_validate(_context, manage_memory)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -29,17 +29,13 @@ impl Block {
|
||||
}
|
||||
|
||||
impl AbstractNode for Block {
|
||||
fn define_types(&self, _context: &Context) -> Result<(), ValidationError> {
|
||||
fn define_and_validate(
|
||||
&self,
|
||||
_context: &Context,
|
||||
_manage_memory: bool,
|
||||
) -> Result<(), ValidationError> {
|
||||
for statement in &self.statements {
|
||||
statement.define_types(_context)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn validate(&self, _context: &Context, _manage_memory: bool) -> Result<(), ValidationError> {
|
||||
for statement in &self.statements {
|
||||
statement.validate(_context, _manage_memory)?;
|
||||
statement.define_and_validate(_context, _manage_memory)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -32,7 +32,7 @@ impl EnumDeclaration {
|
||||
}
|
||||
|
||||
impl AbstractNode for EnumDeclaration {
|
||||
fn define_types(&self, context: &Context) -> Result<(), ValidationError> {
|
||||
fn define_and_validate(&self, context: &Context, _: bool) -> Result<(), ValidationError> {
|
||||
let EnumDeclaration {
|
||||
name,
|
||||
type_parameters,
|
||||
@ -79,10 +79,6 @@ impl AbstractNode for EnumDeclaration {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn validate(&self, _: &Context, _: bool) -> Result<(), ValidationError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn evaluate(self, _: &Context, _: bool) -> Result<Option<Evaluation>, RuntimeError> {
|
||||
Ok(None)
|
||||
}
|
||||
|
@ -41,25 +41,16 @@ impl Expression {
|
||||
}
|
||||
|
||||
impl AbstractNode for Expression {
|
||||
fn define_types(&self, _context: &Context) -> Result<(), ValidationError> {
|
||||
fn define_and_validate(
|
||||
&self,
|
||||
context: &Context,
|
||||
manage_memory: bool,
|
||||
) -> Result<(), ValidationError> {
|
||||
match self {
|
||||
Expression::As(inner) => inner.node.define_types(_context),
|
||||
Expression::FunctionCall(inner) => inner.node.define_types(_context),
|
||||
Expression::Identifier(_) => Ok(()),
|
||||
Expression::MapIndex(inner) => inner.node.define_types(_context),
|
||||
Expression::ListIndex(inner) => inner.node.define_types(_context),
|
||||
Expression::Logic(inner) => inner.node.define_types(_context),
|
||||
Expression::Math(inner) => inner.node.define_types(_context),
|
||||
Expression::Value(inner) => inner.node.define_types(_context),
|
||||
}
|
||||
}
|
||||
|
||||
fn validate(&self, context: &Context, manage_memory: bool) -> Result<(), ValidationError> {
|
||||
match self {
|
||||
Expression::As(r#as) => r#as.node.validate(context, manage_memory),
|
||||
Expression::FunctionCall(function_call) => {
|
||||
function_call.node.validate(context, manage_memory)
|
||||
}
|
||||
Expression::As(r#as) => r#as.node.define_and_validate(context, manage_memory),
|
||||
Expression::FunctionCall(function_call) => function_call
|
||||
.node
|
||||
.define_and_validate(context, manage_memory),
|
||||
Expression::Identifier(identifier) => {
|
||||
let found = context.add_expected_use(&identifier.node)?;
|
||||
|
||||
@ -72,11 +63,17 @@ impl AbstractNode for Expression {
|
||||
})
|
||||
}
|
||||
}
|
||||
Expression::MapIndex(map_index) => map_index.node.validate(context, manage_memory),
|
||||
Expression::ListIndex(list_index) => list_index.node.validate(context, manage_memory),
|
||||
Expression::Logic(logic) => logic.node.validate(context, manage_memory),
|
||||
Expression::Math(math) => math.node.validate(context, manage_memory),
|
||||
Expression::Value(value_node) => value_node.node.validate(context, manage_memory),
|
||||
Expression::MapIndex(map_index) => {
|
||||
map_index.node.define_and_validate(context, manage_memory)
|
||||
}
|
||||
Expression::ListIndex(list_index) => {
|
||||
list_index.node.define_and_validate(context, manage_memory)
|
||||
}
|
||||
Expression::Logic(logic) => logic.node.define_and_validate(context, manage_memory),
|
||||
Expression::Math(math) => math.node.define_and_validate(context, manage_memory),
|
||||
Expression::Value(value_node) => {
|
||||
value_node.node.define_and_validate(context, manage_memory)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,31 +39,18 @@ impl FunctionCall {
|
||||
}
|
||||
|
||||
impl AbstractNode for FunctionCall {
|
||||
fn define_types(&self, context: &Context) -> Result<(), ValidationError> {
|
||||
self.function_expression.define_types(context)?;
|
||||
|
||||
if let Some(expressions) = &self.value_arguments {
|
||||
for expression in expressions {
|
||||
expression.define_types(context)?;
|
||||
}
|
||||
}
|
||||
|
||||
self.context.set_parent(context.clone())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn validate(
|
||||
fn define_and_validate(
|
||||
&self,
|
||||
outer_context: &Context,
|
||||
manage_memory: bool,
|
||||
) -> Result<(), ValidationError> {
|
||||
self.context.set_parent(outer_context.clone())?;
|
||||
self.function_expression
|
||||
.validate(outer_context, manage_memory)?;
|
||||
.define_and_validate(outer_context, manage_memory)?;
|
||||
|
||||
if let Some(value_arguments) = &self.value_arguments {
|
||||
for expression in value_arguments {
|
||||
expression.validate(outer_context, manage_memory)?;
|
||||
expression.define_and_validate(outer_context, manage_memory)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,27 +35,16 @@ impl IfElse {
|
||||
}
|
||||
|
||||
impl AbstractNode for IfElse {
|
||||
fn define_types(&self, _context: &Context) -> Result<(), ValidationError> {
|
||||
self.if_expression.define_types(_context)?;
|
||||
self.if_block.node.define_types(_context)?;
|
||||
|
||||
if let Some(else_ifs) = &self.else_ifs {
|
||||
for (expression, block) in else_ifs {
|
||||
expression.define_types(_context)?;
|
||||
block.node.define_types(_context)?;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(else_block) = &self.else_block {
|
||||
else_block.node.define_types(_context)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn validate(&self, context: &Context, manage_memory: bool) -> Result<(), ValidationError> {
|
||||
self.if_expression.validate(context, manage_memory)?;
|
||||
self.if_block.node.validate(context, manage_memory)?;
|
||||
fn define_and_validate(
|
||||
&self,
|
||||
context: &Context,
|
||||
manage_memory: bool,
|
||||
) -> Result<(), ValidationError> {
|
||||
self.if_expression
|
||||
.define_and_validate(context, manage_memory)?;
|
||||
self.if_block
|
||||
.node
|
||||
.define_and_validate(context, manage_memory)?;
|
||||
|
||||
let if_expression_type = if let Some(r#type) = self.if_expression.expected_type(context)? {
|
||||
r#type
|
||||
@ -71,7 +60,7 @@ impl AbstractNode for IfElse {
|
||||
let expression_type = expression.expected_type(context)?;
|
||||
|
||||
if let Some(Type::Boolean) = expression_type {
|
||||
block.node.validate(context, manage_memory)?;
|
||||
block.node.define_and_validate(context, manage_memory)?;
|
||||
|
||||
let else_if_block_type = block.node.expected_type(context)?;
|
||||
|
||||
@ -94,7 +83,7 @@ impl AbstractNode for IfElse {
|
||||
}
|
||||
|
||||
if let Some(block) = &self.else_block {
|
||||
block.node.validate(context, manage_memory)?;
|
||||
block.node.define_and_validate(context, manage_memory)?;
|
||||
|
||||
let else_if_block_type = block.node.expected_type(context)?;
|
||||
|
||||
|
@ -25,14 +25,14 @@ impl ListIndex {
|
||||
}
|
||||
|
||||
impl AbstractNode for ListIndex {
|
||||
fn define_types(&self, context: &Context) -> Result<(), ValidationError> {
|
||||
self.collection.define_types(context)?;
|
||||
self.index.define_types(context)
|
||||
}
|
||||
|
||||
fn validate(&self, context: &Context, _manage_memory: bool) -> Result<(), ValidationError> {
|
||||
self.collection.validate(context, _manage_memory)?;
|
||||
self.index.validate(context, _manage_memory)?;
|
||||
fn define_and_validate(
|
||||
&self,
|
||||
context: &Context,
|
||||
_manage_memory: bool,
|
||||
) -> Result<(), ValidationError> {
|
||||
self.collection
|
||||
.define_and_validate(context, _manage_memory)?;
|
||||
self.index.define_and_validate(context, _manage_memory)?;
|
||||
|
||||
let collection_type = if let Some(r#type) = self.collection.expected_type(context)? {
|
||||
r#type
|
||||
|
@ -25,45 +25,11 @@ pub enum Logic {
|
||||
}
|
||||
|
||||
impl AbstractNode for Logic {
|
||||
fn define_types(&self, _context: &Context) -> Result<(), ValidationError> {
|
||||
match self {
|
||||
Logic::Equal(left, right) => {
|
||||
left.define_types(_context)?;
|
||||
right.define_types(_context)
|
||||
}
|
||||
Logic::NotEqual(left, right) => {
|
||||
left.define_types(_context)?;
|
||||
right.define_types(_context)
|
||||
}
|
||||
Logic::Greater(left, right) => {
|
||||
left.define_types(_context)?;
|
||||
right.define_types(_context)
|
||||
}
|
||||
Logic::Less(left, right) => {
|
||||
left.define_types(_context)?;
|
||||
right.define_types(_context)
|
||||
}
|
||||
Logic::GreaterOrEqual(left, right) => {
|
||||
left.define_types(_context)?;
|
||||
right.define_types(_context)
|
||||
}
|
||||
Logic::LessOrEqual(left, right) => {
|
||||
left.define_types(_context)?;
|
||||
right.define_types(_context)
|
||||
}
|
||||
Logic::And(left, right) => {
|
||||
left.define_types(_context)?;
|
||||
right.define_types(_context)
|
||||
}
|
||||
Logic::Or(left, right) => {
|
||||
left.define_types(_context)?;
|
||||
right.define_types(_context)
|
||||
}
|
||||
Logic::Not(expression) => expression.define_types(_context),
|
||||
}
|
||||
}
|
||||
|
||||
fn validate(&self, context: &Context, _manage_memory: bool) -> Result<(), ValidationError> {
|
||||
fn define_and_validate(
|
||||
&self,
|
||||
context: &Context,
|
||||
_manage_memory: bool,
|
||||
) -> Result<(), ValidationError> {
|
||||
match self {
|
||||
Logic::Equal(left, right)
|
||||
| Logic::NotEqual(left, right)
|
||||
@ -71,8 +37,8 @@ impl AbstractNode for Logic {
|
||||
| Logic::Less(left, right)
|
||||
| Logic::GreaterOrEqual(left, right)
|
||||
| Logic::LessOrEqual(left, right) => {
|
||||
left.validate(context, _manage_memory)?;
|
||||
right.validate(context, _manage_memory)?;
|
||||
left.define_and_validate(context, _manage_memory)?;
|
||||
right.define_and_validate(context, _manage_memory)?;
|
||||
|
||||
let left_type = if let Some(r#type) = left.expected_type(context)? {
|
||||
r#type
|
||||
@ -96,8 +62,8 @@ impl AbstractNode for Logic {
|
||||
Ok(())
|
||||
}
|
||||
Logic::And(left, right) | Logic::Or(left, right) => {
|
||||
left.validate(context, _manage_memory)?;
|
||||
right.validate(context, _manage_memory)?;
|
||||
left.define_and_validate(context, _manage_memory)?;
|
||||
right.define_and_validate(context, _manage_memory)?;
|
||||
|
||||
let left_type = if let Some(r#type) = left.expected_type(context)? {
|
||||
r#type
|
||||
@ -129,7 +95,7 @@ impl AbstractNode for Logic {
|
||||
Ok(())
|
||||
}
|
||||
Logic::Not(expression) => {
|
||||
expression.validate(context, _manage_memory)?;
|
||||
expression.define_and_validate(context, _manage_memory)?;
|
||||
|
||||
let expression_type = if let Some(r#type) = expression.expected_type(context)? {
|
||||
r#type
|
||||
|
@ -25,17 +25,13 @@ impl Loop {
|
||||
}
|
||||
|
||||
impl AbstractNode for Loop {
|
||||
fn define_types(&self, _context: &Context) -> Result<(), ValidationError> {
|
||||
fn define_and_validate(
|
||||
&self,
|
||||
_context: &Context,
|
||||
_manage_memory: bool,
|
||||
) -> Result<(), ValidationError> {
|
||||
for statement in &self.statements {
|
||||
statement.define_types(_context)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn validate(&self, _context: &Context, _manage_memory: bool) -> Result<(), ValidationError> {
|
||||
for statement in &self.statements {
|
||||
statement.validate(_context, false)?;
|
||||
statement.define_and_validate(_context, false)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -26,13 +26,13 @@ impl MapIndex {
|
||||
}
|
||||
|
||||
impl AbstractNode for MapIndex {
|
||||
fn define_types(&self, _context: &Context) -> Result<(), ValidationError> {
|
||||
self.collection.define_types(_context)?;
|
||||
self.index.define_types(_context)
|
||||
}
|
||||
|
||||
fn validate(&self, context: &Context, _manage_memory: bool) -> Result<(), ValidationError> {
|
||||
self.collection.validate(context, _manage_memory)?;
|
||||
fn define_and_validate(
|
||||
&self,
|
||||
context: &Context,
|
||||
_manage_memory: bool,
|
||||
) -> Result<(), ValidationError> {
|
||||
self.collection
|
||||
.define_and_validate(context, _manage_memory)?;
|
||||
|
||||
let collection_type = if let Some(r#type) = self.collection.expected_type(context)? {
|
||||
r#type
|
||||
@ -56,7 +56,7 @@ impl AbstractNode for MapIndex {
|
||||
if let Expression::Identifier(_) = &self.index {
|
||||
Ok(())
|
||||
} else {
|
||||
self.index.validate(context, _manage_memory)
|
||||
self.index.define_and_validate(context, _manage_memory)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,32 +21,11 @@ pub enum Math {
|
||||
}
|
||||
|
||||
impl AbstractNode for Math {
|
||||
fn define_types(&self, _context: &Context) -> Result<(), ValidationError> {
|
||||
match self {
|
||||
Math::Add(left, right) => {
|
||||
left.define_types(_context)?;
|
||||
right.define_types(_context)
|
||||
}
|
||||
Math::Subtract(left, right) => {
|
||||
left.define_types(_context)?;
|
||||
right.define_types(_context)
|
||||
}
|
||||
Math::Multiply(left, right) => {
|
||||
left.define_types(_context)?;
|
||||
right.define_types(_context)
|
||||
}
|
||||
Math::Divide(left, right) => {
|
||||
left.define_types(_context)?;
|
||||
right.define_types(_context)
|
||||
}
|
||||
Math::Modulo(left, right) => {
|
||||
left.define_types(_context)?;
|
||||
right.define_types(_context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn validate(&self, context: &Context, _manage_memory: bool) -> Result<(), ValidationError> {
|
||||
fn define_and_validate(
|
||||
&self,
|
||||
context: &Context,
|
||||
_manage_memory: bool,
|
||||
) -> Result<(), ValidationError> {
|
||||
match self {
|
||||
Math::Add(left, right) => {
|
||||
let left_type = if let Some(r#type) = left.expected_type(context)? {
|
||||
|
@ -58,6 +58,7 @@ pub use self::{
|
||||
use crate::{
|
||||
context::Context,
|
||||
error::{DustError, RuntimeError, ValidationError},
|
||||
identifier::Identifier,
|
||||
Value,
|
||||
};
|
||||
|
||||
@ -128,18 +129,7 @@ impl AbstractTree {
|
||||
let mut errors = Vec::new();
|
||||
|
||||
for statement in &self.0 {
|
||||
let define_result = statement.define_types(context);
|
||||
|
||||
if let Err(error) = define_result {
|
||||
errors.push(DustError::Validation {
|
||||
error,
|
||||
position: statement.position(),
|
||||
});
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
let validation_result = statement.validate(context, manage_memory);
|
||||
let validation_result = statement.define_and_validate(context, manage_memory);
|
||||
|
||||
if let Err(error) = validation_result {
|
||||
errors.push(DustError::Validation {
|
||||
@ -187,17 +177,13 @@ impl Index<usize> for AbstractTree {
|
||||
}
|
||||
|
||||
impl AbstractNode for AbstractTree {
|
||||
fn define_types(&self, context: &Context) -> Result<(), ValidationError> {
|
||||
fn define_and_validate(
|
||||
&self,
|
||||
context: &Context,
|
||||
manage_memory: bool,
|
||||
) -> Result<(), ValidationError> {
|
||||
for statement in &self.0 {
|
||||
statement.define_types(context)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn validate(&self, context: &Context, manage_memory: bool) -> Result<(), ValidationError> {
|
||||
for statement in &self.0 {
|
||||
statement.validate(context, manage_memory)?;
|
||||
statement.define_and_validate(context, manage_memory)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -223,9 +209,11 @@ impl AbstractNode for AbstractTree {
|
||||
}
|
||||
|
||||
pub trait AbstractNode {
|
||||
fn define_types(&self, context: &Context) -> Result<(), ValidationError>;
|
||||
|
||||
fn validate(&self, context: &Context, manage_memory: bool) -> Result<(), ValidationError>;
|
||||
fn define_and_validate(
|
||||
&self,
|
||||
context: &Context,
|
||||
manage_memory: bool,
|
||||
) -> Result<(), ValidationError>;
|
||||
|
||||
fn evaluate(
|
||||
self,
|
||||
|
@ -58,44 +58,40 @@ impl Statement {
|
||||
}
|
||||
|
||||
impl AbstractNode for Statement {
|
||||
fn define_types(&self, _context: &Context) -> Result<(), ValidationError> {
|
||||
log::trace!("Defining types for statement at {}", self.position());
|
||||
|
||||
match self {
|
||||
Statement::Expression(expression) => expression.define_types(_context),
|
||||
Statement::IfElse(if_else) => if_else.node.define_types(_context),
|
||||
Statement::Block(block) => block.node.define_types(_context),
|
||||
Statement::AsyncBlock(async_block) => async_block.node.define_types(_context),
|
||||
Statement::Assignment(assignment) => assignment.node.define_types(_context),
|
||||
Statement::Loop(r#loop) => r#loop.node.define_types(_context),
|
||||
Statement::StructureDefinition(struct_definition) => {
|
||||
struct_definition.node.define_types(_context)
|
||||
}
|
||||
Statement::TypeAlias(type_alias) => type_alias.node.define_types(_context),
|
||||
Statement::EnumDeclaration(enum_declaration) => {
|
||||
enum_declaration.node.define_types(_context)
|
||||
}
|
||||
Statement::While(r#while) => r#while.node.define_types(_context),
|
||||
Statement::Use(r#use) => r#use.node.define_types(_context),
|
||||
Statement::Break(_) | Statement::Null(_) => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
fn validate(&self, _context: &Context, _manage_memory: bool) -> Result<(), ValidationError> {
|
||||
fn define_and_validate(
|
||||
&self,
|
||||
_context: &Context,
|
||||
_manage_memory: bool,
|
||||
) -> Result<(), ValidationError> {
|
||||
log::trace!("Validating statement at {}", self.position());
|
||||
|
||||
match self {
|
||||
Statement::Assignment(assignment) => assignment.node.validate(_context, _manage_memory),
|
||||
Statement::AsyncBlock(async_block) => {
|
||||
async_block.node.validate(_context, _manage_memory)
|
||||
Statement::Assignment(assignment) => assignment
|
||||
.node
|
||||
.define_and_validate(_context, _manage_memory),
|
||||
Statement::AsyncBlock(async_block) => async_block
|
||||
.node
|
||||
.define_and_validate(_context, _manage_memory),
|
||||
Statement::Block(block) => block.node.define_and_validate(_context, _manage_memory),
|
||||
Statement::EnumDeclaration(enum_declaration) => enum_declaration
|
||||
.node
|
||||
.define_and_validate(_context, _manage_memory),
|
||||
Statement::Expression(expression) => {
|
||||
expression.define_and_validate(_context, _manage_memory)
|
||||
}
|
||||
Statement::Block(block) => block.node.validate(_context, _manage_memory),
|
||||
Statement::Expression(expression) => expression.validate(_context, _manage_memory),
|
||||
Statement::IfElse(if_else) => if_else.node.validate(_context, _manage_memory),
|
||||
Statement::Loop(r#loop) => r#loop.node.validate(_context, _manage_memory),
|
||||
Statement::While(r#while) => r#while.node.validate(_context, _manage_memory),
|
||||
Statement::Use(r#use) => r#use.node.validate(_context, _manage_memory),
|
||||
_ => Ok(()),
|
||||
Statement::IfElse(if_else) => {
|
||||
if_else.node.define_and_validate(_context, _manage_memory)
|
||||
}
|
||||
Statement::Loop(r#loop) => r#loop.node.define_and_validate(_context, _manage_memory),
|
||||
Statement::StructureDefinition(struct_definition) => struct_definition
|
||||
.node
|
||||
.define_and_validate(_context, _manage_memory),
|
||||
Statement::TypeAlias(type_alias) => type_alias
|
||||
.node
|
||||
.define_and_validate(_context, _manage_memory),
|
||||
Statement::While(r#while) => r#while.node.define_and_validate(_context, _manage_memory),
|
||||
Statement::Use(r#use) => r#use.node.define_and_validate(_context, _manage_memory),
|
||||
Statement::Break(_) | Statement::Null(_) => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ impl StructureDefinition {
|
||||
}
|
||||
|
||||
impl AbstractNode for StructureDefinition {
|
||||
fn define_types(&self, context: &Context) -> Result<(), ValidationError> {
|
||||
fn define_and_validate(&self, context: &Context, _: bool) -> Result<(), ValidationError> {
|
||||
let mut fields = Vec::with_capacity(self.fields.len());
|
||||
|
||||
for (identifier, constructor) in &self.fields {
|
||||
@ -42,10 +42,6 @@ impl AbstractNode for StructureDefinition {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn validate(&self, _: &Context, _: bool) -> Result<(), ValidationError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn evaluate(
|
||||
self,
|
||||
context: &Context,
|
||||
|
@ -26,7 +26,7 @@ impl TypeAlias {
|
||||
}
|
||||
|
||||
impl AbstractNode for TypeAlias {
|
||||
fn define_types(&self, context: &Context) -> Result<(), ValidationError> {
|
||||
fn define_and_validate(&self, context: &Context, _: bool) -> Result<(), ValidationError> {
|
||||
let r#type = self.constructor.construct(&context)?;
|
||||
|
||||
context.set_type(self.identifier.node.clone(), r#type)?;
|
||||
@ -34,10 +34,6 @@ impl AbstractNode for TypeAlias {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn validate(&self, _: &Context, _: bool) -> Result<(), ValidationError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn evaluate(self, _: &Context, _: bool) -> Result<Option<Evaluation>, RuntimeError> {
|
||||
Ok(None)
|
||||
}
|
||||
|
@ -37,7 +37,11 @@ impl Use {
|
||||
}
|
||||
|
||||
impl AbstractNode for Use {
|
||||
fn define_types(&self, _context: &Context) -> Result<(), ValidationError> {
|
||||
fn define_and_validate(
|
||||
&self,
|
||||
context: &Context,
|
||||
manage_memory: bool,
|
||||
) -> Result<(), ValidationError> {
|
||||
let abstract_tree = match self.path.as_str() {
|
||||
"std.fs" => std_fs_compiled().clone(),
|
||||
"std.json" => std_json_compiled().clone(),
|
||||
@ -52,16 +56,10 @@ impl AbstractNode for Use {
|
||||
}
|
||||
};
|
||||
|
||||
abstract_tree.define_types(_context)?;
|
||||
|
||||
*self.abstract_tree.write()? = Some(abstract_tree);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn validate(&self, context: &Context, manage_memory: bool) -> Result<(), ValidationError> {
|
||||
if let Some(abstract_tree) = self.abstract_tree.read()?.as_ref() {
|
||||
abstract_tree.validate(context, manage_memory)
|
||||
abstract_tree.define_and_validate(context, manage_memory)
|
||||
} else {
|
||||
Err(ValidationError::Uninitialized)
|
||||
}
|
||||
|
@ -59,68 +59,11 @@ impl ValueNode {
|
||||
}
|
||||
|
||||
impl AbstractNode for ValueNode {
|
||||
fn define_types(&self, outer_context: &Context) -> Result<(), ValidationError> {
|
||||
match self {
|
||||
ValueNode::EnumInstance { content, .. } => {
|
||||
if let Some(expressions) = content {
|
||||
for expression in expressions {
|
||||
expression.define_types(outer_context)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
ValueNode::List(expressions) => {
|
||||
for expression in expressions {
|
||||
expression.define_types(outer_context)?;
|
||||
}
|
||||
}
|
||||
ValueNode::Map(fields) => {
|
||||
for (_, _, expression) in fields {
|
||||
expression.define_types(outer_context)?;
|
||||
}
|
||||
}
|
||||
ValueNode::Structure { fields, .. } => {
|
||||
for (_, expression) in fields {
|
||||
expression.define_types(outer_context)?;
|
||||
}
|
||||
}
|
||||
ValueNode::Function(FunctionNode {
|
||||
body,
|
||||
type_parameters,
|
||||
value_parameters,
|
||||
validation_context,
|
||||
..
|
||||
}) => {
|
||||
validation_context.set_parent(outer_context.clone())?;
|
||||
|
||||
if let Some(type_parameters) = type_parameters {
|
||||
for identifier in type_parameters {
|
||||
validation_context.set_type(
|
||||
identifier.clone(),
|
||||
Type::Generic {
|
||||
identifier: identifier.clone(),
|
||||
concrete_type: None,
|
||||
},
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(value_parameters) = value_parameters {
|
||||
for (identifier, type_constructor) in value_parameters {
|
||||
let r#type = type_constructor.clone().construct(outer_context)?;
|
||||
|
||||
validation_context.set_type(identifier.clone(), r#type)?;
|
||||
}
|
||||
}
|
||||
|
||||
body.node.define_types(validation_context)?;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn validate(&self, context: &Context, _manage_memory: bool) -> Result<(), ValidationError> {
|
||||
fn define_and_validate(
|
||||
&self,
|
||||
context: &Context,
|
||||
_manage_memory: bool,
|
||||
) -> Result<(), ValidationError> {
|
||||
if let ValueNode::List(list) = self {
|
||||
let mut items = list.into_iter();
|
||||
let first_item = items.next().unwrap();
|
||||
@ -133,6 +76,8 @@ impl AbstractNode for ValueNode {
|
||||
};
|
||||
|
||||
for item in items {
|
||||
item.define_and_validate(context, _manage_memory)?;
|
||||
|
||||
let item_type = if let Some(r#type) = item.expected_type(context)? {
|
||||
r#type
|
||||
} else {
|
||||
@ -150,9 +95,17 @@ impl AbstractNode for ValueNode {
|
||||
}
|
||||
|
||||
if let ValueNode::EnumInstance {
|
||||
type_name, variant, ..
|
||||
type_name,
|
||||
variant,
|
||||
content,
|
||||
} = self
|
||||
{
|
||||
if let Some(expressions) = content {
|
||||
for expression in expressions {
|
||||
expression.define_and_validate(context, _manage_memory)?;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(Type::Enum { variants, .. }) = context.get_type(&type_name.node)? {
|
||||
if variants
|
||||
.iter()
|
||||
@ -174,7 +127,7 @@ impl AbstractNode for ValueNode {
|
||||
|
||||
if let ValueNode::Map(map_assignments) = self {
|
||||
for (_identifier, constructor_option, expression) in map_assignments {
|
||||
expression.validate(context, _manage_memory)?;
|
||||
expression.define_and_validate(context, _manage_memory)?;
|
||||
|
||||
if let Some(constructor) = constructor_option {
|
||||
let actual_type = if let Some(r#type) = expression.expected_type(context)? {
|
||||
@ -203,10 +156,36 @@ impl AbstractNode for ValueNode {
|
||||
return_type,
|
||||
body,
|
||||
validation_context,
|
||||
..
|
||||
type_parameters,
|
||||
value_parameters,
|
||||
}) = self
|
||||
{
|
||||
body.node.validate(&validation_context, _manage_memory)?;
|
||||
let outer_context = context;
|
||||
|
||||
validation_context.set_parent(outer_context.clone())?;
|
||||
|
||||
if let Some(type_parameters) = type_parameters {
|
||||
for identifier in type_parameters {
|
||||
validation_context.set_type(
|
||||
identifier.clone(),
|
||||
Type::Generic {
|
||||
identifier: identifier.clone(),
|
||||
concrete_type: None,
|
||||
},
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(value_parameters) = value_parameters {
|
||||
for (identifier, type_constructor) in value_parameters {
|
||||
let r#type = type_constructor.clone().construct(outer_context)?;
|
||||
|
||||
validation_context.set_type(identifier.clone(), r#type)?;
|
||||
}
|
||||
}
|
||||
|
||||
body.node
|
||||
.define_and_validate(&validation_context, _manage_memory)?;
|
||||
|
||||
let ((expected_return, expected_position), actual_return) =
|
||||
match (return_type, body.node.expected_type(&validation_context)?) {
|
||||
@ -259,6 +238,8 @@ impl AbstractNode for ValueNode {
|
||||
}) = context.get_type(&name.node)?
|
||||
{
|
||||
for ((_, expression), (_, expected_type)) in expressions.iter().zip(types.iter()) {
|
||||
expression.define_and_validate(context, _manage_memory)?;
|
||||
|
||||
let actual_type = if let Some(r#type) = expression.expected_type(context)? {
|
||||
r#type
|
||||
} else {
|
||||
|
@ -27,21 +27,15 @@ impl While {
|
||||
}
|
||||
|
||||
impl AbstractNode for While {
|
||||
fn define_types(&self, _context: &Context) -> Result<(), ValidationError> {
|
||||
self.expression.define_types(_context)?;
|
||||
fn define_and_validate(
|
||||
&self,
|
||||
_context: &Context,
|
||||
_manage_memory: bool,
|
||||
) -> Result<(), ValidationError> {
|
||||
self.expression.define_and_validate(_context, false)?;
|
||||
|
||||
for statement in &self.statements {
|
||||
statement.define_types(_context)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn validate(&self, _context: &Context, _manage_memory: bool) -> Result<(), ValidationError> {
|
||||
self.expression.validate(_context, false)?;
|
||||
|
||||
for statement in &self.statements {
|
||||
statement.validate(_context, false)?;
|
||||
statement.define_and_validate(_context, false)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -32,10 +32,7 @@ pub fn core_context<'a>() -> &'a Context {
|
||||
let std_core = std_core_compiled().clone();
|
||||
|
||||
std_core
|
||||
.define_types(&context)
|
||||
.expect("Failed to define types for std.core");
|
||||
std_core
|
||||
.validate(&context, true)
|
||||
.define_and_validate(&context, true)
|
||||
.expect("Failed to validate std.core");
|
||||
std_core
|
||||
.evaluate(&context, true)
|
||||
|
Loading…
Reference in New Issue
Block a user