1
0

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
} else {
return Err(RuntimeError::ValidationFailure(
ValidationError::InterpreterExpectedReturn(expression_position),
ValidationError::ExpectedExpression(expression_position),
));
};
let r#type = self.constructor.construct(&context)?;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -46,7 +46,7 @@ impl AbstractNode for Expression {
Expression::As(inner) => inner.node.define_types(_context),
Expression::BuiltInFunctionCall(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::ListIndex(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::FunctionCall(function_call) => function_call.node.expected_type(_context),
Expression::Identifier(identifier) => {
let get_type = _context.get_type(identifier)?;
let get_type = _context.get_type(&identifier.node)?;
if get_type.is_none() {
Err(ValidationError::VariableNotFound {

View File

@ -35,7 +35,7 @@ impl FunctionCall {
impl AbstractNode for FunctionCall {
fn define_types(&self, _context: &Context) -> Result<(), ValidationError> {
self.function.define_ypes(_context)?;
self.function.define_types(_context)?;
let mut previous = ();
@ -53,7 +53,13 @@ impl AbstractNode for FunctionCall {
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 {
type_parameters,
@ -88,12 +94,12 @@ impl AbstractNode for FunctionCall {
clear_variables: bool,
) -> Result<Option<Evaluation>, RuntimeError> {
let function_position = self.function.position();
let action = self.function.evaluate(context, clear_variables)?;
let value = if let Evaluation::Return(value) = action {
let evaluation = self.function.evaluate(context, clear_variables)?;
let value = if let Some(Evaluation::Return(value)) = evaluation {
value
} else {
return Err(RuntimeError::ValidationFailure(
ValidationError::InterpreterExpectedReturn(function_position),
ValidationError::ExpectedExpression(function_position),
));
};
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 {
let expression_position = expression.position();
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
} else {
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));
@ -143,13 +149,19 @@ impl AbstractNode for FunctionCall {
}
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 {
return_type,
type_parameters,
..
} = function_node_type
} = function_type
{
if let Type::Generic {
identifier: return_identifier,
@ -179,7 +191,14 @@ impl AbstractNode for FunctionCall {
.zip(type_parameters.into_iter())
{
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 {
identifier,
@ -193,7 +212,7 @@ impl AbstractNode for FunctionCall {
Ok(Some(*return_type))
} else {
Err(ValidationError::ExpectedFunction {
actual: function_node_type,
actual: function_type,
position: self.function.position(),
})
}

View File

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

View File

@ -5,7 +5,7 @@ use crate::{
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)]
pub struct ListIndex {
@ -22,8 +22,13 @@ impl ListIndex {
}
}
impl Validate for ListIndex {
fn validate(&self, context: &mut Context, _manage_memory: bool) -> Result<(), ValidationError> {
impl AbstractNode for ListIndex {
fn define_types(&self, context: &Context) -> Result<(), ValidationError> {
self.collection.define_types(context)?;
self.index.define_types(context)
}
fn validate(&self, context: &Context, _manage_memory: bool) -> Result<(), ValidationError> {
self.collection.validate(context, _manage_memory)?;
self.index.validate(context, _manage_memory)?;
@ -57,12 +62,10 @@ impl Validate for ListIndex {
}),
}
}
}
impl AbstractNode for ListIndex {
fn evaluate(
self,
context: &mut Context,
context: &Context,
_clear_variables: bool,
) -> Result<Option<Evaluation>, RuntimeError> {
let left_position = self.collection.position();
@ -71,7 +74,7 @@ impl AbstractNode for ListIndex {
value
} else {
return Err(RuntimeError::ValidationFailure(
ValidationError::InterpreterExpectedReturn(left_position),
ValidationError::ExpectedExpression(left_position),
));
};
let right_position = self.index.position();
@ -80,7 +83,7 @@ impl AbstractNode for ListIndex {
value
} else {
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)?;
if let (

View File

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

View File

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

View File

@ -6,7 +6,7 @@ use crate::{
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)]
pub struct MapIndex {
@ -23,20 +23,19 @@ impl MapIndex {
}
}
impl Validate for MapIndex {
fn validate(
&self,
_context: &mut Context,
_manage_memory: bool,
) -> Result<(), ValidationError> {
impl AbstractNode for MapIndex {
fn define_types(&self, _context: &Context) -> Result<(), ValidationError> {
self.collection.define_types(_context)?;
self.index.define_types(_context)
}
fn validate(&self, _context: &Context, _manage_memory: bool) -> Result<(), ValidationError> {
self.collection.validate(_context, _manage_memory)
}
}
impl AbstractNode for MapIndex {
fn evaluate(
self,
context: &mut Context,
context: &Context,
_manage_memory: bool,
) -> Result<Option<Evaluation>, RuntimeError> {
let collection_position = self.collection.position();
@ -45,7 +44,7 @@ impl AbstractNode for MapIndex {
value
} else {
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)) =
(&self.collection, &self.index)
{

View File

@ -7,7 +7,7 @@ use crate::{
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)]
pub enum Math {
@ -18,8 +18,33 @@ pub enum Math {
Modulo(Expression, Expression),
}
impl Validate for Math {
fn validate(&self, context: &mut Context, _manage_memory: bool) -> Result<(), ValidationError> {
impl AbstractNode for Math {
fn define_types(&self, _context: &Context) -> Result<(), ValidationError> {
match self {
Math::Add(left, right) => {
left.define_types(_context)?;
right.define_types(_context)
}
Math::Subtract(left, right) => {
left.define_types(_context)?;
right.define_types(_context)
}
Math::Multiply(left, right) => {
left.define_types(_context)?;
right.define_types(_context)
}
Math::Divide(left, right) => {
left.define_types(_context)?;
right.define_types(_context)
}
Math::Modulo(left, right) => {
left.define_types(_context)?;
right.define_types(_context)
}
}
}
fn validate(&self, context: &Context, _manage_memory: bool) -> Result<(), ValidationError> {
match self {
Math::Add(left, right) => {
let left_position = left.position();
@ -66,12 +91,10 @@ impl Validate for Math {
}
}
}
}
impl AbstractNode for Math {
fn evaluate(
self,
_context: &mut Context,
_context: &Context,
_clear_variables: bool,
) -> Result<Option<Evaluation>, RuntimeError> {
let run_and_expect_value =
@ -81,7 +104,7 @@ impl AbstractNode for Math {
value
} else {
return Err(RuntimeError::ValidationFailure(
ValidationError::InterpreterExpectedReturn(position),
ValidationError::ExpectedExpression(position),
));
};
@ -296,7 +319,7 @@ impl AbstractNode for Math {
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 {
Math::Add(left, right)
| Math::Subtract(left, right)

View File

@ -6,9 +6,8 @@ use crate::{
};
use super::{
AbstractNode, Assignment, AsyncBlock, Block, DefineTypes, EnumDeclaration, Evaluation,
Expression, IfElse, Loop, SourcePosition, StructureDefinition, Type, TypeAlias, Validate,
While, WithPosition,
AbstractNode, Assignment, AsyncBlock, Block, EnumDeclaration, Evaluation, Expression, IfElse,
Loop, SourcePosition, StructureDefinition, Type, TypeAlias, While, WithPosition,
};
#[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> {
match self {
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),
}
}
}
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(
self,
context: &mut Context,
context: &Context,
manage_memory: bool,
) -> Result<Option<Evaluation>, RuntimeError> {
let result = match self {
@ -105,7 +118,7 @@ impl AbstractNode for Statement {
result
}
fn expected_type(&self, _context: &mut Context) -> Result<Option<Type>, ValidationError> {
fn expected_type(&self, _context: &Context) -> Result<Option<Type>, ValidationError> {
match self {
Statement::Expression(expression) => expression.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 crate::{context::Context, error::RuntimeError, identifier::Identifier};
use crate::{
context::Context,
error::{RuntimeError, ValidationError},
identifier::Identifier,
};
use super::{AbstractNode, Evaluation, Type, TypeConstructor};
@ -17,9 +21,32 @@ impl 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(
self,
context: &mut Context,
context: &Context,
_manage_memory: bool,
) -> Result<Option<Evaluation>, RuntimeError> {
let mut fields = Vec::with_capacity(self.fields.len());
@ -40,10 +67,7 @@ impl AbstractNode for StructureDefinition {
Ok(None)
}
fn expected_type(
&self,
context: &mut Context,
) -> Result<Option<Type>, crate::error::ValidationError> {
fn expected_type(&self, context: &Context) -> Result<Option<Type>, ValidationError> {
Ok(None)
}
}

View File

@ -6,7 +6,7 @@ use crate::{
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)]
pub struct TypeAlias {
@ -24,20 +24,6 @@ impl 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> {
let r#type = self.constructor.construct(&context)?;
@ -45,4 +31,20 @@ impl DefineTypes for TypeAlias {
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::{
AbstractNode, Block, Evaluation, Expression, Type, TypeConstructor, Validate, WithPosition,
AbstractNode, Block, Evaluation, Expression, Type, TypeConstructor, WithPos, WithPosition,
};
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
@ -39,8 +39,46 @@ pub enum ValueNode {
},
}
impl Validate for ValueNode {
fn validate(&self, context: &mut Context, _manage_memory: bool) -> Result<(), ValidationError> {
impl AbstractNode for ValueNode {
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 {
type_name, variant, ..
} = self
@ -69,7 +107,11 @@ impl Validate for ValueNode {
expression.validate(context, _manage_memory)?;
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)?;
exprected_type.check(&actual_type).map_err(|conflict| {
@ -114,7 +156,11 @@ impl Validate for ValueNode {
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
.clone()
@ -147,7 +193,11 @@ impl Validate for ValueNode {
}) = context.get_type(&name.node)?
{
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| {
ValidationError::TypeCheck {
@ -162,12 +212,10 @@ impl Validate for ValueNode {
Ok(())
}
}
impl AbstractNode for ValueNode {
fn evaluate(
self,
context: &mut Context,
context: &Context,
_manage_memory: bool,
) -> Result<Option<Evaluation>, RuntimeError> {
let value = match self {
@ -184,11 +232,11 @@ impl AbstractNode for ValueNode {
let position = expression.position();
let evaluation = expression.evaluate(context, _manage_memory)?;
if let Evaluation::Return(value) = evaluation {
if let Some(Evaluation::Return(value)) = evaluation {
values.push(value);
} else {
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());
for expression in expression_list {
let expression_position = expression.position();
let position = expression.position();
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
} else {
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();
for (identifier, _type, expression) in property_list {
let expression_position = expression.position();
let action = expression.evaluate(context, _manage_memory)?;
let value = if let Evaluation::Return(value) = action {
let position = expression.position();
let evaluation = expression.evaluate(context, _manage_memory)?;
let value = if let Some(Evaluation::Return(value)) = evaluation {
value
} else {
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());
for (identifier, expression) in expressions {
let expression_position = expression.position();
let action = expression.evaluate(context, _manage_memory)?;
let value = if let Evaluation::Return(value) = action {
let position = expression.position();
let evaluation = expression.evaluate(context, _manage_memory)?;
let value = if let Some(Evaluation::Return(value)) = evaluation {
value
} else {
return Err(RuntimeError::ValidationFailure(
ValidationError::InterpreterExpectedReturn(expression_position),
ValidationError::ExpectedExpression(position),
));
};
@ -299,7 +347,7 @@ impl AbstractNode for ValueNode {
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 {
ValueNode::Boolean(_) => Type::Boolean,
ValueNode::EnumInstance { type_name, .. } => {
@ -314,11 +362,16 @@ impl AbstractNode for ValueNode {
}
ValueNode::Float(_) => Type::Float,
ValueNode::Integer(_) => Type::Integer,
ValueNode::List(items) => {
let item_type = items.first().unwrap().expected_type(context)?;
ValueNode::List(expressions) => {
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 {
length: items.len(),
length: expressions.len(),
item_type: Box::new(item_type),
}
}
@ -360,14 +413,15 @@ impl AbstractNode for ValueNode {
let mut types = Vec::with_capacity(expressions.len());
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((
identifier.clone(),
WithPosition {
node: r#type,
position: expression.position(),
},
r#type.with_position(expression.position()),
));
}

View File

@ -7,7 +7,7 @@ use crate::{
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)]
pub struct While {
@ -24,12 +24,18 @@ impl While {
}
}
impl Validate for While {
fn validate(
&self,
_context: &mut Context,
_manage_memory: bool,
) -> Result<(), ValidationError> {
impl AbstractNode for While {
fn define_types(&self, _context: &Context) -> Result<(), ValidationError> {
self.expression.define_types(_context)?;
for statement in &self.statements {
statement.define_types(_context)?;
}
Ok(())
}
fn validate(&self, _context: &Context, _manage_memory: bool) -> Result<(), ValidationError> {
self.expression.validate(_context, false)?;
for statement in &self.statements {
@ -38,12 +44,10 @@ impl Validate for While {
Ok(())
}
}
impl AbstractNode for While {
fn evaluate(
self,
_context: &mut Context,
_context: &Context,
_manage_memory: bool,
) -> Result<Option<Evaluation>, RuntimeError> {
let get_boolean = || -> Result<Value, RuntimeError> {
@ -57,7 +61,7 @@ impl AbstractNode for While {
Ok(value)
} else {
Err(RuntimeError::ValidationFailure(
ValidationError::InterpreterExpectedReturn(expression_position),
ValidationError::ExpectedExpression(expression_position),
))
}
};
@ -75,7 +79,7 @@ impl AbstractNode for While {
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)
}
}

View File

@ -119,7 +119,7 @@ impl<'a> Context<'a> {
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}.");
let mut variables = self.variables.write()?;
@ -136,7 +136,7 @@ impl<'a> Context<'a> {
Ok(())
}
pub fn clean(&mut self) -> Result<(), PoisonError> {
pub fn clean(&self) -> Result<(), PoisonError> {
if *self.is_clean.read()? {
return Ok(());
}

View File

@ -114,7 +114,6 @@ pub enum ValidationError {
index_type: Type,
index_position: SourcePosition,
},
CannotIndexWithVoid(SourcePosition),
ExpectedString {
actual: Type,
position: SourcePosition,
@ -137,7 +136,7 @@ pub enum ValidationError {
identifier: Identifier,
position: SourcePosition,
},
InterpreterExpectedReturn(SourcePosition),
ExpectedExpression(SourcePosition),
RwLockPoison(PoisonError),
TypeCheck {
/// 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),)),
])
}
ValidationError::InterpreterExpectedReturn(_) => todo!(),
ValidationError::ExpectedExpression(_) => todo!(),
ValidationError::ExpectedFunction { .. } => todo!(),
ValidationError::ExpectedValue(_) => todo!(),
ValidationError::PropertyNotFound { .. } => todo!(),
@ -455,6 +455,7 @@ impl InterpreterError {
}
}
ValidationError::EnumVariantNotFound { .. } => todo!(),
ValidationError::CannotIndexWithVoid(_) => todo!(),
}
}

View File

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