Continue refactoring

This commit is contained in:
Jeff 2024-06-21 23:37:25 -04:00
parent fb413e24b0
commit 88906fb6d7
23 changed files with 426 additions and 286 deletions

View File

@ -56,7 +56,7 @@ impl AbstractNode for As {
value value
} else { } else {
return Err(RuntimeError::ValidationFailure( return Err(RuntimeError::ValidationFailure(
ValidationError::InterpreterExpectedReturn(expression_position), ValidationError::ExpectedExpression(expression_position),
)); ));
}; };
let r#type = self.constructor.construct(&context)?; let r#type = self.constructor.construct(&context)?;

View File

@ -46,13 +46,13 @@ impl Assignment {
impl AbstractNode for Assignment { impl AbstractNode for Assignment {
fn define_types(&self, context: &Context) -> Result<(), ValidationError> { fn define_types(&self, context: &Context) -> Result<(), ValidationError> {
let relevant_statement = self.statement.last_evaluated_statement(); let relevant_statement = self.statement.last_evaluated_statement();
let statement_type = relevant_statement.expected_type(context)?; let statement_type = if let Some(r#type) = relevant_statement.expected_type(context)? {
r#type
if let Type::Void = &statement_type { } else {
return Err(ValidationError::CannotAssignToNone( return Err(ValidationError::CannotAssignToNone(
self.statement.position(), self.statement.position(),
)); ));
} };
if let Some(constructor) = &self.constructor { if let Some(constructor) = &self.constructor {
let r#type = constructor.clone().construct(&context)?; let r#type = constructor.clone().construct(&context)?;
@ -83,13 +83,13 @@ impl AbstractNode for Assignment {
} }
let relevant_statement = self.statement.last_evaluated_statement(); let relevant_statement = self.statement.last_evaluated_statement();
let statement_type = relevant_statement.expected_type(context)?; let statement_type = if let Some(r#type) = relevant_statement.expected_type(context)? {
r#type
if let Type::Void = &statement_type { } else {
return Err(ValidationError::CannotAssignToNone( return Err(ValidationError::CannotAssignToNone(
self.statement.position(), self.statement.position(),
)); ));
} };
if let Some(constructor) = &self.constructor { if let Some(constructor) = &self.constructor {
let r#type = constructor.clone().construct(&context)?; let r#type = constructor.clone().construct(&context)?;
@ -138,11 +138,11 @@ impl AbstractNode for Assignment {
let declared_type = constructor.clone().construct(context)?; let declared_type = constructor.clone().construct(context)?;
let function_type = function_call.node.function().expected_type(context)?; let function_type = function_call.node.function().expected_type(context)?;
if let Type::Function { if let Some(Type::Function {
return_type, return_type,
type_parameters: Some(type_parameters), type_parameters: Some(type_parameters),
.. ..
} = function_type }) = function_type
{ {
if let Type::Generic { identifier, .. } = *return_type { if let Type::Generic { identifier, .. } = *return_type {
let returned_parameter = type_parameters let returned_parameter = type_parameters
@ -157,7 +157,7 @@ impl AbstractNode for Assignment {
} }
} else { } else {
return Err(ValidationError::ExpectedFunction { return Err(ValidationError::ExpectedFunction {
actual: function_type, actual: function_type.unwrap(),
position: function_call.position, position: function_call.position,
}); });
} }
@ -171,7 +171,7 @@ impl AbstractNode for Assignment {
context: &Context, context: &Context,
manage_memory: bool, manage_memory: bool,
) -> Result<Option<Evaluation>, RuntimeError> { ) -> Result<Option<Evaluation>, RuntimeError> {
let evaluation = self.statement.run(context, manage_memory)?; let evaluation = self.statement.evaluate(context, manage_memory)?;
let right = match evaluation { let right = match evaluation {
Some(Evaluation::Return(value)) => value, Some(Evaluation::Return(value)) => value,
evaluation => return Ok(evaluation), evaluation => return Ok(evaluation),
@ -273,10 +273,10 @@ impl AbstractNode for Assignment {
} }
} }
Ok(Some(Evaluation::Void)) Ok(None)
} }
fn expected_type(&self, context: &Context) -> Result<Option<Type>, ValidationError> { fn expected_type(&self, _: &Context) -> Result<Option<Type>, ValidationError> {
Ok(None) Ok(None)
} }
} }

View File

@ -38,11 +38,7 @@ impl AbstractNode for AsyncBlock {
Ok(()) Ok(())
} }
fn evaluate( fn evaluate(self, _context: &Context, _: bool) -> Result<Option<Evaluation>, RuntimeError> {
self,
_context: &Context,
_manage_memory: bool,
) -> Result<Option<Evaluation>, RuntimeError> {
let statement_count = self.statements.len(); let statement_count = self.statements.len();
let final_result = Mutex::new(Ok(None)); let final_result = Mutex::new(Ok(None));
@ -51,7 +47,7 @@ impl AbstractNode for AsyncBlock {
.enumerate() .enumerate()
.find_map_any( .find_map_any(
|(index, statement)| -> Option<Result<Option<Evaluation>, RuntimeError>> { |(index, statement)| -> Option<Result<Option<Evaluation>, RuntimeError>> {
let result = statement.run(&mut _context.clone(), false); let result = statement.evaluate(&_context, false);
if result.is_err() { if result.is_err() {
return Some(result); return Some(result);

View File

@ -51,7 +51,7 @@ impl AbstractNode for Block {
let mut previous = None; let mut previous = None;
for statement in self.statements { for statement in self.statements {
previous = statement.run(_context, _manage_memory)?; previous = statement.evaluate(_context, _manage_memory)?;
} }
Ok(previous) Ok(previous)
@ -86,7 +86,7 @@ mod tests {
]); ]);
assert_eq!( assert_eq!(
block.run(&mut Context::new(None), true).unwrap(), block.evaluate(&Context::new(None), true).unwrap(),
Some(Evaluation::Return(Value::integer(42))) Some(Evaluation::Return(Value::integer(42)))
) )
} }
@ -103,8 +103,8 @@ mod tests {
]); ]);
assert_eq!( assert_eq!(
block.expected_type(&mut Context::new(None)), block.expected_type(&Context::new(None)),
Ok(Type::Integer) Ok(Some(Type::Integer))
) )
} }
} }

View File

@ -26,8 +26,15 @@ pub enum BuiltInFunctionCall {
WriteLine(Expression), WriteLine(Expression),
} }
impl AbstractNode for BuiltInFunctionCall { impl AbstractNode for BuiltInFunctionCall {
fn define_types(&self, context: &Context) -> Result<(), ValidationError> { fn define_types(&self, _context: &Context) -> Result<(), ValidationError> {
Ok(()) match self {
BuiltInFunctionCall::JsonParse(_, expression) => expression.define_types(_context),
BuiltInFunctionCall::Length(expression) => expression.define_types(_context),
BuiltInFunctionCall::ReadFile(expression) => expression.define_types(_context),
BuiltInFunctionCall::ReadLine => Ok(()),
BuiltInFunctionCall::Sleep(expression) => expression.define_types(_context),
BuiltInFunctionCall::WriteLine(expression) => expression.define_types(_context),
}
} }
fn validate(&self, _context: &Context, _manage_memory: bool) -> Result<(), ValidationError> { fn validate(&self, _context: &Context, _manage_memory: bool) -> Result<(), ValidationError> {
@ -54,56 +61,53 @@ impl AbstractNode for BuiltInFunctionCall {
context: &Context, context: &Context,
_manage_memory: bool, _manage_memory: bool,
) -> Result<Option<Evaluation>, RuntimeError> { ) -> Result<Option<Evaluation>, RuntimeError> {
fn evaluate_expression(
expression: Expression,
context: &Context,
_manage_memory: bool,
) -> Result<Value, RuntimeError> {
let position = expression.position();
let evaluation = expression.evaluate(context, _manage_memory)?;
if let Some(Evaluation::Return(value)) = evaluation {
Ok(value)
} else {
Err(RuntimeError::ValidationFailure(
ValidationError::ExpectedExpression(position),
))
}
}
match self { match self {
BuiltInFunctionCall::JsonParse(_type, expression) => { BuiltInFunctionCall::JsonParse(_type, expression) => {
let action = expression.clone().evaluate(context, _manage_memory)?; let position = expression.position();
let value = if let Evaluation::Return(value) = action { let value = evaluate_expression(expression, context, _manage_memory)?;
value
} else {
return Err(RuntimeError::ValidationFailure(
ValidationError::InterpreterExpectedReturn(expression.position()),
));
};
if let ValueInner::String(string) = value.inner().as_ref() { if let ValueInner::String(string) = value.inner().as_ref() {
let deserialized = serde_json::from_str(string)?; let deserialized = serde_json::from_str(&string)?;
Ok(Some(Evaluation::Return(deserialized))) Ok(Some(Evaluation::Return(deserialized)))
} else { } else {
Err(RuntimeError::ValidationFailure( Err(RuntimeError::ValidationFailure(
ValidationError::ExpectedString { ValidationError::ExpectedString {
actual: value.r#type(context)?, actual: value.r#type(context)?,
position: expression.position(), position,
}, },
)) ))
} }
} }
BuiltInFunctionCall::Length(expression) => { BuiltInFunctionCall::Length(expression) => {
let action = expression.clone().evaluate(context, _manage_memory)?; let value = evaluate_expression(expression, context, _manage_memory)?;
let value = if let Evaluation::Return(value) = action {
value
} else {
return Err(RuntimeError::ValidationFailure(
ValidationError::InterpreterExpectedReturn(expression.position()),
));
};
let length = if let ValueInner::List(list) = value.inner().as_ref() { let length = if let ValueInner::List(list) = value.inner().as_ref() {
list.len() as i64 list.len() as i64
} else { } else {
0 todo!("Create an error for this occurence.")
}; };
Ok(Some(Evaluation::Return(Value::integer(length)))) Ok(Some(Evaluation::Return(Value::integer(length))))
} }
BuiltInFunctionCall::ReadFile(expression) => { BuiltInFunctionCall::ReadFile(expression) => {
let action = expression.clone().evaluate(context, _manage_memory)?; let value = evaluate_expression(expression, context, _manage_memory)?;
let value = if let Evaluation::Return(value) = action {
value
} else {
return Err(RuntimeError::ValidationFailure(
ValidationError::InterpreterExpectedReturn(expression.position()),
));
};
let file_contents = if let ValueInner::String(path) = value.inner().as_ref() { let file_contents = if let ValueInner::String(path) = value.inner().as_ref() {
read_to_string(path)? read_to_string(path)?
} else { } else {
@ -122,30 +126,16 @@ impl AbstractNode for BuiltInFunctionCall {
)))) ))))
} }
BuiltInFunctionCall::Sleep(expression) => { BuiltInFunctionCall::Sleep(expression) => {
let action = expression.clone().evaluate(context, _manage_memory)?; let value = evaluate_expression(expression, context, _manage_memory)?;
let value = if let Evaluation::Return(value) = action {
value
} else {
return Err(RuntimeError::ValidationFailure(
ValidationError::InterpreterExpectedReturn(expression.position()),
));
};
if let ValueInner::Integer(milliseconds) = value.inner().as_ref() { if let ValueInner::Integer(milliseconds) = value.inner().as_ref() {
thread::sleep(Duration::from_millis(*milliseconds as u64)); thread::sleep(Duration::from_millis(*milliseconds as u64));
} }
Ok(Evaluation::Void) Ok(None)
} }
BuiltInFunctionCall::WriteLine(expression) => { BuiltInFunctionCall::WriteLine(expression) => {
let action = expression.clone().evaluate(context, _manage_memory)?; let value = evaluate_expression(expression, context, _manage_memory)?;
let value = if let Evaluation::Return(value) = action {
value
} else {
return Err(RuntimeError::ValidationFailure(
ValidationError::InterpreterExpectedReturn(expression.position()),
));
};
if let ValueInner::String(output) = value.inner().as_ref() { if let ValueInner::String(output) = value.inner().as_ref() {
let mut stdout = stdout(); let mut stdout = stdout();
@ -155,7 +145,7 @@ impl AbstractNode for BuiltInFunctionCall {
stdout.flush()?; stdout.flush()?;
} }
Ok(Evaluation::Void) Ok(None)
} }
} }
} }

View File

@ -63,7 +63,7 @@ impl AbstractNode for EnumDeclaration {
None None
}; };
type_variants.push((name.node, types)); type_variants.push((name.node.clone(), types));
} }
let r#type = Type::Enum { let r#type = Type::Enum {
@ -72,31 +72,20 @@ impl AbstractNode for EnumDeclaration {
variants: type_variants, variants: type_variants,
}; };
context.set_type(name.node, r#type)?; context.set_type(name.node.clone(), r#type)?;
Ok(()) Ok(())
} }
fn validate( fn validate(&self, _: &Context, _: bool) -> Result<(), ValidationError> {
&self,
context: &Context,
manage_memory: bool,
) -> Result<(), crate::error::ValidationError> {
Ok(()) Ok(())
} }
fn evaluate( fn evaluate(self, _: &Context, _: bool) -> Result<Option<Evaluation>, RuntimeError> {
self,
context: &Context,
_manage_memory: bool,
) -> Result<Option<Evaluation>, RuntimeError> {
Ok(None) Ok(None)
} }
fn expected_type( fn expected_type(&self, _: &Context) -> Result<Option<Type>, ValidationError> {
&self,
context: &Context,
) -> Result<Option<Type>, crate::error::ValidationError> {
Ok(None) Ok(None)
} }
} }

