hm-inference #6

Merged
sb10q merged 136 commits from hm-inference into master 2021-08-19 11:46:50 +08:00
6 changed files with 28 additions and 26 deletions
Showing only changes of commit 18db2ddd53 - Show all commits

View File

@ -13,7 +13,7 @@ impl<'ctx> CodeGenContext<'ctx> {
// we cannot have other types, virtual type should be handled by function calls // we cannot have other types, virtual type should be handled by function calls
_ => unreachable!(), _ => unreachable!(),
}; };
let def = &self.top_level.definitions.read()[obj_id]; let def = &self.top_level.definitions.read()[obj_id.0];
let index = if let TopLevelDef::Class { fields, .. } = &*def.read() { let index = if let TopLevelDef::Class { fields, .. } = &*def.read() {
fields.iter().find_position(|x| x.0 == attr).unwrap().0 fields.iter().find_position(|x| x.0 == attr).unwrap().0
} else { } else {
@ -137,7 +137,7 @@ impl<'ctx> CodeGenContext<'ctx> {
let primitives = &self.top_level.primitives; let primitives = &self.top_level.primitives;
match &expr.node { match &expr.node {
ExprKind::Constant { value, .. } => { ExprKind::Constant { value, .. } => {
let ty = expr.custom.clone().unwrap(); let ty = expr.custom.unwrap();
self.gen_const(value, ty) self.gen_const(value, ty)
} }
ExprKind::Name { id, .. } => { ExprKind::Name { id, .. } => {

View File

@ -7,12 +7,13 @@ use inkwell::{builder::Builder, context::Context, module::Module, values::Pointe
use parking_lot::RwLock; use parking_lot::RwLock;
use rustpython_parser::ast::Stmt; use rustpython_parser::ast::Stmt;
pub struct DefinitionId(usize); #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
pub struct DefinitionId(pub usize);
pub enum TopLevelDef { pub enum TopLevelDef {
Class { Class {
// object ID used for TypeEnum // object ID used for TypeEnum
object_id: usize, object_id: DefinitionId,
// type variables bounded to the class. // type variables bounded to the class.
type_vars: Vec<Type>, type_vars: Vec<Type>,
// class fields and method signature. // class fields and method signature.

View File

@ -61,7 +61,7 @@ pub fn comparison_name(op: &Cmpop) -> Option<&'static str> {
} }
} }
pub fn impl_binop(unifier: &mut Unifier, store: &PrimitiveStore, ty: Type, other_ty: &[Type], ret_ty: Type, ops: &[ast::Operator]) { pub fn impl_binop(unifier: &mut Unifier, _store: &PrimitiveStore, ty: Type, other_ty: &[Type], ret_ty: Type, ops: &[ast::Operator]) {
if let TypeEnum::TObj {fields, ..} = unifier.get_ty(ty).borrow() { if let TypeEnum::TObj {fields, ..} = unifier.get_ty(ty).borrow() {
for op in ops { for op in ops {
fields.borrow_mut().insert( fields.borrow_mut().insert(

View File

@ -55,27 +55,27 @@ impl TestEnvironment {
let mut unifier = Unifier::new(); let mut unifier = Unifier::new();
let int32 = unifier.add_ty(TypeEnum::TObj { let int32 = unifier.add_ty(TypeEnum::TObj {
obj_id: 0, obj_id: DefinitionId(0),
fields: HashMap::new().into(), fields: HashMap::new().into(),
params: HashMap::new(), params: HashMap::new(),
}); });
let int64 = unifier.add_ty(TypeEnum::TObj { let int64 = unifier.add_ty(TypeEnum::TObj {
obj_id: 1, obj_id: DefinitionId(1),
fields: HashMap::new().into(), fields: HashMap::new().into(),
params: HashMap::new(), params: HashMap::new(),
}); });
let float = unifier.add_ty(TypeEnum::TObj { let float = unifier.add_ty(TypeEnum::TObj {
obj_id: 2, obj_id: DefinitionId(2),
fields: HashMap::new().into(), fields: HashMap::new().into(),
params: HashMap::new(), params: HashMap::new(),
}); });
let bool = unifier.add_ty(TypeEnum::TObj { let bool = unifier.add_ty(TypeEnum::TObj {
obj_id: 3, obj_id: DefinitionId(3),
fields: HashMap::new().into(), fields: HashMap::new().into(),
params: HashMap::new(), params: HashMap::new(),
}); });
let none = unifier.add_ty(TypeEnum::TObj { let none = unifier.add_ty(TypeEnum::TObj {
obj_id: 4, obj_id: DefinitionId(4),
fields: HashMap::new().into(), fields: HashMap::new().into(),
params: HashMap::new(), params: HashMap::new(),
}); });
@ -120,27 +120,27 @@ impl TestEnvironment {
let mut unifier = Unifier::new(); let mut unifier = Unifier::new();
let mut identifier_mapping = HashMap::new(); let mut identifier_mapping = HashMap::new();
let int32 = unifier.add_ty(TypeEnum::TObj { let int32 = unifier.add_ty(TypeEnum::TObj {
obj_id: 0, obj_id: DefinitionId(0),
fields: HashMap::new().into(), fields: HashMap::new().into(),
params: HashMap::new(), params: HashMap::new(),
}); });
let int64 = unifier.add_ty(TypeEnum::TObj { let int64 = unifier.add_ty(TypeEnum::TObj {
obj_id: 1, obj_id: DefinitionId(1),
fields: HashMap::new().into(), fields: HashMap::new().into(),
params: HashMap::new(), params: HashMap::new(),
}); });
let float = unifier.add_ty(TypeEnum::TObj { let float = unifier.add_ty(TypeEnum::TObj {
obj_id: 2, obj_id: DefinitionId(2),
fields: HashMap::new().into(), fields: HashMap::new().into(),
params: HashMap::new(), params: HashMap::new(),
}); });
let bool = unifier.add_ty(TypeEnum::TObj { let bool = unifier.add_ty(TypeEnum::TObj {
obj_id: 3, obj_id: DefinitionId(3),
fields: HashMap::new().into(), fields: HashMap::new().into(),
params: HashMap::new(), params: HashMap::new(),
}); });
let none = unifier.add_ty(TypeEnum::TObj { let none = unifier.add_ty(TypeEnum::TObj {
obj_id: 4, obj_id: DefinitionId(4),
fields: HashMap::new().into(), fields: HashMap::new().into(),
params: HashMap::new(), params: HashMap::new(),
}); });
@ -151,7 +151,7 @@ impl TestEnvironment {
let (v0, id) = unifier.get_fresh_var(); let (v0, id) = unifier.get_fresh_var();
let foo_ty = unifier.add_ty(TypeEnum::TObj { let foo_ty = unifier.add_ty(TypeEnum::TObj {
obj_id: 5, obj_id: DefinitionId(5),
fields: [("a".into(), v0)].iter().cloned().collect::<HashMap<_, _>>().into(), fields: [("a".into(), v0)].iter().cloned().collect::<HashMap<_, _>>().into(),
params: [(id, v0)].iter().cloned().collect(), params: [(id, v0)].iter().cloned().collect(),
}); });
@ -171,7 +171,7 @@ impl TestEnvironment {
vars: Default::default(), vars: Default::default(),
})); }));
let bar = unifier.add_ty(TypeEnum::TObj { let bar = unifier.add_ty(TypeEnum::TObj {
obj_id: 6, obj_id: DefinitionId(6),
fields: [("a".into(), int32), ("b".into(), fun)] fields: [("a".into(), int32), ("b".into(), fun)]
.iter() .iter()
.cloned() .cloned()
@ -189,7 +189,7 @@ impl TestEnvironment {
); );
let bar2 = unifier.add_ty(TypeEnum::TObj { let bar2 = unifier.add_ty(TypeEnum::TObj {
obj_id: 7, obj_id: DefinitionId(7),
fields: [("a".into(), bool), ("b".into(), fun)] fields: [("a".into(), bool), ("b".into(), fun)]
.iter() .iter()
.cloned() .cloned()

View File

@ -6,6 +6,7 @@ use std::iter::once;
use std::rc::Rc; use std::rc::Rc;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use crate::top_level::DefinitionId;
use super::unification_table::{UnificationKey, UnificationTable}; use super::unification_table::{UnificationKey, UnificationTable};
#[cfg(test)] #[cfg(test)]
@ -64,7 +65,7 @@ pub enum TypeEnum {
ty: Type, ty: Type,
}, },
TObj { TObj {
obj_id: usize, obj_id: DefinitionId,
fields: RefCell<Mapping<String>>, fields: RefCell<Mapping<String>>,
params: VarMap, params: VarMap,
}, },
@ -433,7 +434,7 @@ impl Unifier {
TObj { obj_id: id2, params: params2, .. }, TObj { obj_id: id2, params: params2, .. },
) => { ) => {
if id1 != id2 { if id1 != id2 {
return Err(format!("Cannot unify objects with ID {} and {}", id1, id2)); return Err(format!("Cannot unify objects with ID {} and {}", id1.0, id2.0));
} }
for (x, y) in zip(params1.values(), params2.values()) { for (x, y) in zip(params1.values(), params2.values()) {
self.unify(*x, *y)?; self.unify(*x, *y)?;
@ -570,7 +571,7 @@ impl Unifier {
format!("virtual[{}]", self.stringify(*ty, obj_to_name, var_to_name)) format!("virtual[{}]", self.stringify(*ty, obj_to_name, var_to_name))
} }
TypeEnum::TObj { obj_id, params, .. } => { TypeEnum::TObj { obj_id, params, .. } => {
let name = obj_to_name(*obj_id); let name = obj_to_name(obj_id.0);
if !params.is_empty() { if !params.is_empty() {
let mut params = let mut params =
params.values().map(|v| self.stringify(*v, obj_to_name, var_to_name)); params.values().map(|v| self.stringify(*v, obj_to_name, var_to_name));

View File

@ -78,7 +78,7 @@ impl TestEnvironment {
type_mapping.insert( type_mapping.insert(
"int".into(), "int".into(),
unifier.add_ty(TypeEnum::TObj { unifier.add_ty(TypeEnum::TObj {
obj_id: 0, obj_id: DefinitionId(0),
fields: HashMap::new().into(), fields: HashMap::new().into(),
params: HashMap::new(), params: HashMap::new(),
}), }),
@ -86,7 +86,7 @@ impl TestEnvironment {
type_mapping.insert( type_mapping.insert(
"float".into(), "float".into(),
unifier.add_ty(TypeEnum::TObj { unifier.add_ty(TypeEnum::TObj {
obj_id: 1, obj_id: DefinitionId(1),
fields: HashMap::new().into(), fields: HashMap::new().into(),
params: HashMap::new(), params: HashMap::new(),
}), }),
@ -94,7 +94,7 @@ impl TestEnvironment {
type_mapping.insert( type_mapping.insert(
"bool".into(), "bool".into(),
unifier.add_ty(TypeEnum::TObj { unifier.add_ty(TypeEnum::TObj {
obj_id: 2, obj_id: DefinitionId(2),
fields: HashMap::new().into(), fields: HashMap::new().into(),
params: HashMap::new(), params: HashMap::new(),
}), }),
@ -103,7 +103,7 @@ impl TestEnvironment {
type_mapping.insert( type_mapping.insert(
"Foo".into(), "Foo".into(),
unifier.add_ty(TypeEnum::TObj { unifier.add_ty(TypeEnum::TObj {
obj_id: 3, obj_id: DefinitionId(3),
fields: [("a".into(), v0)].iter().cloned().collect::<HashMap<_, _>>().into(), fields: [("a".into(), v0)].iter().cloned().collect::<HashMap<_, _>>().into(),
params: [(id, v0)].iter().cloned().collect(), params: [(id, v0)].iter().cloned().collect(),
}), }),
@ -334,7 +334,7 @@ fn test_virtual() {
vars: HashMap::new(), vars: HashMap::new(),
})); }));
let bar = env.unifier.add_ty(TypeEnum::TObj { let bar = env.unifier.add_ty(TypeEnum::TObj {
obj_id: 5, obj_id: DefinitionId(5),
fields: [("f".to_string(), fun), ("a".to_string(), int)] fields: [("f".to_string(), fun), ("a".to_string(), int)]
.iter() .iter()
.cloned() .cloned()