Make use of TypeContext in SymbolTable
This commit is contained in:
parent
40be5a8a33
commit
765a0bec58
@ -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#"
|
||||
|
@ -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
|
||||
|
@ -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(),
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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)]
|
||||
|
Loading…
Reference in New Issue
Block a user