View File

@ -46,7 +46,7 @@ impl AbstractNode for Expression {
Expression::As(inner) => inner.node.define_types(_context), Expression::As(inner) => inner.node.define_types(_context),
Expression::BuiltInFunctionCall(inner) => inner.node.define_types(_context), Expression::BuiltInFunctionCall(inner) => inner.node.define_types(_context),
Expression::FunctionCall(inner) => inner.node.define_types(_context), Expression::FunctionCall(inner) => inner.node.define_types(_context),
Expression::Identifier(inner) => inner.node.define_types(_context), Expression::Identifier(_) => Ok(()),
Expression::MapIndex(inner) => inner.node.define_types(_context), Expression::MapIndex(inner) => inner.node.define_types(_context),
Expression::ListIndex(inner) => inner.node.define_types(_context), Expression::ListIndex(inner) => inner.node.define_types(_context),
Expression::Logic(inner) => inner.node.define_types(_context), Expression::Logic(inner) => inner.node.define_types(_context),
@ -132,7 +132,7 @@ impl AbstractNode for Expression {
Expression::As(r#as) => r#as.node.expected_type(_context), Expression::As(r#as) => r#as.node.expected_type(_context),
Expression::FunctionCall(function_call) => function_call.node.expected_type(_context), Expression::FunctionCall(function_call) => function_call.node.expected_type(_context),
Expression::Identifier(identifier) => { Expression::Identifier(identifier) => {
let get_type = _context.get_type(identifier)?; let get_type = _context.get_type(&identifier.node)?;
if get_type.is_none() { if get_type.is_none() {
Err(ValidationError::VariableNotFound { Err(ValidationError::VariableNotFound {

View File

@ -35,7 +35,7 @@ impl FunctionCall {
impl AbstractNode for FunctionCall { impl AbstractNode for FunctionCall {
fn define_types(&self, _context: &Context) -> Result<(), ValidationError> { fn define_types(&self, _context: &Context) -> Result<(), ValidationError> {
self.function.define_ypes(_context)?; self.function.define_types(_context)?;
let mut previous = (); let mut previous = ();
@ -53,7 +53,13 @@ impl AbstractNode for FunctionCall {
expression.validate(context, manage_memory)?; expression.validate(context, manage_memory)?;
} }
let function_node_type = self.function.expected_type(context)?; let function_node_type = if let Some(r#type) = self.function.expected_type(context)? {
r#type
} else {
return Err(ValidationError::ExpectedExpression(
self.function.position(),
));
};
if let Type::Function { if let Type::Function {
type_parameters, type_parameters,
@ -88,12 +94,12 @@ impl AbstractNode for FunctionCall {
clear_variables: bool, clear_variables: bool,
) -> Result<Option<Evaluation>, RuntimeError> { ) -> Result<Option<Evaluation>, RuntimeError> {
let function_position = self.function.position(); let function_position = self.function.position();
let action = self.function.evaluate(context, clear_variables)?; let evaluation = self.function.evaluate(context, clear_variables)?;
let value = if let Evaluation::Return(value) = action { let value = if let Some(Evaluation::Return(value)) = evaluation {
value value
} else { } else {
return Err(RuntimeError::ValidationFailure( return Err(RuntimeError::ValidationFailure(
ValidationError::InterpreterExpectedReturn(function_position), ValidationError::ExpectedExpression(function_position),
)); ));
}; };
let function = if let ValueInner::Function(function) = value.inner().as_ref() { let function = if let ValueInner::Function(function) = value.inner().as_ref() {
@ -111,15 +117,15 @@ impl AbstractNode for FunctionCall {
for expression in self.value_arguments { for expression in self.value_arguments {
let expression_position = expression.position(); let expression_position = expression.position();
let action = expression.evaluate(context, clear_variables)?; let action = expression.evaluate(context, clear_variables)?;
let value = if let Evaluation::Return(value) = action { let evalution = if let Some(Evaluation::Return(value)) = action {
value value
} else { } else {
return Err(RuntimeError::ValidationFailure( return Err(RuntimeError::ValidationFailure(
ValidationError::InterpreterExpectedReturn(expression_position), ValidationError::ExpectedExpression(expression_position),
)); ));
}; };
arguments.push(value); arguments.push(evalution);
} }
let mut function_context = Context::new(Some(&context)); let mut function_context = Context::new(Some(&context));
@ -143,13 +149,19 @@ impl AbstractNode for FunctionCall {
} }
fn expected_type(&self, context: &Context) -> Result<Option<Type>, ValidationError> { fn expected_type(&self, context: &Context) -> Result<Option<Type>, ValidationError> {
let function_node_type = self.function.expected_type(context)?; let function_type = if let Some(r#type) = self.function.expected_type(context)? {
r#type
} else {
return Err(ValidationError::ExpectedExpression(
self.function.position(),
));
};
if let Type::Function { if let Type::Function {
return_type, return_type,
type_parameters, type_parameters,
.. ..
} = function_node_type } = function_type
{ {
if let Type::Generic { if let Type::Generic {
identifier: return_identifier, identifier: return_identifier,
@ -179,7 +191,14 @@ impl AbstractNode for FunctionCall {
.zip(type_parameters.into_iter()) .zip(type_parameters.into_iter())
{ {
if identifier == return_identifier { if identifier == return_identifier {
let concrete_type = expression.expected_type(context)?; let concrete_type =
if let Some(r#type) = expression.expected_type(context)? {
r#type
} else {
return Err(ValidationError::ExpectedExpression(
expression.position(),
));
};
return Ok(Some(Type::Generic { return Ok(Some(Type::Generic {
identifier, identifier,
@ -193,7 +212,7 @@ impl AbstractNode for FunctionCall {
Ok(Some(*return_type)) Ok(Some(*return_type))
} else { } else {
Err(ValidationError::ExpectedFunction { Err(ValidationError::ExpectedFunction {
actual: function_node_type, actual: function_type,
position: self.function.position(), position: self.function.position(),
}) })
} }

View File

@ -35,16 +35,16 @@ impl IfElse {
impl AbstractNode for IfElse { impl AbstractNode for IfElse {
fn define_types(&self, _context: &Context) -> Result<(), ValidationError> { fn define_types(&self, _context: &Context) -> Result<(), ValidationError> {
self.if_expression.define_types(_context)?; self.if_expression.define_types(_context)?;
self.if_block.define_type(_context)?; self.if_block.node.define_types(_context)?;
if let Some(else_ifs) = self.else_ifs { if let Some(else_ifs) = &self.else_ifs {
for (expression, block) in else_ifs { for (expression, block) in else_ifs {
expression.define_types(_context)?; expression.define_types(_context)?;
block.node.define_types(_context)?; block.node.define_types(_context)?;
} }
} }
if let Some(else_block) = self.else_block { if let Some(else_block) = &self.else_block {
else_block.node.define_types(_context)?; else_block.node.define_types(_context)?;
} }
@ -55,22 +55,36 @@ impl AbstractNode for IfElse {
self.if_expression.validate(context, manage_memory)?; self.if_expression.validate(context, manage_memory)?;
self.if_block.node.validate(context, manage_memory)?; self.if_block.node.validate(context, manage_memory)?;
let expected_type = self.if_block.node.expected_type(context)?; let if_expression_type = if let Some(r#type) = self.if_expression.expected_type(context)? {
let if_expression_type = self.if_expression.expected_type(context)?; r#type
} else {
return Err(ValidationError::ExpectedExpression(
self.if_expression.position(),
));
};
let expected_type = if let Some(r#type) = self.if_block.node.expected_type(context)? {
r#type
} else {
return Err(ValidationError::ExpectedExpression(self.if_block.position));
};
if let Type::Boolean = if_expression_type { if let Type::Boolean = if_expression_type {
if let Some(else_block) = &self.else_block { if let Some(else_block) = &self.else_block {
else_block.node.validate(context, manage_memory)?; else_block.node.validate(context, manage_memory)?;
let actual = else_block.node.expected_type(context)?; let actual_type = if let Some(r#type) = else_block.node.expected_type(context)? {
r#type
} else {
return Err(ValidationError::ExpectedExpression(else_block.position));
};
expected_type expected_type.check(&actual_type).map_err(|conflict| {
.check(&actual) ValidationError::TypeCheck {
.map_err(|conflict| ValidationError::TypeCheck {
conflict, conflict,
actual_position: else_block.node.last_statement().position(), actual_position: else_block.node.last_statement().position(),
expected_position: Some(self.if_block.node.first_statement().position()), expected_position: Some(self.if_block.node.first_statement().position()),
})?; }
})?;
} }
} else { } else {
return Err(ValidationError::ExpectedBoolean { return Err(ValidationError::ExpectedBoolean {
@ -83,12 +97,16 @@ impl AbstractNode for IfElse {
for (expression, block) in else_ifs { for (expression, block) in else_ifs {
let expression_type = expression.expected_type(context)?; let expression_type = expression.expected_type(context)?;
if let Type::Boolean = expression_type { if let Some(Type::Boolean) = expression_type {
block.node.validate(context, manage_memory)?; block.node.validate(context, manage_memory)?;
let actual = block.node.expected_type(context)?; let actual_type = if let Some(r#type) = block.node.expected_type(context)? {
r#type
} else {
return Err(ValidationError::ExpectedExpression(block.position));
};
expected_type.check(&actual).map_err(|conflict| { expected_type.check(&actual_type).map_err(|conflict| {
ValidationError::TypeCheck { ValidationError::TypeCheck {
conflict, conflict,
actual_position: self.if_block.node.last_statement().position(), actual_position: self.if_block.node.last_statement().position(),
@ -113,35 +131,35 @@ impl AbstractNode for IfElse {
_manage_memory: bool, _manage_memory: bool,
) -> Result<Option<Evaluation>, RuntimeError> { ) -> Result<Option<Evaluation>, RuntimeError> {
let if_position = self.if_expression.position(); let if_position = self.if_expression.position();
let action = self.if_expression.evaluate(context, _manage_memory)?; let evaluation = self.if_expression.evaluate(context, _manage_memory)?;
let value = if let Evaluation::Return(value) = action { let value = if let Some(Evaluation::Return(value)) = evaluation {
value value
} else { } else {
return Err(RuntimeError::ValidationFailure( return Err(RuntimeError::ValidationFailure(
ValidationError::InterpreterExpectedReturn(if_position), ValidationError::ExpectedExpression(if_position),
)); ));
}; };
if let ValueInner::Boolean(if_boolean) = value.inner().as_ref() { if let ValueInner::Boolean(if_boolean) = value.inner().as_ref() {
if *if_boolean { if *if_boolean {
return self.if_block.node.run(context, _manage_memory); return self.if_block.node.evaluate(context, _manage_memory);
} }
if let Some(else_ifs) = self.else_ifs { if let Some(else_ifs) = self.else_ifs {
for (expression, block) in else_ifs { for (expression, block) in else_ifs {
let expression_position = expression.position(); let expression_position = expression.position();
let action = expression.evaluate(context, _manage_memory)?; let evaluation = expression.evaluate(context, _manage_memory)?;
let value = if let Evaluation::Return(value) = action { let value = if let Some(Evaluation::Return(value)) = evaluation {
value value
} else { } else {
return Err(RuntimeError::ValidationFailure( return Err(RuntimeError::ValidationFailure(
ValidationError::InterpreterExpectedReturn(expression_position), ValidationError::ExpectedExpression(expression_position),
)); ));
}; };
if let ValueInner::Boolean(else_if_boolean) = value.inner().as_ref() { if let ValueInner::Boolean(else_if_boolean) = value.inner().as_ref() {
if *else_if_boolean { if *else_if_boolean {
return block.node.run(context, _manage_memory); return block.node.evaluate(context, _manage_memory);
} }
} else { } else {
return Err(RuntimeError::ValidationFailure( return Err(RuntimeError::ValidationFailure(
@ -155,7 +173,7 @@ impl AbstractNode for IfElse {
} }
if let Some(else_statement) = self.else_block { if let Some(else_statement) = self.else_block {
else_statement.node.run(context, _manage_memory) else_statement.node.evaluate(context, _manage_memory)
} else { } else {
Ok(None) Ok(None)
} }
@ -195,7 +213,7 @@ mod tests {
Some(Vec::with_capacity(0)), Some(Vec::with_capacity(0)),
None None
) )
.run(&mut Context::new(None), true) .evaluate(&Context::new(None), true)
.unwrap(), .unwrap(),
Some(Evaluation::Return(Value::string("foo".to_string()))) Some(Evaluation::Return(Value::string("foo".to_string())))
) )

View File

@ -5,7 +5,7 @@ use crate::{
error::{RuntimeError, ValidationError}, error::{RuntimeError, ValidationError},
}; };
use super::{AbstractNode, Evaluation, Expression, Type, Validate, ValueNode, WithPosition}; use super::{AbstractNode, Evaluation, Expression, Type, ValueNode, WithPosition};
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct ListIndex { pub struct ListIndex {
@ -22,8 +22,13 @@ impl ListIndex {
} }
} }
impl Validate for ListIndex { impl AbstractNode for ListIndex {
fn validate(&self, context: &mut Context, _manage_memory: bool) -> Result<(), ValidationError> { 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.collection.validate(context, _manage_memory)?;
self.index.validate(context, _manage_memory)?; self.index.validate(context, _manage_memory)?;
@ -57,12 +62,10 @@ impl Validate for ListIndex {
}), }),
} }
} }
}
impl AbstractNode for ListIndex {
fn evaluate( fn evaluate(
self, self,
context: &mut Context, context: &Context,
_clear_variables: bool, _clear_variables: bool,
) -> Result<Option<Evaluation>, RuntimeError> { ) -> Result<Option<Evaluation>, RuntimeError> {
let left_position = self.collection.position(); let left_position = self.collection.position();
@ -71,7 +74,7 @@ impl AbstractNode for ListIndex {
value value
} else { } else {
return Err(RuntimeError::ValidationFailure( return Err(RuntimeError::ValidationFailure(
ValidationError::InterpreterExpectedReturn(left_position), ValidationError::ExpectedExpression(left_position),
)); ));
}; };
let right_position = self.index.position(); let right_position = self.index.position();
@ -80,7 +83,7 @@ impl AbstractNode for ListIndex {
value value
} else { } else {
return Err(RuntimeError::ValidationFailure( return Err(RuntimeError::ValidationFailure(
ValidationError::InterpreterExpectedReturn(right_position), ValidationError::ExpectedExpression(right_position),
)); ));
}; };
@ -104,7 +107,7 @@ impl AbstractNode for ListIndex {
} }
} }
fn expected_type(&self, _context: &mut Context) -> Result<Option<Type>, ValidationError> { fn expected_type(&self, _context: &Context) -> Result<Option<Type>, ValidationError> {
let left_type = self.collection.expected_type(_context)?; let left_type = self.collection.expected_type(_context)?;
if let ( if let (

View File

@ -7,7 +7,7 @@ use crate::{
Value, Value,
}; };
use super::{AbstractNode, Evaluation, Expression, Type, Validate}; use super::{AbstractNode, Evaluation, Expression, Type};
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub enum Logic { pub enum Logic {
@ -22,8 +22,46 @@ pub enum Logic {
Not(Expression), Not(Expression),
} }
impl Validate for Logic { impl AbstractNode for Logic {
fn validate(&self, context: &mut Context, _manage_memory: bool) -> Result<(), ValidationError> { 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> {
match self { match self {
Logic::Equal(left, right) Logic::Equal(left, right)
| Logic::NotEqual(left, right) | Logic::NotEqual(left, right)
@ -88,12 +126,10 @@ impl Validate for Logic {
} }
} }
} }
}
impl AbstractNode for Logic {
fn evaluate( fn evaluate(
self, self,
context: &mut Context, context: &Context,
_manage_memory: bool, _manage_memory: bool,
) -> Result<Option<Evaluation>, RuntimeError> { ) -> Result<Option<Evaluation>, RuntimeError> {
let run_and_expect_value = |expression: Expression| -> Result<Value, RuntimeError> { let run_and_expect_value = |expression: Expression| -> Result<Value, RuntimeError> {
@ -103,7 +139,7 @@ impl AbstractNode for Logic {
value value
} else { } else {
return Err(RuntimeError::ValidationFailure( return Err(RuntimeError::ValidationFailure(
ValidationError::InterpreterExpectedReturn(expression_position), ValidationError::ExpectedExpression(expression_position),
)); ));
}; };
@ -117,7 +153,7 @@ impl AbstractNode for Logic {
value value
} else { } else {
return Err(RuntimeError::ValidationFailure( return Err(RuntimeError::ValidationFailure(
ValidationError::InterpreterExpectedReturn(expression_position), ValidationError::ExpectedExpression(expression_position),
)); ));
}; };
@ -196,7 +232,7 @@ impl AbstractNode for Logic {
Ok(Some(Evaluation::Return(Value::boolean(boolean)))) Ok(Some(Evaluation::Return(Value::boolean(boolean))))
} }
fn expected_type(&self, _context: &mut Context) -> Result<Option<Type>, ValidationError> { fn expected_type(&self, _context: &Context) -> Result<Option<Type>, ValidationError> {
Ok(Some(Type::Boolean)) Ok(Some(Type::Boolean))
} }
} }

View File

@ -5,7 +5,7 @@ use crate::{
error::{RuntimeError, ValidationError}, error::{RuntimeError, ValidationError},
}; };
use super::{AbstractNode, Evaluation, Statement, Validate}; use super::{AbstractNode, Evaluation, Statement, Type};
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct Loop { pub struct Loop {
@ -21,25 +21,26 @@ impl Loop {
self.statements.last().unwrap() self.statements.last().unwrap()
} }
} }
impl AbstractNode for Loop {
fn define_types(&self, _context: &Context) -> Result<(), ValidationError> {
for statement in &self.statements {
statement.define_types(_context)?;
}
impl Validate for Loop { Ok(())
fn validate( }
&self,
_context: &mut Context, fn validate(&self, _context: &Context, _manage_memory: bool) -> Result<(), ValidationError> {
_manage_memory: bool,
) -> Result<(), ValidationError> {
for statement in &self.statements { for statement in &self.statements {
statement.validate(_context, false)?; statement.validate(_context, false)?;
} }
Ok(()) Ok(())
} }
}
impl AbstractNode for Loop {
fn evaluate( fn evaluate(
self, self,
_context: &mut Context, _context: &Context,
_manage_memory: bool, _manage_memory: bool,
) -> Result<Option<Evaluation>, RuntimeError> { ) -> Result<Option<Evaluation>, RuntimeError> {
loop { loop {
@ -53,10 +54,7 @@ impl AbstractNode for Loop {
} }
} }
fn expected_type( fn expected_type(&self, _context: &Context) -> Result<Option<Type>, ValidationError> {
&self,
_context: &mut Context,
) -> Result<Option<super::Type>, ValidationError> {
self.last_statement().expected_type(_context) self.last_statement().expected_type(_context)
} }
} }

View File

@ -6,7 +6,7 @@ use crate::{
value::ValueInner, value::ValueInner,
}; };
use super::{AbstractNode, Evaluation, Expression, Type, Validate, ValueNode, WithPosition}; use super::{AbstractNode, Evaluation, Expression, Type, ValueNode, WithPosition};
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct MapIndex { pub struct MapIndex {
@ -23,20 +23,19 @@ impl MapIndex {
} }
} }
impl Validate for MapIndex { impl AbstractNode for MapIndex {
fn validate( fn define_types(&self, _context: &Context) -> Result<(), ValidationError> {
&self, self.collection.define_types(_context)?;
_context: &mut Context, self.index.define_types(_context)
_manage_memory: bool, }
) -> Result<(), ValidationError> {
fn validate(&self, _context: &Context, _manage_memory: bool) -> Result<(), ValidationError> {
self.collection.validate(_context, _manage_memory) self.collection.validate(_context, _manage_memory)
} }
}
impl AbstractNode for MapIndex {
fn evaluate( fn evaluate(
self, self,
context: &mut Context, context: &Context,
_manage_memory: bool, _manage_memory: bool,
) -> Result<Option<Evaluation>, RuntimeError> { ) -> Result<Option<Evaluation>, RuntimeError> {
let collection_position = self.collection.position(); let collection_position = self.collection.position();
@ -45,7 +44,7 @@ impl AbstractNode for MapIndex {
value value
} else { } else {
return Err(RuntimeError::ValidationFailure( return Err(RuntimeError::ValidationFailure(
ValidationError::InterpreterExpectedReturn(collection_position), ValidationError::ExpectedExpression(collection_position),
)); ));
}; };
@ -67,7 +66,7 @@ impl AbstractNode for MapIndex {
} }
} }
fn expected_type(&self, context: &mut Context) -> Result<Option<Type>, ValidationError> { fn expected_type(&self, context: &Context) -> Result<Option<Type>, ValidationError> {
if let (Expression::Identifier(collection), Expression::Identifier(index)) = if let (Expression::Identifier(collection), Expression::Identifier(index)) =
(&self.collection, &self.index) (&self.collection, &self.index)
{ {

View File

@ -7,7 +7,7 @@ use crate::{
Value, Value,
}; };
use super::{AbstractNode, Evaluation, Expression, SourcePosition, Type, Validate}; use super::{AbstractNode, Evaluation, Expression, SourcePosition, Type};
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub enum Math { pub enum Math {
@ -18,8 +18,33 @@ pub enum Math {
Modulo(Expression, Expression), Modulo(Expression, Expression),
} }
impl Validate for Math { impl AbstractNode for Math {
fn validate(&self, context: &mut Context, _manage_memory: bool) -> Result<(), ValidationError> { 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> {
match self { match self {
Math::Add(left, right) => { Math::Add(left, right) => {
let left_position = left.position(); let left_position = left.position();
@ -66,12 +91,10 @@ impl Validate for Math {
} }
} }
} }
}
impl AbstractNode for Math {
fn evaluate( fn evaluate(
self, self,
_context: &mut Context, _context: &Context,
_clear_variables: bool, _clear_variables: bool,
) -> Result<Option<Evaluation>, RuntimeError> { ) -> Result<Option<Evaluation>, RuntimeError> {
let run_and_expect_value = let run_and_expect_value =
@ -81,7 +104,7 @@ impl AbstractNode for Math {
value value
} else { } else {
return Err(RuntimeError::ValidationFailure( return Err(RuntimeError::ValidationFailure(
ValidationError::InterpreterExpectedReturn(position), ValidationError::ExpectedExpression(position),
)); ));
}; };
@ -296,7 +319,7 @@ impl AbstractNode for Math {
Ok(Some(Evaluation::Return(value))) Ok(Some(Evaluation::Return(value)))
} }
fn expected_type(&self, _context: &mut Context) -> Result<Option<Type>, ValidationError> { fn expected_type(&self, _context: &Context) -> Result<Option<Type>, ValidationError> {
match self { match self {
Math::Add(left, right) Math::Add(left, right)
| Math::Subtract(left, right) | Math::Subtract(left, right)

View File

@ -6,9 +6,8 @@ use crate::{
}; };
use super::{ use super::{
AbstractNode, Assignment, AsyncBlock, Block, DefineTypes, EnumDeclaration, Evaluation, AbstractNode, Assignment, AsyncBlock, Block, EnumDeclaration, Evaluation, Expression, IfElse,
Expression, IfElse, Loop, SourcePosition, StructureDefinition, Type, TypeAlias, Validate, Loop, SourcePosition, StructureDefinition, Type, TypeAlias, While, WithPosition,
While, WithPosition,
}; };
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
@ -52,7 +51,7 @@ impl Statement {
} }
} }
impl DefineTypes for Statement { impl AbstractNode for Statement {
fn define_types(&self, _context: &Context) -> Result<(), ValidationError> { fn define_types(&self, _context: &Context) -> Result<(), ValidationError> {
match self { match self {
Statement::Expression(expression) => expression.define_types(_context), Statement::Expression(expression) => expression.define_types(_context),
@ -72,12 +71,26 @@ impl DefineTypes for Statement {
Statement::While(r#while) => r#while.node.define_types(_context), Statement::While(r#while) => r#while.node.define_types(_context),
} }
} }
}
impl AbstractNode for Statement { fn validate(&self, _context: &Context, _manage_memory: bool) -> Result<(), ValidationError> {
match self {
Statement::Assignment(assignment) => assignment.node.validate(_context, _manage_memory),
Statement::AsyncBlock(async_block) => {
async_block.node.validate(_context, _manage_memory)
}
Statement::Block(block) => block.node.validate(_context, _manage_memory),
Statement::Break(_) => Ok(()),
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),
_ => Ok(()),
}
}
fn evaluate( fn evaluate(
self, self,
context: &mut Context, context: &Context,
manage_memory: bool, manage_memory: bool,
) -> Result<Option<Evaluation>, RuntimeError> { ) -> Result<Option<Evaluation>, RuntimeError> {
let result = match self { let result = match self {
@ -105,7 +118,7 @@ impl AbstractNode for Statement {
result result
} }
fn expected_type(&self, _context: &mut Context) -> Result<Option<Type>, ValidationError> { fn expected_type(&self, _context: &Context) -> Result<Option<Type>, ValidationError> {
match self { match self {
Statement::Expression(expression) => expression.expected_type(_context), Statement::Expression(expression) => expression.expected_type(_context),
Statement::IfElse(if_else) => if_else.node.expected_type(_context), Statement::IfElse(if_else) => if_else.node.expected_type(_context),
@ -125,25 +138,3 @@ impl AbstractNode for Statement {
} }
} }
} }
impl Validate for Statement {
fn validate(
&self,
_context: &mut Context,
_manage_memory: bool,
) -> Result<(), ValidationError> {
match self {
Statement::Assignment(assignment) => assignment.node.validate(_context, _manage_memory),
Statement::AsyncBlock(async_block) => {
async_block.node.validate(_context, _manage_memory)
}
Statement::Block(block) => block.node.validate(_context, _manage_memory),
Statement::Break(_) => Ok(()),
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),
_ => Ok(()),
}
}
}

View File

@ -1,6 +1,10 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{context::Context, error::RuntimeError, identifier::Identifier}; use crate::{
context::Context,
error::{RuntimeError, ValidationError},
identifier::Identifier,
};
use super::{AbstractNode, Evaluation, Type, TypeConstructor}; use super::{AbstractNode, Evaluation, Type, TypeConstructor};
@ -17,9 +21,32 @@ impl StructureDefinition {
} }
impl AbstractNode for StructureDefinition { impl AbstractNode for StructureDefinition {
fn define_types(&self, context: &Context) -> Result<(), ValidationError> {
let mut fields = Vec::with_capacity(self.fields.len());
for (identifier, constructor) in self.fields {
let r#type = constructor.construct(&context)?;
fields.push((identifier, r#type));
}
let struct_type = Type::Structure {
name: self.name.clone(),
fields,
};
context.set_type(self.name, struct_type)?;
Ok(None)
}
fn validate(&self, context: &Context, manage_memory: bool) -> Result<(), ValidationError> {
Ok(())
}
fn evaluate( fn evaluate(
self, self,
context: &mut Context, context: &Context,
_manage_memory: bool, _manage_memory: bool,
) -> Result<Option<Evaluation>, RuntimeError> { ) -> Result<Option<Evaluation>, RuntimeError> {
let mut fields = Vec::with_capacity(self.fields.len()); let mut fields = Vec::with_capacity(self.fields.len());
@ -40,10 +67,7 @@ impl AbstractNode for StructureDefinition {
Ok(None) Ok(None)
} }
fn expected_type( fn expected_type(&self, context: &Context) -> Result<Option<Type>, ValidationError> {
&self,
context: &mut Context,
) -> Result<Option<Type>, crate::error::ValidationError> {
Ok(None) Ok(None)
} }
} }

View File

@ -6,7 +6,7 @@ use crate::{
identifier::Identifier, identifier::Identifier,
}; };
use super::{AbstractNode, DefineTypes, Evaluation, Type, TypeConstructor, WithPosition}; use super::{AbstractNode, Evaluation, Type, TypeConstructor, WithPosition};
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct TypeAlias { pub struct TypeAlias {
@ -24,20 +24,6 @@ impl TypeAlias {
} }
impl AbstractNode for TypeAlias { impl AbstractNode for TypeAlias {
fn evaluate(
self,
context: &mut Context,
manage_memory: bool,
) -> Result<Option<Evaluation>, RuntimeError> {
Ok(None)
}
fn expected_type(&self, context: &mut Context) -> Result<Option<Type>, ValidationError> {
Ok(None)
}
}
impl DefineTypes for TypeAlias {
fn define_types(&self, context: &Context) -> Result<(), ValidationError> { fn define_types(&self, context: &Context) -> Result<(), ValidationError> {
let r#type = self.constructor.construct(&context)?; let r#type = self.constructor.construct(&context)?;
@ -45,4 +31,20 @@ impl DefineTypes for TypeAlias {
Ok(()) Ok(())
} }
fn validate(&self, context: &Context, manage_memory: bool) -> Result<(), ValidationError> {
Ok(())
}
fn evaluate(
self,
context: &Context,
manage_memory: bool,
) -> Result<Option<Evaluation>, RuntimeError> {
Ok(None)
}
fn expected_type(&self, context: &Context) -> Result<Option<Type>, ValidationError> {
Ok(None)
}
} }

View File

@ -10,7 +10,7 @@ use crate::{
}; };
use super::{ use super::{
AbstractNode, Block, Evaluation, Expression, Type, TypeConstructor, Validate, WithPosition, AbstractNode, Block, Evaluation, Expression, Type, TypeConstructor, WithPos, WithPosition,
}; };
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
@ -39,8 +39,46 @@ pub enum ValueNode {
}, },
} }
impl Validate for ValueNode { impl AbstractNode for ValueNode {
fn validate(&self, context: &mut Context, _manage_memory: bool) -> Result<(), ValidationError> { fn define_types(&self, _context: &Context) -> Result<(), ValidationError> {
match self {
ValueNode::EnumInstance { content, .. } => {
if let Some(expressions) = content {
for expression in expressions {
expression.define_types(_context)?;
}
}
}
ValueNode::List(expressions) => {
for expression in expressions {
expression.define_types(_context)?;
}
}
ValueNode::Map(fields) => {
for (_, _, expression) in fields {
expression.define_types(_context)?;
}
}
ValueNode::Structure { fields, .. } => {
for (_, expression) in fields {
expression.define_types(_context)?;
}
}
ValueNode::Function {
type_parameters,
value_parameters,
return_type,
body,
} => {
body.node.define_types(_context)?;
}
_ => {}
}
Ok(())
}
fn validate(&self, context: &Context, _manage_memory: bool) -> Result<(), ValidationError> {
if let ValueNode::EnumInstance { if let ValueNode::EnumInstance {
type_name, variant, .. type_name, variant, ..
} = self } = self
@ -69,7 +107,11 @@ impl Validate for ValueNode {
expression.validate(context, _manage_memory)?; expression.validate(context, _manage_memory)?;
if let Some(constructor) = constructor_option { if let Some(constructor) = constructor_option {
let actual_type = expression.expected_type(context)?; let actual_type = if let Some(r#type) = expression.expected_type(context)? {
r#type
} else {
return Err(ValidationError::ExpectedExpression(expression.position()));
};
let exprected_type = constructor.clone().construct(&context)?; let exprected_type = constructor.clone().construct(&context)?;
exprected_type.check(&actual_type).map_err(|conflict| { exprected_type.check(&actual_type).map_err(|conflict| {
@ -114,7 +156,11 @@ impl Validate for ValueNode {
body.node.validate(&mut function_context, _manage_memory)?; body.node.validate(&mut function_context, _manage_memory)?;
let actual_return_type = body.node.expected_type(&mut function_context)?; let actual_return_type = if let Some(r#type) = body.node.expected_type(context)? {
r#type
} else {
return Err(ValidationError::ExpectedExpression(body.position));
};
return_type return_type
.clone() .clone()
@ -147,7 +193,11 @@ impl Validate 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()) {
let actual_type = expression.expected_type(context)?; let actual_type = if let Some(r#type) = expression.expected_type(context)? {
r#type
} else {
return Err(ValidationError::ExpectedExpression(expression.position()));
};
expected_type.check(&actual_type).map_err(|conflict| { expected_type.check(&actual_type).map_err(|conflict| {
ValidationError::TypeCheck { ValidationError::TypeCheck {
@ -162,12 +212,10 @@ impl Validate for ValueNode {
Ok(()) Ok(())
} }
}
impl AbstractNode for ValueNode {
fn evaluate( fn evaluate(
self, self,
context: &mut Context, context: &Context,
_manage_memory: bool, _manage_memory: bool,
) -> Result<Option<Evaluation>, RuntimeError> { ) -> Result<Option<Evaluation>, RuntimeError> {
let value = match self { let value = match self {
@ -184,11 +232,11 @@ impl AbstractNode for ValueNode {
let position = expression.position(); let position = expression.position();
let evaluation = expression.evaluate(context, _manage_memory)?; let evaluation = expression.evaluate(context, _manage_memory)?;
if let Evaluation::Return(value) = evaluation { if let Some(Evaluation::Return(value)) = evaluation {
values.push(value); values.push(value);
} else { } else {
return Err(RuntimeError::ValidationFailure( return Err(RuntimeError::ValidationFailure(
ValidationError::InterpreterExpectedReturn(position), ValidationError::ExpectedExpression(position),
)); ));
} }
} }
@ -205,13 +253,13 @@ impl AbstractNode for ValueNode {
let mut value_list = Vec::with_capacity(expression_list.len()); let mut value_list = Vec::with_capacity(expression_list.len());
for expression in expression_list { for expression in expression_list {
let expression_position = expression.position(); let position = expression.position();
let evaluation = expression.evaluate(context, _manage_memory)?; let evaluation = expression.evaluate(context, _manage_memory)?;
let value = if let Evaluation::Return(value) = evaluation { let value = if let Some(Evaluation::Return(value)) = evaluation {
value value
} else { } else {
return Err(RuntimeError::ValidationFailure( return Err(RuntimeError::ValidationFailure(
ValidationError::InterpreterExpectedReturn(expression_position), ValidationError::ExpectedExpression(position),
)); ));
}; };
@ -224,13 +272,13 @@ impl AbstractNode for ValueNode {
let mut property_map = BTreeMap::new(); let mut property_map = BTreeMap::new();
for (identifier, _type, expression) in property_list { for (identifier, _type, expression) in property_list {
let expression_position = expression.position(); let position = expression.position();
let action = expression.evaluate(context, _manage_memory)?; let evaluation = expression.evaluate(context, _manage_memory)?;
let value = if let Evaluation::Return(value) = action { let value = if let Some(Evaluation::Return(value)) = evaluation {
value value
} else { } else {
return Err(RuntimeError::ValidationFailure( return Err(RuntimeError::ValidationFailure(
ValidationError::InterpreterExpectedReturn(expression_position), ValidationError::ExpectedExpression(position),
)); ));
}; };
@ -279,13 +327,13 @@ impl AbstractNode for ValueNode {
let mut fields = Vec::with_capacity(expressions.len()); let mut fields = Vec::with_capacity(expressions.len());
for (identifier, expression) in expressions { for (identifier, expression) in expressions {
let expression_position = expression.position(); let position = expression.position();
let action = expression.evaluate(context, _manage_memory)?; let evaluation = expression.evaluate(context, _manage_memory)?;
let value = if let Evaluation::Return(value) = action { let value = if let Some(Evaluation::Return(value)) = evaluation {
value value
} else { } else {
return Err(RuntimeError::ValidationFailure( return Err(RuntimeError::ValidationFailure(
ValidationError::InterpreterExpectedReturn(expression_position), ValidationError::ExpectedExpression(position),
)); ));
}; };
@ -299,7 +347,7 @@ impl AbstractNode for ValueNode {
Ok(Some(Evaluation::Return(value))) Ok(Some(Evaluation::Return(value)))
} }
fn expected_type(&self, context: &mut Context) -> Result<Option<Type>, ValidationError> { fn expected_type(&self, context: &Context) -> Result<Option<Type>, ValidationError> {
let r#type = match self { let r#type = match self {
ValueNode::Boolean(_) => Type::Boolean, ValueNode::Boolean(_) => Type::Boolean,
ValueNode::EnumInstance { type_name, .. } => { ValueNode::EnumInstance { type_name, .. } => {
@ -314,11 +362,16 @@ impl AbstractNode for ValueNode {
} }
ValueNode::Float(_) => Type::Float, ValueNode::Float(_) => Type::Float,
ValueNode::Integer(_) => Type::Integer, ValueNode::Integer(_) => Type::Integer,
ValueNode::List(items) => { ValueNode::List(expressions) => {
let item_type = items.first().unwrap().expected_type(context)?; let first_item = expressions.first().unwrap();
let item_type = if let Some(r#type) = first_item.expected_type(context)? {
r#type
} else {
return Err(ValidationError::ExpectedExpression(first_item.position()));
};
Type::List { Type::List {
length: items.len(), length: expressions.len(),
item_type: Box::new(item_type), item_type: Box::new(item_type),
} }
} }
@ -360,14 +413,15 @@ impl AbstractNode for ValueNode {
let mut types = Vec::with_capacity(expressions.len()); let mut types = Vec::with_capacity(expressions.len());
for (identifier, expression) in expressions { for (identifier, expression) in expressions {
let r#type = expression.expected_type(context)?; let r#type = if let Some(r#type) = expression.expected_type(context)? {
r#type
} else {
return Err(ValidationError::ExpectedExpression(expression.position()));
};
types.push(( types.push((
identifier.clone(), identifier.clone(),
WithPosition { r#type.with_position(expression.position()),
node: r#type,
position: expression.position(),
},
)); ));
} }

View File

@ -7,7 +7,7 @@ use crate::{
Value, Value,
}; };
use super::{AbstractNode, Evaluation, Expression, Statement, Type, Validate}; use super::{AbstractNode, Evaluation, Expression, Statement, Type};
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct While { pub struct While {
@ -24,12 +24,18 @@ impl While {
} }
} }
impl Validate for While { impl AbstractNode for While {
fn validate( fn define_types(&self, _context: &Context) -> Result<(), ValidationError> {
&self, self.expression.define_types(_context)?;
_context: &mut Context,
_manage_memory: bool, for statement in &self.statements {
) -> Result<(), ValidationError> { statement.define_types(_context)?;
}
Ok(())
}
fn validate(&self, _context: &Context, _manage_memory: bool) -> Result<(), ValidationError> {
self.expression.validate(_context, false)?; self.expression.validate(_context, false)?;
for statement in &self.statements { for statement in &self.statements {
@ -38,12 +44,10 @@ impl Validate for While {
Ok(()) Ok(())
} }
}
impl AbstractNode for While {
fn evaluate( fn evaluate(
self, self,
_context: &mut Context, _context: &Context,
_manage_memory: bool, _manage_memory: bool,
) -> Result<Option<Evaluation>, RuntimeError> { ) -> Result<Option<Evaluation>, RuntimeError> {
let get_boolean = || -> Result<Value, RuntimeError> { let get_boolean = || -> Result<Value, RuntimeError> {
@ -57,7 +61,7 @@ impl AbstractNode for While {
Ok(value) Ok(value)
} else { } else {
Err(RuntimeError::ValidationFailure( Err(RuntimeError::ValidationFailure(
ValidationError::InterpreterExpectedReturn(expression_position), ValidationError::ExpectedExpression(expression_position),
)) ))
} }
}; };
@ -75,7 +79,7 @@ impl AbstractNode for While {
Ok(None) Ok(None)
} }
fn expected_type(&self, _context: &mut Context) -> Result<Option<Type>, ValidationError> { fn expected_type(&self, _context: &Context) -> Result<Option<Type>, ValidationError> {
self.statements.last().unwrap().expected_type(_context) self.statements.last().unwrap().expected_type(_context)
} }
} }

View File

@ -119,7 +119,7 @@ impl<'a> Context<'a> {
Ok(()) Ok(())
} }
pub fn set_value(&mut self, identifier: Identifier, value: Value) -> Result<(), PoisonError> { pub fn set_value(&self, identifier: Identifier, value: Value) -> Result<(), PoisonError> {
log::debug!("Setting {identifier} to value {value}."); log::debug!("Setting {identifier} to value {value}.");
let mut variables = self.variables.write()?; let mut variables = self.variables.write()?;
@ -136,7 +136,7 @@ impl<'a> Context<'a> {
Ok(()) Ok(())
} }
pub fn clean(&mut self) -> Result<(), PoisonError> { pub fn clean(&self) -> Result<(), PoisonError> {
if *self.is_clean.read()? { if *self.is_clean.read()? {
return Ok(()); return Ok(());
} }

View File

@ -114,7 +114,6 @@ pub enum ValidationError {
index_type: Type, index_type: Type,
index_position: SourcePosition, index_position: SourcePosition,
}, },
CannotIndexWithVoid(SourcePosition),
ExpectedString { ExpectedString {
actual: Type, actual: Type,
position: SourcePosition, position: SourcePosition,
@ -137,7 +136,7 @@ pub enum ValidationError {
identifier: Identifier, identifier: Identifier,
position: SourcePosition, position: SourcePosition,
}, },
InterpreterExpectedReturn(SourcePosition), ExpectedExpression(SourcePosition),
RwLockPoison(PoisonError), RwLockPoison(PoisonError),
TypeCheck { TypeCheck {
/// The mismatch that caused the error. /// The mismatch that caused the error.

View File

@ -416,7 +416,7 @@ impl InterpreterError {
.with_message(format!("This has type {}.", index_type.fg(type_color),)), .with_message(format!("This has type {}.", index_type.fg(type_color),)),
]) ])
} }
ValidationError::InterpreterExpectedReturn(_) => todo!(), ValidationError::ExpectedExpression(_) => todo!(),
ValidationError::ExpectedFunction { .. } => todo!(), ValidationError::ExpectedFunction { .. } => todo!(),
ValidationError::ExpectedValue(_) => todo!(), ValidationError::ExpectedValue(_) => todo!(),
ValidationError::PropertyNotFound { .. } => todo!(), ValidationError::PropertyNotFound { .. } => todo!(),
@ -455,6 +455,7 @@ impl InterpreterError {
} }
} }
ValidationError::EnumVariantNotFound { .. } => todo!(), ValidationError::EnumVariantNotFound { .. } => todo!(),
ValidationError::CannotIndexWithVoid(_) => todo!(),
} }
} }

View File

@ -14,7 +14,7 @@ use serde::{
}; };
use crate::{ use crate::{
abstract_tree::{Block, Evaluation, Type, WithPosition}, abstract_tree::{AbstractNode, Block, Evaluation, Type, WithPosition},
context::Context, context::Context,
error::{RuntimeError, ValidationError}, error::{RuntimeError, ValidationError},
identifier::Identifier, identifier::Identifier,
@ -725,8 +725,8 @@ impl Function {
self, self,
value_arguments: Vec<Value>, value_arguments: Vec<Value>,
context: &mut Context, context: &mut Context,
clear_variables: bool, manage_memory: bool,
) -> Result<Evaluation, RuntimeError> { ) -> Result<Option<Evaluation>, RuntimeError> {
for ((identifier, _), value) in self for ((identifier, _), value) in self
.value_parameters .value_parameters
.into_iter() .into_iter()
@ -735,12 +735,6 @@ impl Function {
context.set_value(identifier.clone(), value)?; context.set_value(identifier.clone(), value)?;
} }
self.body.run(context, clear_variables).map(|eval_option| { self.body.evaluate(context, manage_memory)
if let Some(evaluation) = eval_option {
evaluation
} else {
Evaluation::Void
}
})
} }
} }