From 4bd3ac06fa26a6f08fb9eb22e489dc0e16bc804c Mon Sep 17 00:00:00 2001 From: John Doty Date: Sun, 7 Jan 2024 09:13:34 -0800 Subject: [PATCH] [fine] Use the right tree to get the environment for an identifier Can't go up to the parent, that defeats the whole point! Use *my* environment, not my parent's environment!! --- fine/src/semantics.rs | 22 ++++++++++--------- .../expression/errors/unknown_variable.fine | 4 ++++ 2 files changed, 16 insertions(+), 10 deletions(-) create mode 100644 fine/tests/expression/errors/unknown_variable.fine diff --git a/fine/src/semantics.rs b/fine/src/semantics.rs index 5df686ec..1791023f 100644 --- a/fine/src/semantics.rs +++ b/fine/src/semantics.rs @@ -351,8 +351,11 @@ impl<'a> Semantics<'a> { Incremental::None => (), Incremental::Complete(e) => return e.clone(), Incremental::InProgress => { - // eprintln!("environment_of circular => {t:?}"); + // NOTE: Set the state so the ICE doesn't loop on itself. + *state = Incremental::Complete(self.empty_environment.clone()); drop(borrow); + + //eprintln!("environment_of circular => {t:?}"); self.internal_compiler_error(Some(t), "circular environment dependency"); } } @@ -360,7 +363,7 @@ impl<'a> Semantics<'a> { } let tree = &self.syntax_tree[t]; - // eprintln!("environment_of => {tree:?}"); + //eprintln!(">>> environment_of => {tree:?}"); let parent = match self.logical_parents[t.index()] { Some(t) => self.environment_of(t), @@ -376,6 +379,7 @@ impl<'a> Semantics<'a> { }; self.environments.borrow_mut()[t.index()] = Incremental::Complete(result.clone()); + //eprintln!("<<< environment_of => {tree:?}"); result } @@ -475,7 +479,7 @@ impl<'a> Semantics<'a> { TreeKind::LetStatement => Some(Type::Nothing), TreeKind::ReturnStatement => Some(Type::Unreachable), TreeKind::ExpressionStatement => self.type_of_expression_statement(tree), - TreeKind::Identifier => self.type_of_identifier(tree), + TreeKind::Identifier => self.type_of_identifier(t, tree), _ => None, }; @@ -743,15 +747,13 @@ impl<'a> Semantics<'a> { }) } - fn type_of_identifier(&self, tree: &Tree) -> Option { + fn type_of_identifier(&self, t: TreeRef, tree: &Tree) -> Option { assert_eq!(tree.kind, TreeKind::Identifier); let id = tree.nth_token(0)?; - if let Some(parent) = tree.parent { - let environment = self.environment_of(parent); - if let Some(declaration) = environment.bind(id) { - return Some(declaration.declaration_type); - } + let environment = self.environment_of(t); + if let Some(declaration) = environment.bind(id) { + return Some(declaration.declaration_type); } self.report_error_tree(tree, format!("cannot find value {id} here")); @@ -801,7 +803,7 @@ impl<'a> Semantics<'a> { } fn internal_compiler_error(&self, tr: Option, message: &str) -> ! { - eprintln!("Internan compiler error: {message}!"); + eprintln!("Internal compiler error: {message}!"); self.dump_compiler_state(tr); panic!("INTERNAL COMPILER ERROR: {message}") } diff --git a/fine/tests/expression/errors/unknown_variable.fine b/fine/tests/expression/errors/unknown_variable.fine new file mode 100644 index 00000000..81d88198 --- /dev/null +++ b/fine/tests/expression/errors/unknown_variable.fine @@ -0,0 +1,4 @@ +let x = y; +x; + +// @type-error: 11 cannot find value y here