Store constant state, func/binding as value

on symbol table, instead of key
This commit is contained in:
greg 2017-10-09 02:38:33 -07:00
parent 996f75e15c
commit ed8359bcd7

View File

@ -6,12 +6,16 @@ use schala_lang::parsing::{AST, Statement, Declaration, Signature, Expression, E
#[derive(Debug, PartialEq, Eq, Hash)] #[derive(Debug, PartialEq, Eq, Hash)]
struct PathSpecifier { struct PathSpecifier {
name: Rc<String>, name: Rc<String>,
kind: &'static str, }
constant: bool,
#[derive(Debug, PartialEq, Clone)]
struct TypeContextEntry {
type_var: TypeVariable,
constant: bool
} }
pub struct TypeContext { pub struct TypeContext {
symbol_table: HashMap<PathSpecifier, TypeVariable>, symbol_table: HashMap<PathSpecifier, TypeContextEntry>,
existential_type_label_count: u64 existential_type_label_count: u64
} }
@ -37,40 +41,33 @@ impl TypeContext {
Binding {ref name, ref constant, ref expr} => { Binding {ref name, ref constant, ref expr} => {
let spec = PathSpecifier { let spec = PathSpecifier {
name: name.clone(), name: name.clone(),
kind: "binding",
constant: *constant
}; };
let binding_contents = expr.1.as_ref() let type_var = expr.1.as_ref()
.map(|ty| self.from_anno(ty)) .map(|ty| self.from_anno(ty))
.unwrap_or_else(|| { self.get_existential_type() }); .unwrap_or_else(|| { self.get_existential_type() });
self.symbol_table.insert(spec, binding_contents); let entry = TypeContextEntry { type_var, constant: *constant };
self.symbol_table.insert(spec, entry);
}, },
FuncDecl(ref signature, _) => { FuncDecl(ref signature, _) => {
let spec = PathSpecifier { let spec = PathSpecifier {
name: signature.name.clone(), name: signature.name.clone(),
kind: "binding",
constant: true
}; };
let func_type = self.from_signature(signature); let type_var = self.from_signature(signature);
self.symbol_table.insert(spec, func_type); let entry = TypeContextEntry { type_var, constant: true };
self.symbol_table.insert(spec, entry);
}, },
} }
} }
} }
} }
} }
fn lookup(&mut self, binding: &Rc<String>) -> Option<TypeVariable> { fn lookup(&mut self, binding: &Rc<String>) -> Option<TypeContextEntry> {
use self::TypeVariable::*;
use self::UVar::*;
let key = PathSpecifier { let key = PathSpecifier {
name: binding.clone(), name: binding.clone(),
kind: "binding",
constant: true
}; };
self.symbol_table.get(&key).map(|x| x.clone()) self.symbol_table.get(&key).map(|entry| entry.clone())
} }
pub fn debug_symbol_table(&self) -> String { pub fn debug_symbol_table(&self) -> String {
format!("Symbol table:\n {:?}", self.symbol_table) format!("Symbol table:\n {:?}", self.symbol_table)
@ -175,7 +172,7 @@ impl TypeContext {
}, },
(&IntLiteral(_), _) => Univ(UVar::Integer), (&IntLiteral(_), _) => Univ(UVar::Integer),
(&BoolLiteral(_), _) => Univ(UVar::Boolean), (&BoolLiteral(_), _) => Univ(UVar::Boolean),
(&Variable(ref name), _) => self.lookup(name) (&Variable(ref name), _) => self.lookup(name).map(|entry| entry.type_var)
.ok_or(format!("Couldn't find {}", name))?, .ok_or(format!("Couldn't find {}", name))?,
(&Call { ref f, ref arguments }, _) => { (&Call { ref f, ref arguments }, _) => {
let f_type = self.infer(&*f)?; let f_type = self.infer(&*f)?;