Reimplement type setting for type check system
This commit is contained in:
parent
5fada12165
commit
4a42f51580
@ -37,6 +37,13 @@ impl AbstractTree for Assignment {
|
|||||||
let statement_node = syntax_node.child(child_count - 1).unwrap();
|
let statement_node = syntax_node.child(child_count - 1).unwrap();
|
||||||
let statement = Statement::from_syntax(statement_node, source, context)?;
|
let statement = Statement::from_syntax(statement_node, source, context)?;
|
||||||
|
|
||||||
|
if let AssignmentOperator::Equal = operator {
|
||||||
|
context.set_type(
|
||||||
|
identifier.inner().clone(),
|
||||||
|
statement.expected_type(context)?,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(Assignment {
|
Ok(Assignment {
|
||||||
identifier,
|
identifier,
|
||||||
type_definition,
|
type_definition,
|
||||||
@ -87,7 +94,9 @@ impl AbstractTree for Assignment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.statement.check_type(source, context)?;
|
self.statement
|
||||||
|
.check_type(source, context)
|
||||||
|
.map_err(|error| error.at_source_position(source, self.syntax_position))?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -115,6 +115,10 @@ impl AbstractTree for FunctionNode {
|
|||||||
|
|
||||||
function_context.clone_complex_values_from(context)?;
|
function_context.clone_complex_values_from(context)?;
|
||||||
|
|
||||||
|
for (parameter, parameter_type) in parameters.iter().zip(parameter_types.iter()) {
|
||||||
|
function_context.set_type(parameter.inner().clone(), parameter_type.clone())?;
|
||||||
|
}
|
||||||
|
|
||||||
let body_node = node.child(child_count - 1).unwrap();
|
let body_node = node.child(child_count - 1).unwrap();
|
||||||
let body = Block::from_syntax(body_node, source, &function_context)?;
|
let body = Block::from_syntax(body_node, source, &function_context)?;
|
||||||
|
|
||||||
|
@ -41,6 +41,8 @@ impl Type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn check(&self, other: &Type) -> Result<()> {
|
pub fn check(&self, other: &Type) -> Result<()> {
|
||||||
|
log::info!("Checking type {self} against {other}.");
|
||||||
|
|
||||||
match (self, other) {
|
match (self, other) {
|
||||||
(Type::Any, _)
|
(Type::Any, _)
|
||||||
| (_, Type::Any)
|
| (_, Type::Any)
|
||||||
|
@ -80,6 +80,14 @@ impl Map {
|
|||||||
Ok(previous)
|
Ok(previous)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_type(&self, key: String, r#type: Type) -> Result<Option<(Value, Type)>> {
|
||||||
|
log::info!("Setting type {key} = {}", r#type);
|
||||||
|
|
||||||
|
let previous = self.variables.write()?.insert(key, (Value::none(), r#type));
|
||||||
|
|
||||||
|
Ok(previous)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn unset_all(&self) -> Result<()> {
|
pub fn unset_all(&self) -> Result<()> {
|
||||||
for (_key, (value, r#_type)) in self.variables.write()?.iter_mut() {
|
for (_key, (value, r#_type)) in self.variables.write()?.iter_mut() {
|
||||||
*value = Value::none();
|
*value = Value::none();
|
||||||
|
@ -12,6 +12,8 @@ fn simple_type_check() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn argument_count_check() {
|
fn argument_count_check() {
|
||||||
|
env_logger::builder().is_test(true).try_init().unwrap();
|
||||||
|
|
||||||
let source = "
|
let source = "
|
||||||
foo = (x <int>) <int> {
|
foo = (x <int>) <int> {
|
||||||
x
|
x
|
||||||
|
Loading…
Reference in New Issue
Block a user