forked from M-Labs/nac3
inference and tests
This commit is contained in:
parent
7f09596bcb
commit
929b7e1d92
@ -169,3 +169,208 @@ pub fn resolve_call(
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::primitives::*;
|
||||
|
||||
#[test]
|
||||
fn test_simple_generic() {
|
||||
let mut ctx = basic_ctx();
|
||||
let mut assumptions = HashMap::new();
|
||||
|
||||
assert_eq!(
|
||||
resolve_call(
|
||||
&ctx,
|
||||
None,
|
||||
"int32",
|
||||
create_tuple(vec![PrimitiveType(FLOAT_TYPE).into()]),
|
||||
&mut assumptions
|
||||
),
|
||||
Ok(Some(PrimitiveType(INT32_TYPE).into()))
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
resolve_call(
|
||||
&ctx,
|
||||
None,
|
||||
"int32",
|
||||
create_tuple(vec![PrimitiveType(INT32_TYPE).into()]),
|
||||
&mut assumptions
|
||||
),
|
||||
Ok(Some(PrimitiveType(INT32_TYPE).into()))
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
resolve_call(
|
||||
&ctx,
|
||||
None,
|
||||
"float",
|
||||
create_tuple(vec![PrimitiveType(INT32_TYPE).into()]),
|
||||
&mut assumptions
|
||||
),
|
||||
Ok(Some(PrimitiveType(FLOAT_TYPE).into()))
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
resolve_call(
|
||||
&ctx,
|
||||
None,
|
||||
"float",
|
||||
create_tuple(vec![PrimitiveType(BOOL_TYPE).into()]),
|
||||
&mut assumptions
|
||||
),
|
||||
Err("different domain".to_string())
|
||||
);
|
||||
|
||||
let v1 = ctx.add_variable(VarDef {
|
||||
name: "V1",
|
||||
bound: vec![
|
||||
PrimitiveType(INT32_TYPE).into(),
|
||||
PrimitiveType(FLOAT_TYPE).into(),
|
||||
],
|
||||
});
|
||||
|
||||
assert_eq!(
|
||||
resolve_call(
|
||||
&ctx,
|
||||
None,
|
||||
"float",
|
||||
create_tuple(vec![TypeVariable(v1).into()]),
|
||||
&mut assumptions
|
||||
),
|
||||
Ok(Some(PrimitiveType(FLOAT_TYPE).into()))
|
||||
);
|
||||
|
||||
let v2 = ctx.add_variable(VarDef {
|
||||
name: "V2",
|
||||
bound: vec![
|
||||
PrimitiveType(BOOL_TYPE).into(),
|
||||
PrimitiveType(INT32_TYPE).into(),
|
||||
PrimitiveType(FLOAT_TYPE).into(),
|
||||
],
|
||||
});
|
||||
|
||||
assert_eq!(
|
||||
resolve_call(
|
||||
&ctx,
|
||||
None,
|
||||
"float",
|
||||
create_tuple(vec![TypeVariable(v2).into()]),
|
||||
&mut assumptions
|
||||
),
|
||||
Err("different domain".to_string())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_methods() {
|
||||
let mut ctx = basic_ctx();
|
||||
let mut assumptions = HashMap::new();
|
||||
|
||||
let v1 = Rc::new(TypeVariable(ctx.add_variable(VarDef {
|
||||
name: "V1",
|
||||
bound: vec![
|
||||
PrimitiveType(INT32_TYPE).into(),
|
||||
PrimitiveType(FLOAT_TYPE).into(),
|
||||
],
|
||||
})));
|
||||
let v2 = Rc::new(TypeVariable(ctx.add_variable(VarDef {
|
||||
name: "V2",
|
||||
bound: vec![
|
||||
PrimitiveType(INT32_TYPE).into(),
|
||||
PrimitiveType(FLOAT_TYPE).into(),
|
||||
],
|
||||
})));
|
||||
let v3 = Rc::new(TypeVariable(ctx.add_variable(VarDef {
|
||||
name: "V3",
|
||||
bound: vec![
|
||||
PrimitiveType(BOOL_TYPE).into(),
|
||||
PrimitiveType(INT32_TYPE).into(),
|
||||
PrimitiveType(FLOAT_TYPE).into(),
|
||||
],
|
||||
})));
|
||||
|
||||
let int32 = Rc::new(PrimitiveType(INT32_TYPE));
|
||||
let int64 = Rc::new(PrimitiveType(INT64_TYPE));
|
||||
|
||||
// simple cases
|
||||
assert_eq!(
|
||||
resolve_call(
|
||||
&ctx,
|
||||
Some(int32.clone()),
|
||||
"__add__",
|
||||
create_tuple(vec![int32.clone()]),
|
||||
&mut assumptions
|
||||
),
|
||||
Ok(Some(int32.clone()))
|
||||
);
|
||||
|
||||
assert_ne!(
|
||||
resolve_call(
|
||||
&ctx,
|
||||
Some(int32.clone()),
|
||||
"__add__",
|
||||
create_tuple(vec![int32.clone()]),
|
||||
&mut assumptions
|
||||
),
|
||||
Ok(Some(int64.clone()))
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
resolve_call(
|
||||
&ctx,
|
||||
Some(int32.clone()),
|
||||
"__add__",
|
||||
create_tuple(vec![int64.clone()]),
|
||||
&mut assumptions
|
||||
),
|
||||
Err("not equal".to_string())
|
||||
);
|
||||
|
||||
// with type variables
|
||||
assert_eq!(
|
||||
resolve_call(
|
||||
&ctx,
|
||||
Some(v1.clone()),
|
||||
"__add__",
|
||||
create_tuple(vec![v1.clone()]),
|
||||
&mut assumptions
|
||||
),
|
||||
Ok(Some(v1.clone()))
|
||||
);
|
||||
assert_eq!(
|
||||
resolve_call(
|
||||
&ctx,
|
||||
Some(v1.clone()),
|
||||
"__add__",
|
||||
create_tuple(vec![v2.clone()]),
|
||||
&mut assumptions
|
||||
),
|
||||
Err("different domain".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
resolve_call(
|
||||
&ctx,
|
||||
Some(v3.clone()),
|
||||
"__add__",
|
||||
create_tuple(vec![v1.clone()]),
|
||||
&mut assumptions
|
||||
),
|
||||
Err("no such function".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
resolve_call(
|
||||
&ctx,
|
||||
Some(v3.clone()),
|
||||
"__add__",
|
||||
create_tuple(vec![v3.clone()]),
|
||||
&mut assumptions
|
||||
),
|
||||
Err("no such function".to_string())
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
extern crate rustpython_parser;
|
||||
|
||||
mod types;
|
||||
mod inference;
|
||||
mod primitives;
|
||||
pub mod types;
|
||||
pub mod inference;
|
||||
pub mod primitives;
|
||||
|
||||
|
@ -13,7 +13,7 @@ pub const FLOAT_TYPE: PrimitiveId = PrimitiveId(3);
|
||||
fn impl_math(def: &mut TypeDef, ty: &Rc<Type>) {
|
||||
let bin = Rc::new(ParametricType(
|
||||
TUPLE_TYPE,
|
||||
vec![SelfType.into(), ty.clone()],
|
||||
vec![ty.clone()],
|
||||
));
|
||||
let result = Some(ty.clone());
|
||||
let fun = FnDef {
|
||||
@ -39,7 +39,7 @@ fn impl_math(def: &mut TypeDef, ty: &Rc<Type>) {
|
||||
fn impl_bits(def: &mut TypeDef, ty: &Rc<Type>) {
|
||||
let bin = Rc::new(ParametricType(
|
||||
TUPLE_TYPE,
|
||||
vec![SelfType.into(), PrimitiveType(INT32_TYPE).into()],
|
||||
vec![PrimitiveType(INT32_TYPE).into()],
|
||||
));
|
||||
let result = Some(ty.clone());
|
||||
let fun = FnDef {
|
||||
@ -52,7 +52,7 @@ fn impl_bits(def: &mut TypeDef, ty: &Rc<Type>) {
|
||||
def.methods.insert(
|
||||
"__xor__",
|
||||
FnDef {
|
||||
args: ParametricType(TUPLE_TYPE, vec![SelfType.into(), ty.clone()]).into(),
|
||||
args: ParametricType(TUPLE_TYPE, vec![ty.clone()]).into(),
|
||||
result: Some(ty.clone()),
|
||||
},
|
||||
);
|
||||
@ -61,7 +61,7 @@ fn impl_bits(def: &mut TypeDef, ty: &Rc<Type>) {
|
||||
fn impl_eq(def: &mut TypeDef, ty: &Rc<Type>) {
|
||||
let bin = Rc::new(ParametricType(
|
||||
TUPLE_TYPE,
|
||||
vec![SelfType.into(), ty.clone()],
|
||||
vec![ty.clone()],
|
||||
));
|
||||
let fun = FnDef {
|
||||
args: bin.clone(),
|
||||
@ -75,7 +75,7 @@ fn impl_eq(def: &mut TypeDef, ty: &Rc<Type>) {
|
||||
fn impl_order(def: &mut TypeDef, ty: &Rc<Type>) {
|
||||
let bin = Rc::new(ParametricType(
|
||||
TUPLE_TYPE,
|
||||
vec![SelfType.into(), ty.clone()],
|
||||
vec![ty.clone()],
|
||||
));
|
||||
let fun = FnDef {
|
||||
args: bin.clone(),
|
||||
@ -88,6 +88,10 @@ fn impl_order(def: &mut TypeDef, ty: &Rc<Type>) {
|
||||
def.methods.insert("__ge__", fun.clone());
|
||||
}
|
||||
|
||||
pub fn create_tuple(tys: Vec<Rc<Type>>) -> Rc<Type> {
|
||||
ParametricType(TUPLE_TYPE, tys).into()
|
||||
}
|
||||
|
||||
pub fn basic_ctx() -> GlobalContext<'static> {
|
||||
let primitives = [
|
||||
TypeDef {
|
||||
|
@ -26,6 +26,8 @@ pub enum Type {
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct FnDef {
|
||||
// we assume methods first argument to be SelfType,
|
||||
// so the first argument is not contained here
|
||||
pub args: Rc<Type>,
|
||||
pub result: Option<Rc<Type>>,
|
||||
}
|
||||
@ -209,3 +211,4 @@ impl Type {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user