From bdcae36b602eff098fcf59c20069ecd8f53d9ff2 Mon Sep 17 00:00:00 2001 From: greg Date: Mon, 11 Mar 2019 02:47:47 -0700 Subject: [PATCH] More cleaning up of how scopes are stored on Symbol --- schala-lang/language/src/eval.rs | 2 +- schala-lang/language/src/symbol_table.rs | 47 +++++++++++------------- 2 files changed, 23 insertions(+), 26 deletions(-) diff --git a/schala-lang/language/src/eval.rs b/schala-lang/language/src/eval.rs index 750dcd4..946c305 100644 --- a/schala-lang/language/src/eval.rs +++ b/schala-lang/language/src/eval.rs @@ -467,7 +467,7 @@ impl<'a> State<'a> { let symbol_table = self.symbol_table_handle.borrow(); let value = symbol_table.lookup_by_name(&name); Ok(match value { - Some(Symbol { name, spec }) => match spec { + Some(Symbol { name, spec, .. }) => match spec { //TODO I'll need this type_name later to do a table lookup SymbolSpec::DataConstructor { type_name: _type_name, type_args, .. } => { if type_args.len() == 0 { diff --git a/schala-lang/language/src/symbol_table.rs b/schala-lang/language/src/symbol_table.rs index 9567adf..5966fa4 100644 --- a/schala-lang/language/src/symbol_table.rs +++ b/schala-lang/language/src/symbol_table.rs @@ -3,7 +3,6 @@ use std::collections::hash_map::Entry; use std::rc::Rc; use std::fmt; use std::fmt::Write; -use std::iter::IntoIterator; use crate::ast; use crate::ast::{Meta, TypeBody, TypeSingletonName, Signature, Statement}; @@ -15,14 +14,14 @@ type SymbolTrackTable = HashMap, LineNumber>; #[derive(PartialEq, Eq, Hash, Debug)] struct PathToSymbol(Vec>); -#[derive(Debug)] +#[derive(Debug, Clone)] struct ScopeSegment { scope_name: Rc, - scope_type: ScopeType, + scope_type: ScopeSegmentKind, } -#[derive(Debug)] -enum ScopeType { +#[derive(Debug, Clone)] +enum ScopeSegmentKind { Function, Type, } @@ -40,10 +39,11 @@ impl SymbolTable { } } - fn add_new_symbol(&mut self, name: &Rc, path: &Vec>, symbol: Symbol) { - let mut vec = path.clone(); + fn add_new_symbol(&mut self, name: &Rc, scope_path: &Vec, spec: SymbolSpec) { + let mut vec: Vec> = scope_path.iter().map(|segment| segment.scope_name.clone()).collect(); vec.push(name.clone()); let symbol_path = PathToSymbol(vec); + let symbol = Symbol { name: name.clone(), scopes: scope_path.to_vec(), spec }; self.values.insert(symbol_path, symbol); } @@ -61,7 +61,8 @@ impl SymbolTable { #[derive(Debug)] pub struct Symbol { - pub name: Rc, + pub name: Rc, //TODO does this need to be pub? + scopes: Vec, pub spec: SymbolSpec, } @@ -106,7 +107,7 @@ impl SymbolTable { self.add_symbols_from_scope(&ast.0, &mut scope_name_stack) } - fn add_symbols_from_scope<'a>(&'a mut self, statements: &Vec>, scope_name_stack: &mut Vec>) -> Result<(), String> { + fn add_symbols_from_scope<'a>(&'a mut self, statements: &Vec>, scope_name_stack: &mut Vec) -> Result<(), String> { use self::ast::Declaration::*; fn insert_and_check_duplicate_symbol(table: &mut SymbolTrackTable, name: &Rc) -> Result<(), String> { @@ -136,7 +137,10 @@ impl SymbolTable { FuncDecl(ref signature, ref body) => { insert_and_check_duplicate_symbol(&mut seen_identifiers, &signature.name)?; self.add_function_signature(signature, scope_name_stack)?; - scope_name_stack.push(signature.name.clone()); + scope_name_stack.push(ScopeSegment{ + scope_name: signature.name.clone(), + scope_type: ScopeSegmentKind::Function, + }); let output = self.add_symbols_from_scope(body, scope_name_stack); let _ = scope_name_stack.pop(); output? @@ -147,8 +151,7 @@ impl SymbolTable { }, Binding { name, .. } => { insert_and_check_duplicate_symbol(&mut seen_identifiers, name)?; - let symbol = Symbol { name: name.clone(), spec: SymbolSpec::Binding }; - self.add_new_symbol(name, scope_name_stack, symbol); + self.add_new_symbol(name, scope_name_stack, SymbolSpec::Binding); } _ => () } @@ -164,22 +167,17 @@ impl SymbolTable { output } - fn add_function_signature(&mut self, signature: &Signature, scope_name_stack: &mut Vec>) -> Result<(), String> { + fn add_function_signature(&mut self, signature: &Signature, scope_name_stack: &mut Vec) -> Result<(), String> { let mut local_type_context = LocalTypeContext::new(); let types = signature.params.iter().map(|param| match param { (_, Some(type_identifier)) => Rc::new(format!("{:?}", type_identifier)), (_, None) => local_type_context.new_universal_type() }).collect(); - let spec = SymbolSpec::Func(types); - self.add_new_symbol( - &signature.name, - scope_name_stack, - Symbol { name: signature.name.clone(), spec } - ); + self.add_new_symbol(&signature.name, scope_name_stack, SymbolSpec::Func(types)); Ok(()) } - fn add_type_decl(&mut self, type_name: &TypeSingletonName, body: &TypeBody, _mutable: &bool, scope_name_stack: &mut Vec>) -> Result<(), String> { + fn add_type_decl(&mut self, type_name: &TypeSingletonName, body: &TypeBody, _mutable: &bool, scope_name_stack: &mut Vec) -> Result<(), String> { use crate::ast::{TypeIdentifier, Variant}; let TypeBody(variants) = body; let TypeSingletonName { name, .. } = type_name; @@ -194,7 +192,7 @@ impl SymbolTable { type_name: name.clone(), type_args: vec![], }; - self.add_new_symbol(variant_name, scope_name_stack, Symbol { name: variant_name.clone(), spec }); + self.add_new_symbol(variant_name, scope_name_stack, spec); }, Variant::TupleStruct(variant_name, tuple_members) => { let type_args = tuple_members.iter().map(|type_name| match type_name { @@ -206,16 +204,14 @@ impl SymbolTable { type_name: name.clone(), type_args }; - let symbol = Symbol { name: variant_name.clone(), spec }; - self.add_new_symbol(variant_name, scope_name_stack, symbol); + self.add_new_symbol(variant_name, scope_name_stack, spec); }, //TODO if there is only one variant, and it is a record, it doesn't need to have an //explicit name Variant::Record { name, members: _members } => { let fields = HashMap::new(); let spec = SymbolSpec::RecordConstructor { fields }; - let symbol = Symbol { name: name.clone(), spec }; - self.add_new_symbol(name, scope_name_stack, symbol); + self.add_new_symbol(name, scope_name_stack, spec); }, } } @@ -311,6 +307,7 @@ mod symbol_table_tests { assert!(output.contains("Duplicate")) } + #[test] fn dont_falsely_detect_duplicates() { let source = r#" let a = 20;