[fine] Fix list variable binding

This commit is contained in:
John Doty 2024-02-08 06:34:02 -08:00
parent 09a85596d8
commit 13aaca36c8
3 changed files with 46 additions and 28 deletions

View file

@ -908,31 +908,19 @@ impl<'a> Semantics<'a> {
EnvironmentRef::new(environment)
}
fn environment_of_for(&self, parent: EnvironmentRef, _tree: &Tree) -> EnvironmentRef {
// let Some(id) = tree.nth_token(1) else {
// return parent;
// };
fn environment_of_for(&self, parent: EnvironmentRef, tree: &Tree) -> EnvironmentRef {
let Some(it) = tree.nth_tree(1) else {
return parent;
};
// let Some(enumerable) = tree.nth_tree(3) else {
// return parent;
// };
let iterator = &self.syntax_tree[it];
let Some(id) = iterator.nth_token(0) else {
return parent;
};
// let item_type = match self.type_of(enumerable) {
// Type::Error => Type::Error,
// Type::List(x) => (&*x).clone(),
// _ => {
// self.report_error_tree_ref(enumerable, "this expression is not enumerable");
// Type::Error
// }
// };
// TODO: This is broken, need a sub-tree to point the decl at that
// has the right type.
//
// let mut environment = Environment::new(Some(parent), Location::Local);
// environment.insert(id, item_type);
// EnvironmentRef::new(environment)
parent
let mut environment = Environment::new(Some(parent), Location::Local);
environment.insert(id, it);
EnvironmentRef::new(environment)
}
fn environment_of_is_expression(&self, parent: EnvironmentRef, tree: &Tree) -> EnvironmentRef {
@ -1277,6 +1265,7 @@ impl<'a> Semantics<'a> {
TreeKind::Identifier => self.type_of_identifier(t, tree),
TreeKind::IfStatement => self.type_of_if_statement(tree),
TreeKind::IsExpression => Some(Type::Bool),
TreeKind::IteratorVariable => self.type_of_iterator_variable(tree),
TreeKind::LetStatement => Some(Type::Nothing),
TreeKind::ListConstructor => self.type_of_list_constructor(t, tree),
TreeKind::ListConstructorElement => self.type_of_list_constructor_element(tree),
@ -1938,6 +1927,24 @@ impl<'a> Semantics<'a> {
}
}
fn type_of_iterator_variable(&self, tree: &Tree) -> Option<Type> {
assert_eq!(tree.kind, TreeKind::IteratorVariable);
let parent = &self.syntax_tree[tree.parent?];
assert_eq!(parent.kind, TreeKind::ForStatement);
let enumerable = parent.nth_tree(3)?;
let item_type = match self.type_of(enumerable) {
Type::Error => Type::Error,
Type::List(x) => (&*x).clone(),
_ => {
self.report_error_tree_ref(enumerable, "this expression is not enumerable");
Type::Error
}
};
Some(item_type)
}
fn type_of_list_constructor(&self, t: TreeRef, tree: &Tree) -> Option<Type> {
assert_eq!(tree.kind, TreeKind::ListConstructor);
let mut element_type = None;
@ -2346,7 +2353,9 @@ pub fn check(s: &Semantics) {
TreeKind::ListConstructorElement => {
let _ = s.type_of(t);
}
TreeKind::ForStatement => check_for_statement(s, t),
TreeKind::IteratorVariable => {}
TreeKind::ClassDecl => check_class_declaration(s, tree),
TreeKind::FieldDecl => {}