More cleaning up of how scopes are stored
on Symbol
This commit is contained in:
parent
dbcd2278a6
commit
bdcae36b60
@ -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 {
|
||||
|
@ -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<Rc<String>, LineNumber>;
|
||||
#[derive(PartialEq, Eq, Hash, Debug)]
|
||||
struct PathToSymbol(Vec<Rc<String>>);
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
struct ScopeSegment {
|
||||
scope_name: Rc<String>,
|
||||
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<String>, path: &Vec<Rc<String>>, symbol: Symbol) {
|
||||
let mut vec = path.clone();
|
||||
fn add_new_symbol(&mut self, name: &Rc<String>, scope_path: &Vec<ScopeSegment>, spec: SymbolSpec) {
|
||||
let mut vec: Vec<Rc<String>> = 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<String>,
|
||||
pub name: Rc<String>, //TODO does this need to be pub?
|
||||
scopes: Vec<ScopeSegment>,
|
||||
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<Meta<Statement>>, scope_name_stack: &mut Vec<Rc<String>>) -> Result<(), String> {
|
||||
fn add_symbols_from_scope<'a>(&'a mut self, statements: &Vec<Meta<Statement>>, scope_name_stack: &mut Vec<ScopeSegment>) -> Result<(), String> {
|
||||
use self::ast::Declaration::*;
|
||||
|
||||
fn insert_and_check_duplicate_symbol(table: &mut SymbolTrackTable, name: &Rc<String>) -> 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<Rc<String>>) -> Result<(), String> {
|
||||
fn add_function_signature(&mut self, signature: &Signature, scope_name_stack: &mut Vec<ScopeSegment>) -> 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<Rc<String>>) -> Result<(), String> {
|
||||
fn add_type_decl(&mut self, type_name: &TypeSingletonName, body: &TypeBody, _mutable: &bool, scope_name_stack: &mut Vec<ScopeSegment>) -> 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;
|
||||
|
Loading…
Reference in New Issue
Block a user