Make use of TypeContext in SymbolTable

This commit is contained in:
Greg Shuflin 2021-10-27 15:39:09 -07:00
parent 40be5a8a33
commit 765a0bec58
6 changed files with 64 additions and 48 deletions

View File

@ -1,20 +1,21 @@
#![cfg(test)] #![cfg(test)]
use crate::symbol_table::SymbolTable;
use super::*; use super::*;
use crate::{symbol_table::SymbolTable, type_inference::TypeContext};
fn build_ir(input: &str) -> ReducedIR { fn build_ir(input: &str) -> ReducedIR {
let ast = crate::util::quick_ast(input); let ast = crate::util::quick_ast(input);
let mut symbol_table = SymbolTable::new(); let mut symbol_table = SymbolTable::new();
symbol_table.process_ast(&ast).unwrap(); let mut type_context = TypeContext::new();
symbol_table.process_ast(&ast, &mut type_context).unwrap();
let reduced = reduce(&ast, &symbol_table); let reduced = reduce(&ast, &symbol_table);
reduced.debug(&symbol_table); reduced.debug(&symbol_table);
reduced reduced
} }
#[test] #[test]
fn test_ir() { fn test_ir() {
let src = r#" let src = r#"

View File

@ -83,7 +83,9 @@ impl<'a> Schala<'a> {
.map_err(|err| SchalaError::from_parse_error(err, &self.source_reference))?; .map_err(|err| SchalaError::from_parse_error(err, &self.source_reference))?;
//Perform all symbol table work //Perform all symbol table work
self.symbol_table.process_ast(&ast).map_err(SchalaError::from_symbol_table)?; self.symbol_table
.process_ast(&ast, &mut self.type_context)
.map_err(SchalaError::from_symbol_table)?;
// Typechecking // Typechecking
// TODO typechecking not working // TODO typechecking not working

View File

@ -8,7 +8,7 @@ use crate::ast::{
Variant, VariantKind, Variant, VariantKind,
}; };
use crate::tokenizing::Location; use crate::tokenizing::Location;
use crate::type_inference::TypeId; use crate::type_inference::{TypeContext, TypeId};
mod resolver; mod resolver;
mod symbol_trie; mod symbol_trie;
@ -171,12 +171,15 @@ impl SymbolTable {
/// The main entry point into the symbol table. This will traverse the AST in several /// The main entry point into the symbol table. This will traverse the AST in several
/// different ways and populate subtables with information that will be used further in the /// different ways and populate subtables with information that will be used further in the
/// compilation process. /// compilation process.
pub fn process_ast(&mut self, ast: &ast::AST) -> Result<(), Vec<SymbolError>> { pub fn process_ast(&mut self, ast: &ast::AST, type_context: &mut TypeContext) -> Result<(), Vec<SymbolError>> {
let errs = self.populate_name_tables(ast);
let mut runner = SymbolTableRunner { type_context, table: self };
let errs = runner.populate_name_tables(ast);
if !errs.is_empty() { if !errs.is_empty() {
return Err(errs); return Err(errs);
} }
self.resolve_scopes(ast); runner.resolve_scopes(ast);
Ok(()) Ok(())
} }
@ -198,6 +201,26 @@ impl SymbolTable {
println!("{} => {}", id, sym); println!("{} => {}", id, sym);
} }
} }
/// Register a new mapping of a fully-qualified symbol name (e.g. `Option::Some`)
/// to a Symbol, a descriptor of what that name refers to.
fn add_symbol(&mut self, id: &ItemId, fqsn: Fqsn, spec: SymbolSpec) {
let def_id = self.def_id_store.fresh();
let symbol = Rc::new(Symbol {
fully_qualified_name: fqsn.clone(),
spec,
def_id,
});
println!("In add_symbol(), adding: {:?}", symbol);
self.symbol_trie.insert(&fqsn);
self.fqsn_to_symbol.insert(fqsn, symbol.clone());
self.id_to_symbol.insert(*id, symbol);
}
}
struct SymbolTableRunner<'a> {
type_context: &'a mut TypeContext,
table: &'a mut SymbolTable
} }
#[allow(dead_code)] #[allow(dead_code)]
@ -286,29 +309,18 @@ impl fmt::Display for SymbolSpec {
} }
} }
impl SymbolTable { impl<'a> SymbolTableRunner<'a> {
/* note: this adds names for *forward reference* but doesn't actually create any types. solve that problem /* note: this adds names for *forward reference* but doesn't actually create any types. solve that problem
* later */ * later */
/// Register a new mapping of a fully-qualified symbol name (e.g. `Option::Some`)
/// to a Symbol, a descriptor of what that name refers to.
fn add_symbol(&mut self, id: &ItemId, fqsn: Fqsn, spec: SymbolSpec) { fn add_symbol(&mut self, id: &ItemId, fqsn: Fqsn, spec: SymbolSpec) {
let def_id = self.def_id_store.fresh(); self.table.add_symbol(id, fqsn, spec)
let symbol = Rc::new(Symbol {
fully_qualified_name: fqsn.clone(),
spec,
def_id,
});
println!("In add_symbol(), adding: {:?}", symbol);
self.symbol_trie.insert(&fqsn);
self.fqsn_to_symbol.insert(fqsn, symbol.clone());
self.id_to_symbol.insert(*id, symbol);
} }
/// Walks the AST, matching the ID of an identifier used in some expression to /// Walks the AST, matching the ID of an identifier used in some expression to
/// the corresponding Symbol. /// the corresponding Symbol.
fn resolve_scopes(&mut self, ast: &ast::AST) { fn resolve_scopes(&mut self, ast: &ast::AST) {
let mut resolver = resolver::ScopeResolver::new(self); let mut resolver = resolver::ScopeResolver::new(self.table);
resolver.resolve(ast); resolver.resolve(ast);
} }
@ -321,8 +333,8 @@ impl SymbolTable {
self.add_from_scope(ast.statements.as_ref(), &mut scope_stack, false) self.add_from_scope(ast.statements.as_ref(), &mut scope_stack, false)
} }
fn add_from_scope<'a>( fn add_from_scope(
&'a mut self, &mut self,
statements: &[Statement], statements: &[Statement],
scope_stack: &mut Vec<Scope>, scope_stack: &mut Vec<Scope>,
function_scope: bool, function_scope: bool,
@ -380,14 +392,14 @@ impl SymbolTable {
match kind { match kind {
StatementKind::Declaration(Declaration::FuncSig(signature)) => { StatementKind::Declaration(Declaration::FuncSig(signature)) => {
let fq_function = Fqsn::from_scope_stack(scope_stack, signature.name.clone()); let fq_function = Fqsn::from_scope_stack(scope_stack, signature.name.clone());
self.fq_names.register( self.table.fq_names.register(
fq_function.clone(), fq_function.clone(),
NameSpec { NameSpec {
location, location,
kind: NameKind::Function, kind: NameKind::Function,
}, },
)?; )?;
self.types.register( self.table.types.register(
fq_function.clone(), fq_function.clone(),
NameSpec { NameSpec {
location, location,
@ -404,14 +416,14 @@ impl SymbolTable {
StatementKind::Declaration(Declaration::FuncDecl(signature, ..)) => { StatementKind::Declaration(Declaration::FuncDecl(signature, ..)) => {
let fn_name = &signature.name; let fn_name = &signature.name;
let fq_function = Fqsn::from_scope_stack(scope_stack, fn_name.clone()); let fq_function = Fqsn::from_scope_stack(scope_stack, fn_name.clone());
self.fq_names.register( self.table.fq_names.register(
fq_function.clone(), fq_function.clone(),
NameSpec { NameSpec {
location, location,
kind: NameKind::Function, kind: NameKind::Function,
}, },
)?; )?;
self.types.register( self.table.types.register(
fq_function.clone(), fq_function.clone(),
NameSpec { NameSpec {
location, location,
@ -427,7 +439,7 @@ impl SymbolTable {
} }
StatementKind::Declaration(Declaration::TypeDecl { name, .. }) => { StatementKind::Declaration(Declaration::TypeDecl { name, .. }) => {
let fq_type = Fqsn::from_scope_stack(scope_stack, name.name.clone()); let fq_type = Fqsn::from_scope_stack(scope_stack, name.name.clone());
self.types.register( self.table.types.register(
fq_type, fq_type,
NameSpec { NameSpec {
location, location,
@ -437,7 +449,7 @@ impl SymbolTable {
} }
StatementKind::Declaration(Declaration::Binding { name, .. }) => { StatementKind::Declaration(Declaration::Binding { name, .. }) => {
let fq_binding = Fqsn::from_scope_stack(scope_stack, name.clone()); let fq_binding = Fqsn::from_scope_stack(scope_stack, name.clone());
self.fq_names.register( self.table.fq_names.register(
fq_binding.clone(), fq_binding.clone(),
NameSpec { NameSpec {
location, location,
@ -454,7 +466,7 @@ impl SymbolTable {
} }
StatementKind::Module(ModuleSpecifier { name, .. }) => { StatementKind::Module(ModuleSpecifier { name, .. }) => {
let fq_module = Fqsn::from_scope_stack(scope_stack, name.clone()); let fq_module = Fqsn::from_scope_stack(scope_stack, name.clone());
self.fq_names.register( self.table.fq_names.register(
fq_module, fq_module,
NameSpec { NameSpec {
location, location,
@ -483,10 +495,10 @@ impl SymbolTable {
location, location,
kind: TypeKind, kind: TypeKind,
}; };
if let Err(err) = self.types.register(fqsn.clone(), name_spec) { if let Err(err) = self.table.types.register(fqsn.clone(), name_spec) {
errors.push(err); errors.push(err);
} else { } else {
self.add_symbol(id, fqsn, spec); self.table.add_symbol(id, fqsn, spec);
}; };
}; };
@ -497,7 +509,7 @@ impl SymbolTable {
for (index, variant) in variants.iter().enumerate() { for (index, variant) in variants.iter().enumerate() {
let tag = index as u32; let tag = index as u32;
let Variant { name, kind, id } = variant; let Variant { name, kind, id } = variant;
let type_id = TypeId::lookup_name(name.as_ref()); let type_id = self.type_context.id_from_name(name.as_ref());
match kind { match kind {
VariantKind::UnitStruct => { VariantKind::UnitStruct => {
@ -547,7 +559,7 @@ impl SymbolTable {
.map(|(member_name, _type_identifier)| { .map(|(member_name, _type_identifier)| {
( (
member_name.clone(), member_name.clone(),
TypeId::lookup_name("DUMMY_TYPE_ID"), self.type_context.id_from_name("DUMMY_TYPE_ID")
) )
}) })
.collect(), .collect(),

View File

@ -6,7 +6,8 @@ use assert_matches::assert_matches;
fn add_symbols(src: &str) -> (SymbolTable, Result<(), Vec<SymbolError>>) { fn add_symbols(src: &str) -> (SymbolTable, Result<(), Vec<SymbolError>>) {
let ast = quick_ast(src); let ast = quick_ast(src);
let mut symbol_table = SymbolTable::new(); let mut symbol_table = SymbolTable::new();
let result = symbol_table.process_ast(&ast); let mut type_context = crate::type_inference::TypeContext::new();
let result = symbol_table.process_ast(&ast, &mut type_context);
(symbol_table, result) (symbol_table, result)
} }

View File

@ -10,9 +10,9 @@ use crate::{
fn evaluate_input(input: &str) -> Result<String, String> { fn evaluate_input(input: &str) -> Result<String, String> {
let ast = crate::util::quick_ast(input); let ast = crate::util::quick_ast(input);
let mut symbol_table = SymbolTable::new(); let mut symbol_table = SymbolTable::new();
symbol_table.process_ast(&ast).unwrap(); let mut type_context = TypeContext::new();
let type_context = TypeContext::new(); symbol_table.process_ast(&ast, &mut type_context).unwrap();
let reduced_ir = crate::reduced_ir::reduce(&ast, &symbol_table); let reduced_ir = crate::reduced_ir::reduce(&ast, &symbol_table);
reduced_ir.debug(&symbol_table); reduced_ir.debug(&symbol_table);

View File

@ -13,11 +13,6 @@ impl fmt::Display for TypeId {
} }
impl TypeId { impl TypeId {
//TODO this is definitely incomplete
pub fn lookup_name(name: &str) -> TypeId {
TypeId { local_name: Rc::new(name.to_string()) }
}
pub fn local_name(&self) -> &str { pub fn local_name(&self) -> &str {
self.local_name.as_ref() self.local_name.as_ref()
} }
@ -29,6 +24,11 @@ impl TypeContext {
pub fn new() -> Self { pub fn new() -> Self {
Self Self
} }
//TODO flesh this out...
pub fn id_from_name(&self, name: &str) -> TypeId {
TypeId { local_name: Rc::new(name.to_string()) }
}
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]