Fix assignment type check bug
This commit is contained in:
parent
e6acb8cbb9
commit
d8850b2d3c
@ -42,13 +42,13 @@ impl AbstractTree for Assignment {
|
|||||||
let variable_key = identifier.inner().clone();
|
let variable_key = identifier.inner().clone();
|
||||||
let variable_type = if let Some(definition) = &type_definition {
|
let variable_type = if let Some(definition) = &type_definition {
|
||||||
definition.inner().clone()
|
definition.inner().clone()
|
||||||
} else if let Some((_, r#type)) = context.variables()?.get(identifier.inner()) {
|
|
||||||
r#type.clone()
|
|
||||||
} else {
|
} else {
|
||||||
statement_type
|
statement_type
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if let AssignmentOperator::Equal = operator {
|
||||||
context.set(variable_key, Value::none(), Some(variable_type))?;
|
context.set(variable_key, Value::none(), Some(variable_type))?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(Assignment {
|
Ok(Assignment {
|
||||||
identifier,
|
identifier,
|
||||||
@ -60,19 +60,29 @@ impl AbstractTree for Assignment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn check_type(&self, source: &str, context: &Map) -> Result<()> {
|
fn check_type(&self, source: &str, context: &Map) -> Result<()> {
|
||||||
let statement_type = self.statement.expected_type(context)?;
|
let variables = context.variables()?;
|
||||||
|
let established_type = variables
|
||||||
|
.get(self.identifier.inner())
|
||||||
|
.map(|(_value, _type)| _type);
|
||||||
|
let actual_type = self.statement.expected_type(context)?;
|
||||||
|
|
||||||
if let Some(type_definition) = &self.type_definition {
|
if let Some(type_definition) = &self.type_definition {
|
||||||
match self.operator {
|
match self.operator {
|
||||||
AssignmentOperator::Equal => {
|
AssignmentOperator::Equal => {
|
||||||
|
if let Some(r#type) = established_type {
|
||||||
|
r#type.check(&actual_type).map_err(|error| {
|
||||||
|
error.at_source_position(source, self.syntax_position)
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
|
||||||
type_definition
|
type_definition
|
||||||
.inner()
|
.inner()
|
||||||
.check(&statement_type)
|
.check(&actual_type)
|
||||||
.map_err(|error| error.at_source_position(source, self.syntax_position))?;
|
.map_err(|error| error.at_source_position(source, self.syntax_position))?;
|
||||||
}
|
}
|
||||||
AssignmentOperator::PlusEqual => {
|
AssignmentOperator::PlusEqual => {
|
||||||
if let Type::List(item_type) = type_definition.inner() {
|
if let Type::List(item_type) = type_definition.inner() {
|
||||||
item_type.check(&statement_type)?;
|
item_type.check(&actual_type)?;
|
||||||
} else {
|
} else {
|
||||||
type_definition
|
type_definition
|
||||||
.inner()
|
.inner()
|
||||||
@ -86,10 +96,14 @@ impl AbstractTree for Assignment {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
match self.operator {
|
match self.operator {
|
||||||
AssignmentOperator::Equal => {}
|
AssignmentOperator::Equal => {
|
||||||
|
if let Some(r#type) = established_type {
|
||||||
|
r#type.check(&actual_type)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
AssignmentOperator::PlusEqual => {
|
AssignmentOperator::PlusEqual => {
|
||||||
if let Type::List(item_type) = self.identifier.expected_type(context)? {
|
if let Type::List(item_type) = self.identifier.expected_type(context)? {
|
||||||
item_type.check(&statement_type).map_err(|error| {
|
item_type.check(&actual_type).map_err(|error| {
|
||||||
error.at_source_position(source, self.syntax_position)
|
error.at_source_position(source, self.syntax_position)
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
|
@ -190,20 +190,12 @@ impl AbstractTree for ValueNode {
|
|||||||
|
|
||||||
fn check_type(&self, _source: &str, _context: &Map) -> Result<()> {
|
fn check_type(&self, _source: &str, _context: &Map) -> Result<()> {
|
||||||
match self {
|
match self {
|
||||||
ValueNode::Boolean(_) => todo!(),
|
|
||||||
ValueNode::Float(_) => todo!(),
|
|
||||||
ValueNode::Function(function) => {
|
ValueNode::Function(function) => {
|
||||||
if let Function::ContextDefined(function_node) = function {
|
if let Function::ContextDefined(function_node) = function {
|
||||||
function_node.check_type(_source, _context)?;
|
function_node.check_type(_source, _context)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ValueNode::Integer(_) => todo!(),
|
_ => {}
|
||||||
ValueNode::String(_) => todo!(),
|
|
||||||
ValueNode::List(_) => todo!(),
|
|
||||||
ValueNode::Option(_) => todo!(),
|
|
||||||
ValueNode::Map(_) => todo!(),
|
|
||||||
ValueNode::BuiltInValue(_) => todo!(),
|
|
||||||
ValueNode::Structure(_) => todo!(),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
Loading…
Reference in New Issue
Block a user