Store constant state, func/binding as value
on symbol table, instead of key
This commit is contained in:
parent
996f75e15c
commit
ed8359bcd7
@ -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)?;
|
||||||
|
Loading…
Reference in New Issue
Block a user