More symbol-table refactoring

This commit is contained in:
greg 2019-01-20 22:13:05 -08:00
parent 10c3a60515
commit 1ce06bc0ef

View File

@ -4,7 +4,7 @@ use std::fmt;
use std::fmt::Write; use std::fmt::Write;
use crate::ast; use crate::ast;
use crate::ast::Signature; use crate::ast::{TypeBody, TypeSingletonName, Signature};
use crate::typechecking::TypeName; use crate::typechecking::TypeName;
//cf. p. 150 or so of Language Implementation Patterns //cf. p. 150 or so of Language Implementation Patterns
@ -60,15 +60,47 @@ impl SymbolTable {
/* 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 */
pub fn add_top_level_symbols(&mut self, ast: &ast::AST) -> Result<(), String> { pub fn add_top_level_symbols(&mut self, ast: &ast::AST) -> Result<(), String> {
use self::ast::{Statement, TypeIdentifier, Variant, TypeSingletonName, TypeBody}; use self::ast::Statement;
use self::ast::Declaration::*; use self::ast::Declaration::*;
for statement in ast.0.iter() { for statement in ast.0.iter() {
let statement = statement.node(); let statement = statement.node();
if let Statement::Declaration(decl) = statement { if let Statement::Declaration(decl) = statement {
match decl { match decl {
FuncSig(signature) | FuncDecl(signature, _) => self.add_function_signature(signature), FuncSig(signature) | FuncDecl(signature, _) => self.add_function_signature(signature)?,
TypeDecl { name, body, mutable } => self.add_type_decl(name, body, mutable)?,
_ => ()
}
}
}
Ok(())
}
pub fn debug_symbol_table(&self) -> String {
let mut output = format!("Symbol table\n");
for (name, sym) in &self.values {
write!(output, "{} -> {}\n", name, sym).unwrap();
}
output
}
fn add_function_signature(&mut self, signature: &Signature) -> Result<(), String> {
let mut local_type_context = LocalTypeContext::new();
let types = signature.params.iter().map(|param| match param {
(_, Some(type_identifier)) => Rc::new(format!("{:?}", type_identifier)),
(_, None) => local_type_context.new_universal_type()
}).collect();
let spec = SymbolSpec::Func(types);
self.values.insert(
signature.name.clone(),
Symbol { name: signature.name.clone(), spec }
);
Ok(())
}
fn add_type_decl(&mut self, type_name: &TypeSingletonName, body: &TypeBody, _mutable: &bool) -> Result<(), String> {
use crate::ast::{TypeIdentifier, Variant};
let TypeBody(variants) = body;
let TypeSingletonName { name, .. } = type_name;
//TODO figure out why _params isn't being used here //TODO figure out why _params isn't being used here
TypeDecl { name: TypeSingletonName { name, params: _params}, body: TypeBody(variants), mutable: _mutable, } => {
for (index, var) in variants.iter().enumerate() { for (index, var) in variants.iter().enumerate() {
match var { match var {
Variant::UnitStruct(variant_name) => { Variant::UnitStruct(variant_name) => {
@ -92,36 +124,11 @@ impl SymbolTable {
let symbol = Symbol { name: variant_name.clone(), spec }; let symbol = Symbol { name: variant_name.clone(), spec };
self.values.insert(variant_name.clone(), symbol); self.values.insert(variant_name.clone(), symbol);
}, },
e => return Err(format!("{:?} not supported in typing yet", e)), Variant::Record { .. } => return Err(format!("Record types not supported yet")),
}
}
},
_ => ()
}
} }
} }
Ok(()) Ok(())
} }
pub fn debug_symbol_table(&self) -> String {
let mut output = format!("Symbol table\n");
for (name, sym) in &self.values {
write!(output, "{} -> {}\n", name, sym).unwrap();
}
output
}
fn add_function_signature(&mut self, signature: &Signature) {
let mut local_type_context = LocalTypeContext::new();
let types = signature.params.iter().map(|param| match param {
(_, Some(type_identifier)) => Rc::new(format!("{:?}", type_identifier)),
(_, None) => local_type_context.new_universal_type()
}).collect();
let spec = SymbolSpec::Func(types);
self.values.insert(
signature.name.clone(),
Symbol { name: signature.name.clone(), spec }
);
}
} }
struct LocalTypeContext { struct LocalTypeContext {