diff --git a/fine/src/parser.rs b/fine/src/parser.rs index a0f519f7..6fd7b36b 100644 --- a/fine/src/parser.rs +++ b/fine/src/parser.rs @@ -138,7 +138,7 @@ pub enum TreeKind { pub struct Tree<'a> { pub kind: TreeKind, - pub parent: Option, // TODO: Do we actually need this? + pub parent: Option, pub start_pos: usize, pub end_pos: usize, pub children: Vec>, diff --git a/fine/src/semantics.rs b/fine/src/semantics.rs index 53dc1346..7d087afd 100644 --- a/fine/src/semantics.rs +++ b/fine/src/semantics.rs @@ -1,8 +1,8 @@ use crate::{ parser::{Child, SyntaxTree, Tree, TreeKind, TreeRef}, - tokens::{Lines, Token, TokenKind}, + tokens::{Lines, TokenKind}, }; -use std::{cell::RefCell, collections::HashMap, fmt, rc::Rc}; +use std::{cell::RefCell, collections::HashMap, fmt}; // TODO: An error should have: // @@ -121,126 +121,22 @@ impl fmt::Display for Type { } } -pub struct Declaration { - declaration_type: Type, -} - -pub struct Environment { - parent: Option, - declarations: HashMap, Declaration>, -} - -impl Environment { - pub fn new(parent: Option) -> Self { - Environment { - parent, - declarations: HashMap::new(), - } - } - - pub fn bind(&self, token: &Token) -> Option<&Declaration> { - if let Some(decl) = self.declarations.get(token.as_str()) { - return Some(decl); - } - - let mut current = &self.parent; - while let Some(env) = current { - if let Some(decl) = env.declarations.get(token.as_str()) { - return Some(decl); - } - current = &env.parent; - } - - None - } -} - -#[derive(Clone)] -pub struct EnvironmentRef(Rc); - -impl EnvironmentRef { - pub fn new(environment: Environment) -> Self { - EnvironmentRef(Rc::new(environment)) - } -} - -impl std::ops::Deref for EnvironmentRef { - type Target = Environment; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -fn set_logical_parents(parents: &mut Vec>, syntax_tree: &SyntaxTree, t: TreeRef) { - let tree = &syntax_tree[t]; - - // The default logical parent is the physical parent. - if parents.len() <= t.index() { - parents.resize(t.index() + 1, None); - parents[t.index()] = tree.parent.clone(); - } - - for child in &tree.children { - match child { - Child::Token(_) => (), - Child::Tree(ct) => set_logical_parents(parents, syntax_tree, *ct), - } - } - - match tree.kind { - TreeKind::Block => { - // In a block, each child actually points to the previous child - // as the logical parent, so that variable declarations that - // occur as part of statements in the block are available to - // statements later in the block. - let mut parent = Some(t); - for child in &tree.children { - match child { - Child::Token(_) => (), - Child::Tree(ct) => { - parents[t.index()] = parent; - parent = Some(*ct); - } - } - } - } - _ => {} - } -} - pub struct Semantics<'a> { // TODO: Do I really want my own copy here? Should we standardize on Arc // or Rc or some other nice sharing mechanism? syntax_tree: &'a SyntaxTree<'a>, lines: &'a Lines, - - // Instead of physical parents, this is the set of *logical* parents. - // This is what is used for binding. - logical_parents: Vec>, - - // TODO: State should be externalized instead of this refcell nonsense. errors: RefCell>, types: RefCell>, - environments: RefCell>, - empty_environment: EnvironmentRef, } impl<'a> Semantics<'a> { pub fn new(tree: &'a SyntaxTree<'a>, lines: &'a Lines) -> Self { - let mut logical_parents = Vec::new(); - if let Some(root) = tree.root() { - set_logical_parents(&mut logical_parents, tree, root); - } - let mut semantics = Semantics { syntax_tree: tree, lines, - logical_parents, errors: RefCell::new(vec![]), types: RefCell::new(HashMap::new()), - environments: RefCell::new(HashMap::new()), - empty_environment: EnvironmentRef::new(Environment::new(None)), }; // NOTE: We ensure all the known errors are reported before we move @@ -314,26 +210,6 @@ impl<'a> Semantics<'a> { } } - pub fn environment_of(&self, t: TreeRef) -> EnvironmentRef { - if let Some(existing) = self.environments.borrow().get(&t) { - return existing.clone(); - } - - let tree = &self.syntax_tree[t]; - let parent = match self.logical_parents[t.index()] { - Some(t) => self.environment_of(t), - None => self.empty_environment.clone(), - }; - - let result = match tree.kind { - // TODO: Things that introduce an environment! - _ => parent, - }; - - self.environments.borrow_mut().insert(t, result.clone()); - result - } - pub fn type_of(&self, t: TreeRef) -> Option { if let Some(existing) = self.types.borrow().get(&t) { return Some(existing.clone()); @@ -471,10 +347,10 @@ impl<'a> Semantics<'a> { return None; } - if tree.children.len() == 2 { - // Empty blocks generate Nothing. - return Some(Type::Nothing); - } + // if tree.children.len() == 2 { + // // Empty blocks generate Nothing. + // return Some(Type::Nothing); + // } // The type of the block is the type of the last expression. // (But the last child is the closing brace probably?) @@ -483,9 +359,6 @@ impl<'a> Semantics<'a> { let mut is_unreachable = false; for i in 1..last_index { - // TODO: if `is_unreachable` here then we actually have - // unreachable code here! We should warn about it I guess. - is_unreachable = self .type_of(tree.nth_tree(i)?) .map(|t| matches!(t, Type::Unreachable)) @@ -615,16 +488,6 @@ impl<'a> Semantics<'a> { fn type_of_identifier(&self, 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); - } - } - - self.report_error_tree(tree, format!("cannot find value {id} here")); Some(Type::Error) } } diff --git a/fine/tests/example_tests.rs b/fine/tests/example_tests.rs index ad296efd..d2bd33b2 100644 --- a/fine/tests/example_tests.rs +++ b/fine/tests/example_tests.rs @@ -16,7 +16,7 @@ fn rebase_concrete(source_path: &str, dump: &str) { result.push_str(line); result.push_str("\n"); - if line == "// @concrete:" { + if line == "// concrete:" { found_concrete_section = true; break; } diff --git a/fine/tests/expression/block.fine b/fine/tests/expression/block.fine deleted file mode 100644 index 524514bc..00000000 --- a/fine/tests/expression/block.fine +++ /dev/null @@ -1,10 +0,0 @@ -// @concrete: -// | File -// | Block -// | LeftBrace:'"{"' -// | RightBrace:'"}"' -// | - -{} - -// @type: 94 ()