Partway there in terms of implementing source map lookup

This commit is contained in:
greg 2019-10-23 03:08:36 -07:00
parent 7495f30e16
commit 1ffe61cf5f
3 changed files with 25 additions and 12 deletions

View File

@ -3,10 +3,12 @@ use std::fmt;
use crate::ast::ItemId;
pub type LineNumber = usize;
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Location {
pub line_num: usize,
pub char_num: usize
pub line_num: LineNumber,
pub char_num: usize,
}
impl fmt::Display for Location {
@ -27,4 +29,11 @@ impl SourceMap {
pub fn add_location(&mut self, id: &ItemId, loc: Location) {
self.map.insert(id.clone(), loc);
}
pub fn lookup(&self, id: &ItemId) -> Option<Location> {
match self.map.get(id) {
Some(loc) => Some(loc.clone()),
None => None
}
}
}

View File

@ -5,6 +5,7 @@ use std::fmt;
use std::fmt::Write;
use crate::schala::SourceMapHandle;
use crate::source_map::{SourceMap, LineNumber};
use crate::ast;
use crate::ast::{ItemId, TypeBody, TypeSingletonName, Signature, Statement, StatementKind};
use crate::typechecking::TypeName;
@ -27,7 +28,6 @@ mod symbol_trie;
use symbol_trie::SymbolTrie;
mod test;
type LineNumber = u32;
type SymbolTrackTable = HashMap<Rc<String>, LineNumber>;
#[derive(PartialEq, Eq, Hash, Debug, Clone, PartialOrd, Ord)]
@ -163,14 +163,18 @@ impl SymbolTable {
fn add_symbols_from_scope<'a>(&'a mut self, statements: &Vec<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> {
fn insert_and_check_duplicate_symbol(table: &mut SymbolTrackTable, name: &Rc<String>, id: &ItemId, source_map: &SourceMap) -> Result<(), String> {
match table.entry(name.clone()) {
Entry::Occupied(o) => {
let line_number = o.get(); //TODO make this actually work
let line_number = o.get();
Err(format!("Duplicate definition: {}. It's already defined at {}", name, line_number))
},
Entry::Vacant(v) => {
let line_number = 0; //TODO should work
let line_number = if let Some(loc) = source_map.lookup(id) {
loc.line_num
} else {
0
};
v.insert(line_number);
Ok(())
}
@ -180,14 +184,14 @@ impl SymbolTable {
let mut seen_identifiers: SymbolTrackTable = HashMap::new();
for statement in statements.iter() {
if let Statement { kind: StatementKind::Declaration(decl), .. } = statement {
if let Statement { kind: StatementKind::Declaration(decl), id } = statement {
match decl {
FuncSig(ref signature) => {
insert_and_check_duplicate_symbol(&mut seen_identifiers, &signature.name)?;
insert_and_check_duplicate_symbol(&mut seen_identifiers, &signature.name, &id, &self.source_map_handle.borrow())?;
self.add_function_signature(signature, scope_name_stack)?
}
FuncDecl(ref signature, ref body) => {
insert_and_check_duplicate_symbol(&mut seen_identifiers, &signature.name)?;
insert_and_check_duplicate_symbol(&mut seen_identifiers, &signature.name, &id, &self.source_map_handle.borrow())?;
self.add_function_signature(signature, scope_name_stack)?;
scope_name_stack.push(ScopeSegment{
name: signature.name.clone(),
@ -197,11 +201,11 @@ impl SymbolTable {
output?
},
TypeDecl { name, body, mutable } => {
insert_and_check_duplicate_symbol(&mut seen_identifiers, &name.name)?;
insert_and_check_duplicate_symbol(&mut seen_identifiers, &name.name, &id, &self.source_map_handle.borrow())?;
self.add_type_decl(name, body, mutable, scope_name_stack)?
},
Binding { name, .. } => {
insert_and_check_duplicate_symbol(&mut seen_identifiers, name)?;
insert_and_check_duplicate_symbol(&mut seen_identifiers, name, &id, &self.source_map_handle.borrow())?;
self.add_new_symbol(name, scope_name_stack, SymbolSpec::Binding);
}
_ => ()

View File

@ -46,7 +46,6 @@ fn no_duplicates() {
let mut symbol_table = SymbolTable::new(source_map);
let ast = quick_ast(source);
let output = symbol_table.add_top_level_symbols(&ast).unwrap_err();
println!("OUTPUT: {}", output);
assert!(output.contains("Duplicate"))
}
@ -61,6 +60,7 @@ fn no_duplicates_2() {
let mut symbol_table = SymbolTable::new(source_map);
let ast = quick_ast(source);
let output = symbol_table.add_top_level_symbols(&ast).unwrap_err();
println!("OUTPUT: {}", output);
assert!(output.contains("Duplicate"));
assert!(output.contains("Line 3"));
}