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

View File

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