use slice for function parameters

This commit is contained in:
pca006132 2020-12-28 16:26:10 +08:00 committed by pca006132
parent 0200ea1458
commit 422b92f686
3 changed files with 96 additions and 70 deletions

View File

@ -116,7 +116,7 @@ pub fn resolve_call(
ctx: &GlobalContext,
obj: Option<Rc<Type>>,
func: &str,
args: Rc<Type>,
args: &[Rc<Type>],
assumptions: &mut HashMap<VariableId, Rc<Type>>,
) -> Result<Option<Rc<Type>>, String> {
let obj = obj.as_ref().map(|v| Rc::new(v.subst(assumptions)));
@ -167,7 +167,12 @@ pub fn resolve_call(
}
.ok_or("no such function".to_string())?;
find_subst(ctx, assumptions, &mut subst, args, fun.args.clone())?;
if args.len() != fun.args.len() {
return Err("incorrect parameter number".to_string());
}
for (a, b) in args.iter().zip(fun.args.iter()) {
find_subst(ctx, assumptions, &mut subst, a.clone(), b.clone())?;
}
let result = fun.result.as_ref().map(|v| v.subst(&subst));
Ok(result.map(|result| {
if let SelfType = result {
@ -193,7 +198,7 @@ mod tests {
&ctx,
None,
"int32",
create_tuple(vec![PrimitiveType(FLOAT_TYPE).into()]),
&[PrimitiveType(FLOAT_TYPE).into()],
&mut assumptions
),
Ok(Some(PrimitiveType(INT32_TYPE).into()))
@ -204,7 +209,7 @@ mod tests {
&ctx,
None,
"int32",
create_tuple(vec![PrimitiveType(INT32_TYPE).into()]),
&[PrimitiveType(INT32_TYPE).into()],
&mut assumptions
),
Ok(Some(PrimitiveType(INT32_TYPE).into()))
@ -215,7 +220,7 @@ mod tests {
&ctx,
None,
"float",
create_tuple(vec![PrimitiveType(INT32_TYPE).into()]),
&[PrimitiveType(INT32_TYPE).into()],
&mut assumptions
),
Ok(Some(PrimitiveType(FLOAT_TYPE).into()))
@ -226,15 +231,15 @@ mod tests {
&ctx,
None,
"float",
create_tuple(vec![PrimitiveType(BOOL_TYPE).into()]),
&[PrimitiveType(BOOL_TYPE).into()],
&mut assumptions
),
Err("different domain".to_string())
);
assert_eq!(
resolve_call(&ctx, None, "float", create_tuple(vec![]), &mut assumptions),
Err("different parametric types".to_string())
resolve_call(&ctx, None, "float", &[], &mut assumptions),
Err("incorrect parameter number".to_string())
);
let v1 = ctx.add_variable(VarDef {
@ -250,7 +255,7 @@ mod tests {
&ctx,
None,
"float",
create_tuple(vec![TypeVariable(v1).into()]),
&[TypeVariable(v1).into()],
&mut assumptions
),
Ok(Some(PrimitiveType(FLOAT_TYPE).into()))
@ -270,7 +275,7 @@ mod tests {
&ctx,
None,
"float",
create_tuple(vec![TypeVariable(v2).into()]),
&[TypeVariable(v2).into()],
&mut assumptions
),
Err("different domain".to_string())
@ -318,7 +323,7 @@ mod tests {
&ctx,
Some(int32.clone()),
"__add__",
create_tuple(vec![int32.clone()]),
&[int32.clone()],
&mut assumptions
),
Ok(Some(int32.clone()))
@ -329,7 +334,7 @@ mod tests {
&ctx,
Some(int32.clone()),
"__add__",
create_tuple(vec![int32.clone()]),
&[int32.clone()],
&mut assumptions
),
Ok(Some(int64.clone()))
@ -340,7 +345,7 @@ mod tests {
&ctx,
Some(int32.clone()),
"__add__",
create_tuple(vec![int64.clone()]),
&[int64.clone()],
&mut assumptions
),
Err("not equal".to_string())
@ -352,7 +357,7 @@ mod tests {
&ctx,
Some(v1.clone()),
"__add__",
create_tuple(vec![v1.clone()]),
&[v1.clone()],
&mut assumptions
),
Ok(Some(v1.clone()))
@ -362,7 +367,7 @@ mod tests {
&ctx,
Some(v0.clone()),
"__add__",
create_tuple(vec![v2.clone()]),
&[v2.clone()],
&mut assumptions
),
Err("unbounded type var".to_string())
@ -372,7 +377,7 @@ mod tests {
&ctx,
Some(v1.clone()),
"__add__",
create_tuple(vec![v0.clone()]),
&[v0.clone()],
&mut assumptions
),
Err("different domain".to_string())
@ -382,7 +387,7 @@ mod tests {
&ctx,
Some(v1.clone()),
"__add__",
create_tuple(vec![v2.clone()]),
&[v2.clone()],
&mut assumptions
),
Err("different domain".to_string())
@ -392,7 +397,7 @@ mod tests {
&ctx,
Some(v1.clone()),
"__add__",
create_tuple(vec![v3.clone()]),
&[v3.clone()],
&mut assumptions
),
Err("different domain".to_string())
@ -402,7 +407,7 @@ mod tests {
&ctx,
Some(v3.clone()),
"__add__",
create_tuple(vec![v1.clone()]),
&[v1.clone()],
&mut assumptions
),
Err("no such function".to_string())
@ -412,7 +417,7 @@ mod tests {
&ctx,
Some(v3.clone()),
"__add__",
create_tuple(vec![v3.clone()]),
&[v3.clone()],
&mut assumptions
),
Err("no such function".to_string())
@ -443,7 +448,17 @@ mod tests {
ctx.add_fn(
"foo",
FnDef {
args: create_tuple(vec![v0.clone(), v0.clone(), v1.clone()]),
args: vec![v0.clone(), v0.clone(), v1.clone()],
result: Some(v0.clone()),
},
);
ctx.add_fn(
"foo1",
FnDef {
args: vec![
ParametricType(TUPLE_TYPE, vec![v0.clone(), v0.clone(), v1.clone()]).into(),
],
result: Some(v0.clone()),
},
);
@ -453,7 +468,7 @@ mod tests {
&ctx,
None,
"foo",
create_tuple(vec![v2.clone(), v2.clone(), v2.clone()]),
&[v2.clone(), v2.clone(), v2.clone()],
&mut assumptions
),
Ok(Some(v2.clone()))
@ -463,7 +478,7 @@ mod tests {
&ctx,
None,
"foo",
create_tuple(vec![v2.clone(), v2.clone(), v3.clone()]),
&[v2.clone(), v2.clone(), v3.clone()],
&mut assumptions
),
Ok(Some(v2.clone()))
@ -473,7 +488,38 @@ mod tests {
&ctx,
None,
"foo",
create_tuple(vec![v2.clone(), v3.clone(), v3.clone()]),
&[v2.clone(), v3.clone(), v3.clone()],
&mut assumptions
),
Err("different variables".to_string())
);
assert_eq!(
resolve_call(
&ctx,
None,
"foo1",
&[ParametricType(TUPLE_TYPE, vec![v2.clone(), v2.clone(), v2.clone()]).into()],
&mut assumptions
),
Ok(Some(v2.clone()))
);
assert_eq!(
resolve_call(
&ctx,
None,
"foo1",
&[ParametricType(TUPLE_TYPE, vec![v2.clone(), v2.clone(), v3.clone()]).into()],
&mut assumptions
),
Ok(Some(v2.clone()))
);
assert_eq!(
resolve_call(
&ctx,
None,
"foo1",
&[ParametricType(TUPLE_TYPE, vec![v2.clone(), v3.clone(), v3.clone()]).into()],
&mut assumptions
),
Err("different variables".to_string())
@ -490,14 +536,14 @@ mod tests {
list.base.methods.insert(
"head",
FnDef {
args: create_tuple(vec![]),
args: vec![],
result: Some(t.clone()),
},
);
list.base.methods.insert(
"append",
FnDef {
args: create_tuple(vec![t.clone()]),
args: vec![t.clone()],
result: None,
},
);
@ -516,7 +562,7 @@ mod tests {
&ctx,
Some(ParametricType(LIST_TYPE, vec![v0.clone()]).into()),
"head",
create_tuple(vec![]),
&[],
&mut assumptions
),
Ok(Some(v0.clone()))
@ -526,7 +572,7 @@ mod tests {
&ctx,
Some(ParametricType(LIST_TYPE, vec![v0.clone()]).into()),
"append",
create_tuple(vec![v0.clone()]),
&[v0.clone()],
&mut assumptions
),
Ok(None)
@ -536,7 +582,7 @@ mod tests {
&ctx,
Some(ParametricType(LIST_TYPE, vec![v0.clone()]).into()),
"append",
create_tuple(vec![v1.clone()]),
&[v1.clone()],
&mut assumptions
),
Err("different variables".to_string())
@ -587,14 +633,14 @@ mod tests {
ctx.add_fn(
"foo",
FnDef {
args: create_tuple(vec![VirtualClassType(foo).into()]),
args: vec![VirtualClassType(foo).into()],
result: None,
},
);
ctx.add_fn(
"foo1",
FnDef {
args: create_tuple(vec![VirtualClassType(foo1).into()]),
args: vec![VirtualClassType(foo1).into()],
result: None,
},
);
@ -604,7 +650,7 @@ mod tests {
&ctx,
None,
"foo",
create_tuple(vec![ClassType(foo).into()]),
&[ClassType(foo).into()],
&mut assumptions
),
Ok(None)
@ -615,7 +661,7 @@ mod tests {
&ctx,
None,
"foo",
create_tuple(vec![ClassType(foo1).into()]),
&[ClassType(foo1).into()],
&mut assumptions
),
Ok(None)
@ -626,7 +672,7 @@ mod tests {
&ctx,
None,
"foo",
create_tuple(vec![ClassType(foo2).into()]),
&[ClassType(foo2).into()],
&mut assumptions
),
Ok(None)
@ -637,7 +683,7 @@ mod tests {
&ctx,
None,
"foo",
create_tuple(vec![ClassType(bar).into()]),
&[ClassType(bar).into()],
&mut assumptions
),
Err("not subtype".to_string())
@ -648,7 +694,7 @@ mod tests {
&ctx,
None,
"foo1",
create_tuple(vec![ClassType(foo1).into()]),
&[ClassType(foo1).into()],
&mut assumptions
),
Ok(None)
@ -659,7 +705,7 @@ mod tests {
&ctx,
None,
"foo1",
create_tuple(vec![ClassType(foo2).into()]),
&[ClassType(foo2).into()],
&mut assumptions
),
Ok(None)
@ -670,7 +716,7 @@ mod tests {
&ctx,
None,
"foo1",
create_tuple(vec![ClassType(foo).into()]),
&[ClassType(foo).into()],
&mut assumptions
),
Err("not subtype".to_string())
@ -682,7 +728,7 @@ mod tests {
&ctx,
None,
"foo",
create_tuple(vec![VirtualClassType(foo).into()]),
&[VirtualClassType(foo).into()],
&mut assumptions
),
Ok(None)
@ -692,7 +738,7 @@ mod tests {
&ctx,
None,
"foo",
create_tuple(vec![VirtualClassType(foo1).into()]),
&[VirtualClassType(foo1).into()],
&mut assumptions
),
Ok(None)
@ -702,7 +748,7 @@ mod tests {
&ctx,
None,
"foo",
create_tuple(vec![VirtualClassType(foo2).into()]),
&[VirtualClassType(foo2).into()],
&mut assumptions
),
Ok(None)
@ -712,7 +758,7 @@ mod tests {
&ctx,
None,
"foo",
create_tuple(vec![VirtualClassType(bar).into()]),
&[VirtualClassType(bar).into()],
&mut assumptions
),
Err("not subtype".to_string())

View File

@ -11,13 +11,9 @@ pub const INT64_TYPE: PrimitiveId = PrimitiveId(2);
pub const FLOAT_TYPE: PrimitiveId = PrimitiveId(3);
fn impl_math(def: &mut TypeDef, ty: &Rc<Type>) {
let bin = Rc::new(ParametricType(
TUPLE_TYPE,
vec![ty.clone()],
));
let result = Some(ty.clone());
let fun = FnDef {
args: bin.clone(),
args: vec![ty.clone()],
result,
};
def.methods.insert("__add__", fun.clone());
@ -27,7 +23,7 @@ fn impl_math(def: &mut TypeDef, ty: &Rc<Type>) {
def.methods.insert(
"__truediv__",
FnDef {
args: bin.clone(),
args: vec![ty.clone()],
result: Some(PrimitiveType(FLOAT_TYPE).into()),
},
);
@ -37,13 +33,9 @@ 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![PrimitiveType(INT32_TYPE).into()],
));
let result = Some(ty.clone());
let fun = FnDef {
args: bin.clone(),
args: vec![PrimitiveType(INT32_TYPE).into()],
result,
};
@ -52,19 +44,15 @@ fn impl_bits(def: &mut TypeDef, ty: &Rc<Type>) {
def.methods.insert(
"__xor__",
FnDef {
args: ParametricType(TUPLE_TYPE, vec![ty.clone()]).into(),
args: vec![ty.clone()],
result: Some(ty.clone()),
},
);
}
fn impl_eq(def: &mut TypeDef, ty: &Rc<Type>) {
let bin = Rc::new(ParametricType(
TUPLE_TYPE,
vec![ty.clone()],
));
let fun = FnDef {
args: bin.clone(),
args: vec![ty.clone()],
result: Some(PrimitiveType(BOOL_TYPE).into()),
};
@ -73,12 +61,8 @@ 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![ty.clone()],
));
let fun = FnDef {
args: bin.clone(),
args: vec![ty.clone()],
result: Some(PrimitiveType(BOOL_TYPE).into()),
};
@ -88,10 +72,6 @@ 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 {
@ -171,7 +151,7 @@ pub fn basic_ctx() -> GlobalContext<'static> {
PrimitiveType(FLOAT_TYPE).into(),
],
});
let args = Rc::new(ParametricType(TUPLE_TYPE, vec![TypeVariable(i).into()]));
let args = vec![TypeVariable(i).into()];
ctx.add_fn(
"int32",
FnDef {

View File

@ -28,7 +28,7 @@ pub enum Type {
pub struct FnDef {
// we assume methods first argument to be SelfType,
// so the first argument is not contained here
pub args: Rc<Type>,
pub args: Vec<Rc<Type>>,
pub result: Option<Rc<Type>>,
}