Clean up; Add error for assignment without a value

This commit is contained in:
Jeff 2024-06-17 18:00:42 -04:00
parent dd062e63f1
commit b0d80ab867
5 changed files with 22 additions and 5 deletions

View File

@ -7,7 +7,9 @@ use crate::{
Context, Value, Context, Value,
}; };
use super::{AbstractNode, Evaluation, ExpectedType, Statement, TypeConstructor, WithPosition}; use super::{
AbstractNode, Evaluation, ExpectedType, Statement, Type, TypeConstructor, WithPosition,
};
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct Assignment { pub struct Assignment {
@ -44,6 +46,12 @@ impl AbstractNode for Assignment {
fn validate(&self, context: &mut Context, manage_memory: bool) -> Result<(), ValidationError> { fn validate(&self, context: &mut Context, manage_memory: bool) -> Result<(), ValidationError> {
let statement_type = self.statement.expected_type(context)?; let statement_type = self.statement.expected_type(context)?;
if let Type::None = statement_type {
return Err(ValidationError::CannotAssignToNone(
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)?;

View File

@ -139,13 +139,13 @@ impl AbstractTree {
fn validate( fn validate(
self, self,
context: &mut Context, context: &mut Context,
add_variable_uses: bool, manage_memory: bool,
) -> Result<Vec<Statement>, Vec<Error>> { ) -> Result<Vec<Statement>, Vec<Error>> {
let mut errors = Vec::new(); let mut errors = Vec::new();
let mut valid_statements = Vec::new(); let mut valid_statements = Vec::new();
for statement in self.0 { for statement in self.0 {
let validation = statement.validate(context, add_variable_uses); let validation = statement.validate(context, manage_memory);
if let Err(validation_error) = validation { if let Err(validation_error) = validation {
errors.push(Error::Validation { errors.push(Error::Validation {

View File

@ -64,7 +64,7 @@ impl AbstractNode for ValueNode {
body, body,
} = self } = self
{ {
let mut function_context = Context::new(Some(&context)); let mut function_context = context.create_child();
if let Some(type_parameters) = type_parameters { if let Some(type_parameters) = type_parameters {
for identifier in type_parameters { for identifier in type_parameters {

View File

@ -103,6 +103,7 @@ impl PartialEq for RuntimeError {
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub enum ValidationError { pub enum ValidationError {
CannotAssignToNone(SourcePosition),
CannotIndex { CannotIndex {
r#type: Type, r#type: Type,
position: SourcePosition, position: SourcePosition,

View File

@ -150,7 +150,6 @@ impl<'a> Interpreter<'a> {
Ok(tokens) => tokens, Ok(tokens) => tokens,
Err(error) => return Some(error), Err(error) => return Some(error),
}; };
let parse_result = parser(true) let parse_result = parser(true)
.parse(tokens.spanned((tokens.len()..tokens.len()).into())) .parse(tokens.spanned((tokens.len()..tokens.len()).into()))
.into_result() .into_result()
@ -293,6 +292,15 @@ impl InterpreterError {
if let Some(validation_error) = validation_error { if let Some(validation_error) = validation_error {
match validation_error { match validation_error {
ValidationError::CannotAssignToNone(postion) => {
builder.add_label(
Label::new((self.source_id.clone(), postion.0..postion.1))
.with_message(format!(
"This statement does not yield a value, you cannot assign a variable to it."
)),
);
}
ValidationError::ExpectedBoolean { actual, position } => { ValidationError::ExpectedBoolean { actual, position } => {
builder.add_label( builder.add_label(
Label::new((self.source_id.clone(), position.0..position.1)) Label::new((self.source_id.clone(), position.0..position.1))