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)]
use crate::symbol_table::SymbolTable;
use super::*;
use crate::{symbol_table::SymbolTable, type_inference::TypeContext};
fn build_ir(input: &str) -> ReducedIR {
let ast = crate::util::quick_ast(input);
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);
reduced.debug(&symbol_table);
reduced
}
#[test]
fn test_ir() {
let src = r#"

View File

@ -83,7 +83,9 @@ impl<'a> Schala<'a> {
.map_err(|err| SchalaError::from_parse_error(err, &self.source_reference))?;
//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
// TODO typechecking not working

View File

@ -8,7 +8,7 @@ use crate::ast::{
Variant, VariantKind,
};
use crate::tokenizing::Location;
use crate::type_inference::TypeId;
use crate::type_inference::{TypeContext, TypeId};
mod resolver;
mod symbol_trie;
@ -171,12 +171,15 @@ impl SymbolTable {
/// 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
/// compilation process.
pub fn process_ast(&mut self, ast: &ast::AST) -> Result<(), Vec<SymbolError>> {
let errs = self.populate_name_tables(ast);
pub fn process_ast(&mut self, ast: &ast::AST, type_context: &mut TypeContext) -> Result<(), Vec<SymbolError>> {
let mut runner = SymbolTableRunner { type_context, table: self };
let errs = runner.populate_name_tables(ast);
if !errs.is_empty() {
return Err(errs);
}
self.resolve_scopes(ast);
runner.resolve_scopes(ast);
Ok(())
}
@ -198,6 +201,26 @@ impl SymbolTable {
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)]
@ -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
* 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) {
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);
self.table.add_symbol(id, fqsn, spec)
}
/// Walks the AST, matching the ID of an identifier used in some expression to
/// the corresponding Symbol.
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);
}
@ -321,8 +333,8 @@ impl SymbolTable {
self.add_from_scope(ast.statements.as_ref(), &mut scope_stack, false)
}
fn add_from_scope<'a>(
&'a mut self,
fn add_from_scope(
&mut self,
statements: &[Statement],
scope_stack: &mut Vec<Scope>,
function_scope: bool,
@ -380,14 +392,14 @@ impl SymbolTable {
match kind {
StatementKind::Declaration(Declaration::FuncSig(signature)) => {
let fq_function = Fqsn::from_scope_stack(scope_stack, signature.name.clone());
self.fq_names.register(
self.table.fq_names.register(
fq_function.clone(),
NameSpec {
location,
kind: NameKind::Function,
},
)?;
self.types.register(
self.table.types.register(
fq_function.clone(),
NameSpec {
location,
@ -404,14 +416,14 @@ impl SymbolTable {
StatementKind::Declaration(Declaration::FuncDecl(signature, ..)) => {
let fn_name = &signature.name;
let fq_function = Fqsn::from_scope_stack(scope_stack, fn_name.clone());
self.fq_names.register(
self.table.fq_names.register(
fq_function.clone(),
NameSpec {
location,
kind: NameKind::Function,
},
)?;
self.types.register(
self.table.types.register(
fq_function.clone(),
NameSpec {
location,
@ -427,7 +439,7 @@ impl SymbolTable {
}
StatementKind::Declaration(Declaration::TypeDecl { name, .. }) => {
let fq_type = Fqsn::from_scope_stack(scope_stack, name.name.clone());
self.types.register(
self.table.types.register(
fq_type,
NameSpec {
location,
@ -437,7 +449,7 @@ impl SymbolTable {
}
StatementKind::Declaration(Declaration::Binding { name, .. }) => {
let fq_binding = Fqsn::from_scope_stack(scope_stack, name.clone());
self.fq_names.register(
self.table.fq_names.register(
fq_binding.clone(),
NameSpec {
location,
@ -454,7 +466,7 @@ impl SymbolTable {
}
StatementKind::Module(ModuleSpecifier { name, .. }) => {
let fq_module = Fqsn::from_scope_stack(scope_stack, name.clone());
self.fq_names.register(
self.table.fq_names.register(
fq_module,
NameSpec {
location,
@ -483,10 +495,10 @@ impl SymbolTable {
location,
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);
} 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() {
let tag = index as u32;
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 {
VariantKind::UnitStruct => {
@ -547,7 +559,7 @@ impl SymbolTable {
.map(|(member_name, _type_identifier)| {
(
member_name.clone(),
TypeId::lookup_name("DUMMY_TYPE_ID"),
self.type_context.id_from_name("DUMMY_TYPE_ID")
)
})
.collect(),

View File

@ -6,7 +6,8 @@ use assert_matches::assert_matches;
fn add_symbols(src: &str) -> (SymbolTable, Result<(), Vec<SymbolError>>) {
let ast = quick_ast(src);
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)
}

View File

@ -10,9 +10,9 @@ use crate::{
fn evaluate_input(input: &str) -> Result<String, String> {
let ast = crate::util::quick_ast(input);
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);
reduced_ir.debug(&symbol_table);

View File

@ -13,11 +13,6 @@ impl fmt::Display for 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 {
self.local_name.as_ref()
}
@ -29,6 +24,11 @@ impl TypeContext {
pub fn new() -> 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)]