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