Clean up; Add error for assignment without a value
This commit is contained in:
parent
dd062e63f1
commit
b0d80ab867
@ -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)?;
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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,
|
||||||
|
@ -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))
|
||||||
|
Loading…
Reference in New Issue
Block a user