1
0

Fix list type checking

This commit is contained in:
Jeff 2023-12-09 18:50:17 -05:00
parent 0452243c08
commit aada1c72d6
2 changed files with 34 additions and 21 deletions

View File

@ -58,18 +58,6 @@ impl AbstractTree for Assignment {
let statement_node = node.child(child_count - 1).unwrap(); let statement_node = node.child(child_count - 1).unwrap();
let statement = Statement::from_syntax_node(source, statement_node, context)?; let statement = Statement::from_syntax_node(source, statement_node, context)?;
if let Some((_previous_value, previous_type)) = context.variables()?.get(identifier.inner())
{
let type_check = previous_type.check(&statement.expected_type(context)?);
if let Err(error) = type_check {
return Err(error.with_context(
statement_node.start_position(),
source[statement_node.byte_range()].to_string(),
));
}
}
if let Some(type_definition) = &type_definition { if let Some(type_definition) = &type_definition {
let statement_type = statement.expected_type(context)?; let statement_type = statement.expected_type(context)?;
@ -81,8 +69,6 @@ impl AbstractTree for Assignment {
let identifier_type = identifier.expected_type(context)?; let identifier_type = identifier.expected_type(context)?;
if let Type::List(item_type) = type_definition.inner() { if let Type::List(item_type) = type_definition.inner() {
println!("{item_type}");
item_type.check(&identifier_type)?; item_type.check(&identifier_type)?;
item_type.check(&statement_type)?; item_type.check(&statement_type)?;
} else { } else {
@ -92,6 +78,22 @@ impl AbstractTree for Assignment {
} }
AssignmentOperator::MinusEqual => todo!(), AssignmentOperator::MinusEqual => todo!(),
} }
} else if let Some((_previous_value, previous_type)) =
context.variables()?.get(identifier.inner())
{
let statement_type = statement.expected_type(context)?;
let type_check = if let Type::List(item_type) = previous_type {
item_type.check(&statement_type)
} else {
previous_type.check(&statement_type)
};
if let Err(error) = type_check {
return Err(error.with_context(
statement_node.start_position(),
source[statement_node.byte_range()].to_string(),
));
}
} }
Ok(Assignment { Ok(Assignment {
@ -126,7 +128,11 @@ impl AbstractTree for Assignment {
AssignmentOperator::Equal => value, AssignmentOperator::Equal => value,
}; };
context.set(key.clone(), new_value)?; if let Some(type_defintion) = &self.type_definition {
context.set(key.clone(), new_value, Some(type_defintion.inner().clone()))?;
} else {
context.set(key.clone(), new_value, None)?;
}
Ok(Value::Empty) Ok(Value::Empty)
} }
@ -175,11 +181,13 @@ mod tests {
x <[str]> = [] x <[str]> = []
x += 1 x += 1
", ",
); )
.unwrap_err();
if let Err(Error::TypeCheck { .. }) = test { match test {
} else { Error::WithContext { .. } => {}
panic!() Error::TypeCheck { .. } => {}
_ => panic!(),
} }
} }
} }

View File

@ -41,8 +41,13 @@ impl Map {
Ok(self.variables.read()?) Ok(self.variables.read()?)
} }
pub fn set(&self, key: String, value: Value) -> Result<Option<(Value, Type)>> { pub fn set(
let value_type = value.r#type(); &self,
key: String,
value: Value,
r#type: Option<Type>,
) -> Result<Option<(Value, Type)>> {
let value_type = r#type.unwrap_or(value.r#type());
let previous = self let previous = self
.variables .variables
.write()? .write()?