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;
|
use crate::ast::ItemId;
|
||||||
|
|
||||||
|
pub type LineNumber = usize;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub struct Location {
|
pub struct Location {
|
||||||
pub line_num: usize,
|
pub line_num: LineNumber,
|
||||||
pub char_num: usize
|
pub char_num: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Location {
|
impl fmt::Display for Location {
|
||||||
@ -27,4 +29,11 @@ impl SourceMap {
|
|||||||
pub fn add_location(&mut self, id: &ItemId, loc: Location) {
|
pub fn add_location(&mut self, id: &ItemId, loc: Location) {
|
||||||
self.map.insert(id.clone(), loc);
|
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 std::fmt::Write;
|
||||||
|
|
||||||
use crate::schala::SourceMapHandle;
|
use crate::schala::SourceMapHandle;
|
||||||
|
use crate::source_map::{SourceMap, LineNumber};
|
||||||
use crate::ast;
|
use crate::ast;
|
||||||
use crate::ast::{ItemId, TypeBody, TypeSingletonName, Signature, Statement, StatementKind};
|
use crate::ast::{ItemId, TypeBody, TypeSingletonName, Signature, Statement, StatementKind};
|
||||||
use crate::typechecking::TypeName;
|
use crate::typechecking::TypeName;
|
||||||
@ -27,7 +28,6 @@ mod symbol_trie;
|
|||||||
use symbol_trie::SymbolTrie;
|
use symbol_trie::SymbolTrie;
|
||||||
mod test;
|
mod test;
|
||||||
|
|
||||||
type LineNumber = u32;
|
|
||||||
type SymbolTrackTable = HashMap<Rc<String>, LineNumber>;
|
type SymbolTrackTable = HashMap<Rc<String>, LineNumber>;
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Hash, Debug, Clone, PartialOrd, Ord)]
|
#[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> {
|
fn add_symbols_from_scope<'a>(&'a mut self, statements: &Vec<Statement>, scope_name_stack: &mut Vec<ScopeSegment>) -> Result<(), String> {
|
||||||
use self::ast::Declaration::*;
|
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()) {
|
match table.entry(name.clone()) {
|
||||||
Entry::Occupied(o) => {
|
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))
|
Err(format!("Duplicate definition: {}. It's already defined at {}", name, line_number))
|
||||||
},
|
},
|
||||||
Entry::Vacant(v) => {
|
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);
|
v.insert(line_number);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -180,14 +184,14 @@ impl SymbolTable {
|
|||||||
let mut seen_identifiers: SymbolTrackTable = HashMap::new();
|
let mut seen_identifiers: SymbolTrackTable = HashMap::new();
|
||||||
|
|
||||||
for statement in statements.iter() {
|
for statement in statements.iter() {
|
||||||
if let Statement { kind: StatementKind::Declaration(decl), .. } = statement {
|
if let Statement { kind: StatementKind::Declaration(decl), id } = statement {
|
||||||
match decl {
|
match decl {
|
||||||
FuncSig(ref signature) => {
|
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)?
|
self.add_function_signature(signature, scope_name_stack)?
|
||||||
}
|
}
|
||||||
FuncDecl(ref signature, ref body) => {
|
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)?;
|
self.add_function_signature(signature, scope_name_stack)?;
|
||||||
scope_name_stack.push(ScopeSegment{
|
scope_name_stack.push(ScopeSegment{
|
||||||
name: signature.name.clone(),
|
name: signature.name.clone(),
|
||||||
@ -197,11 +201,11 @@ impl SymbolTable {
|
|||||||
output?
|
output?
|
||||||
},
|
},
|
||||||
TypeDecl { name, body, mutable } => {
|
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)?
|
self.add_type_decl(name, body, mutable, scope_name_stack)?
|
||||||
},
|
},
|
||||||
Binding { name, .. } => {
|
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);
|
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 mut symbol_table = SymbolTable::new(source_map);
|
||||||
let ast = quick_ast(source);
|
let ast = quick_ast(source);
|
||||||
let output = symbol_table.add_top_level_symbols(&ast).unwrap_err();
|
let output = symbol_table.add_top_level_symbols(&ast).unwrap_err();
|
||||||
println!("OUTPUT: {}", output);
|
|
||||||
assert!(output.contains("Duplicate"))
|
assert!(output.contains("Duplicate"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,6 +60,7 @@ fn no_duplicates_2() {
|
|||||||
let mut symbol_table = SymbolTable::new(source_map);
|
let mut symbol_table = SymbolTable::new(source_map);
|
||||||
let ast = quick_ast(source);
|
let ast = quick_ast(source);
|
||||||
let output = symbol_table.add_top_level_symbols(&ast).unwrap_err();
|
let output = symbol_table.add_top_level_symbols(&ast).unwrap_err();
|
||||||
|
println!("OUTPUT: {}", output);
|
||||||
assert!(output.contains("Duplicate"));
|
assert!(output.contains("Duplicate"));
|
||||||
assert!(output.contains("Line 3"));
|
assert!(output.contains("Line 3"));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user