Combine define and verify functions on AST nodes

This commit is contained in:
Jeff 2024-07-02 13:11:31 -04:00
parent db94fbdb5b
commit 9bd39338d5
21 changed files with 205 additions and 358 deletions

View File

@ -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(_) => {}

View File

@ -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)?;

View File

@ -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(())

View File

@ -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(())

View File

@ -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)
}

View File

@ -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)
}
}
}

View File

@ -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)?;
}
}

View File

@ -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)?;

View File

@ -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

View File

@ -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

View File

@ -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(())

View File

@ -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)
}
}

View File

@ -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)? {

View File

@ -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,

View File

@ -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(()),
}
}

View File

@ -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,

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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 {

View File

@ -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(())

View File

@ -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)