From 422b92f6866935ce5b8f9ae12bf6dc06572b07a2 Mon Sep 17 00:00:00 2001 From: pca006132 Date: Mon, 28 Dec 2020 16:26:10 +0800 Subject: [PATCH] use slice for function parameters --- nac3type/src/inference.rs | 130 +++++++++++++++++++++++++------------ nac3type/src/primitives.rs | 34 ++-------- nac3type/src/types.rs | 2 +- 3 files changed, 96 insertions(+), 70 deletions(-) diff --git a/nac3type/src/inference.rs b/nac3type/src/inference.rs index 87d4da8875..28ef48b518 100644 --- a/nac3type/src/inference.rs +++ b/nac3type/src/inference.rs @@ -116,7 +116,7 @@ pub fn resolve_call( ctx: &GlobalContext, obj: Option>, func: &str, - args: Rc, + args: &[Rc], assumptions: &mut HashMap>, ) -> Result>, 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()) diff --git a/nac3type/src/primitives.rs b/nac3type/src/primitives.rs index 4159b3aecd..d4593207a7 100644 --- a/nac3type/src/primitives.rs +++ b/nac3type/src/primitives.rs @@ -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) { - 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) { 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) { } fn impl_bits(def: &mut TypeDef, ty: &Rc) { - 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) { 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) { - 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) { } fn impl_order(def: &mut TypeDef, ty: &Rc) { - 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) { def.methods.insert("__ge__", fun.clone()); } -pub fn create_tuple(tys: Vec>) -> Rc { - 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 { diff --git a/nac3type/src/types.rs b/nac3type/src/types.rs index 586507d8ca..d2517deb99 100644 --- a/nac3type/src/types.rs +++ b/nac3type/src/types.rs @@ -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, + pub args: Vec>, pub result: Option>, }