Make use of TypeContext in SymbolTable
This commit is contained in:
parent
40be5a8a33
commit
765a0bec58
@ -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();
|
||||||
|
|
||||||
let reduced = reduce(&ast, &symbol_table);
|
symbol_table.process_ast(&ast, &mut type_context).unwrap();
|
||||||
reduced.debug(&symbol_table);
|
|
||||||
reduced
|
let reduced = reduce(&ast, &symbol_table);
|
||||||
|
reduced.debug(&symbol_table);
|
||||||
|
reduced
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_ir() {
|
fn test_ir() {
|
||||||
let src = r#"
|
let src = r#"
|
||||||
|
@ -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
|
||||||
|
@ -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(),
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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)]
|
||||||
|
Loading…
Reference in New Issue
Block a user