hm-inference #6
|
@ -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, .. } => {
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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()
|
||||||
|
|
Loading…
Reference in New Issue