Partway there in terms of implementing source map lookup
This commit is contained in:
parent
7495f30e16
commit
1ffe61cf5f
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
_ => ()
|
||||
|
@ -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"));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user