From cbf79c5e9c2d1c062ecf061edf923478b670b958 Mon Sep 17 00:00:00 2001 From: David Mak Date: Tue, 9 Jul 2024 15:55:11 +0800 Subject: [PATCH] core/typecheck/typedef: Add is_vararg to FuncArg, ConcreteFuncArg --- nac3artiq/src/codegen.rs | 1 + nac3artiq/src/lib.rs | 4 +- nac3core/src/codegen/concrete_type.rs | 3 + nac3core/src/codegen/expr.rs | 15 ++- nac3core/src/codegen/mod.rs | 1 + nac3core/src/codegen/test.rs | 21 +++- nac3core/src/toplevel/builtins.rs | 101 +++++++++++++++--- nac3core/src/toplevel/composer.rs | 10 +- nac3core/src/toplevel/helper.rs | 1 + nac3core/src/typecheck/magic_methods.rs | 2 + nac3core/src/typecheck/type_inferencer/mod.rs | 53 +++++++-- .../src/typecheck/type_inferencer/test.rs | 14 ++- nac3core/src/typecheck/typedef/mod.rs | 1 + 13 files changed, 198 insertions(+), 29 deletions(-) diff --git a/nac3artiq/src/codegen.rs b/nac3artiq/src/codegen.rs index 914798c06..9b0b00d96 100644 --- a/nac3artiq/src/codegen.rs +++ b/nac3artiq/src/codegen.rs @@ -700,6 +700,7 @@ pub fn attributes_writeback( name: i.to_string().into(), ty: *ty, default_value: None, + is_vararg: false, }) .collect(), ret: ctx.primitives.none, diff --git a/nac3artiq/src/lib.rs b/nac3artiq/src/lib.rs index f3eef9fed..32fe0218d 100644 --- a/nac3artiq/src/lib.rs +++ b/nac3artiq/src/lib.rs @@ -265,7 +265,7 @@ impl Nac3 { arg_names.len(), )); } - for (i, FuncArg { ty, default_value, name }) in args.iter().enumerate() { + for (i, FuncArg { ty, default_value, name, .. }) in args.iter().enumerate() { let in_name = match arg_names.get(i) { Some(n) => n, None if default_value.is_none() => { @@ -869,6 +869,7 @@ impl Nac3 { name: "t".into(), ty: primitive.int64, default_value: None, + is_vararg: false, }], ret: primitive.none, vars: VarMap::new(), @@ -888,6 +889,7 @@ impl Nac3 { name: "dt".into(), ty: primitive.int64, default_value: None, + is_vararg: false, }], ret: primitive.none, vars: VarMap::new(), diff --git a/nac3core/src/codegen/concrete_type.rs b/nac3core/src/codegen/concrete_type.rs index 6488ec61b..ff0777757 100644 --- a/nac3core/src/codegen/concrete_type.rs +++ b/nac3core/src/codegen/concrete_type.rs @@ -25,6 +25,7 @@ pub struct ConcreteFuncArg { pub name: StrRef, pub ty: ConcreteType, pub default_value: Option, + pub is_vararg: bool, } #[derive(Clone, Debug)] @@ -104,6 +105,7 @@ impl ConcreteTypeStore { name: arg.name, ty: self.from_unifier_type(unifier, primitives, arg.ty, cache), default_value: arg.default_value.clone(), + is_vararg: arg.is_vararg, }) .collect(), ret: self.from_unifier_type(unifier, primitives, signature.ret, cache), @@ -277,6 +279,7 @@ impl ConcreteTypeStore { name: arg.name, ty: self.to_unifier_type(unifier, primitives, arg.ty, cache), default_value: arg.default_value.clone(), + is_vararg: false, }) .collect(), ret: self.to_unifier_type(unifier, primitives, *ret, cache), diff --git a/nac3core/src/codegen/expr.rs b/nac3core/src/codegen/expr.rs index de9c9f71c..847ddb73f 100644 --- a/nac3core/src/codegen/expr.rs +++ b/nac3core/src/codegen/expr.rs @@ -731,7 +731,15 @@ pub fn gen_func_instance<'ctx>( let zelf = store.from_unifier_type(&mut ctx.unifier, &ctx.primitives, obj.0, &mut cache); let ConcreteTypeEnum::TFunc { args, .. } = &mut signature else { unreachable!() }; - args.insert(0, ConcreteFuncArg { name: "self".into(), ty: zelf, default_value: None }); + args.insert( + 0, + ConcreteFuncArg { + name: "self".into(), + ty: zelf, + default_value: None, + is_vararg: false, + }, + ); } let signature = store.add_cty(signature); @@ -852,7 +860,10 @@ pub fn gen_call<'ctx, G: CodeGenerator>( let fun_val = ctx.module.get_function(&symbol).unwrap_or_else(|| { let mut args = fun.0.args.clone(); if let Some(obj) = &obj { - args.insert(0, FuncArg { name: "self".into(), ty: obj.0, default_value: None }); + args.insert( + 0, + FuncArg { name: "self".into(), ty: obj.0, default_value: None, is_vararg: false }, + ); } let ret_type = if ctx.unifier.unioned(fun.0.ret, ctx.primitives.none) { None diff --git a/nac3core/src/codegen/mod.rs b/nac3core/src/codegen/mod.rs index 2619f5e17..c5d07ca79 100644 --- a/nac3core/src/codegen/mod.rs +++ b/nac3core/src/codegen/mod.rs @@ -718,6 +718,7 @@ pub fn gen_func_impl< name: arg.name, ty: task.store.to_unifier_type(&mut unifier, &primitives, arg.ty, &mut cache), default_value: arg.default_value.clone(), + is_vararg: arg.is_vararg, }) .collect_vec(), task.store.to_unifier_type(&mut unifier, &primitives, *ret, &mut cache), diff --git a/nac3core/src/codegen/test.rs b/nac3core/src/codegen/test.rs index 85e7d2052..8d128ae35 100644 --- a/nac3core/src/codegen/test.rs +++ b/nac3core/src/codegen/test.rs @@ -109,8 +109,18 @@ fn test_primitives() { let threads = vec![DefaultCodeGenerator::new("test".into(), 32).into()]; let signature = FunSignature { args: vec![ - FuncArg { name: "a".into(), ty: primitives.int32, default_value: None }, - FuncArg { name: "b".into(), ty: primitives.int32, default_value: None }, + FuncArg { + name: "a".into(), + ty: primitives.int32, + default_value: None, + is_vararg: false, + }, + FuncArg { + name: "b".into(), + ty: primitives.int32, + default_value: None, + is_vararg: false, + }, ], ret: primitives.int32, vars: VarMap::new(), @@ -255,7 +265,12 @@ fn test_simple_call() { unifier.top_level = Some(top_level.clone()); let signature = FunSignature { - args: vec![FuncArg { name: "a".into(), ty: primitives.int32, default_value: None }], + args: vec![FuncArg { + name: "a".into(), + ty: primitives.int32, + default_value: None, + is_vararg: false, + }], ret: primitives.int32, vars: VarMap::new(), }; diff --git a/nac3core/src/toplevel/builtins.rs b/nac3core/src/toplevel/builtins.rs index a14ade5d8..247031634 100644 --- a/nac3core/src/toplevel/builtins.rs +++ b/nac3core/src/toplevel/builtins.rs @@ -45,10 +45,26 @@ pub fn get_exn_constructor( name: "msg".into(), ty: string, default_value: Some(SymbolValue::Str(String::new())), + is_vararg: false, + }, + FuncArg { + name: "param0".into(), + ty: int64, + default_value: Some(SymbolValue::I64(0)), + is_vararg: false, + }, + FuncArg { + name: "param1".into(), + ty: int64, + default_value: Some(SymbolValue::I64(0)), + is_vararg: false, + }, + FuncArg { + name: "param2".into(), + ty: int64, + default_value: Some(SymbolValue::I64(0)), + is_vararg: false, }, - FuncArg { name: "param0".into(), ty: int64, default_value: Some(SymbolValue::I64(0)) }, - FuncArg { name: "param1".into(), ty: int64, default_value: Some(SymbolValue::I64(0)) }, - FuncArg { name: "param2".into(), ty: int64, default_value: Some(SymbolValue::I64(0)) }, ]; let exn_type = unifier.add_ty(TypeEnum::TObj { obj_id: DefinitionId(class_id), @@ -114,7 +130,12 @@ fn create_fn_by_codegen( signature: unifier.add_ty(TypeEnum::TFunc(FunSignature { args: param_ty .iter() - .map(|p| FuncArg { name: p.1.into(), ty: p.0, default_value: None }) + .map(|p| FuncArg { + name: p.1.into(), + ty: p.0, + default_value: None, + is_vararg: false, + }) .collect(), ret: ret_ty, vars: var_map.clone(), @@ -629,17 +650,24 @@ impl<'a> BuiltinBuilder<'a> { let make_ctor_signature = |unifier: &mut Unifier| { unifier.add_ty(TypeEnum::TFunc(FunSignature { args: vec![ - FuncArg { name: "start".into(), ty: int32, default_value: None }, + FuncArg { + name: "start".into(), + ty: int32, + default_value: None, + is_vararg: false, + }, FuncArg { name: "stop".into(), ty: int32, // placeholder default_value: Some(SymbolValue::I32(0)), + is_vararg: false, }, FuncArg { name: "step".into(), ty: int32, default_value: Some(SymbolValue::I32(1)), + is_vararg: false, }, ], ret: range, @@ -895,6 +923,7 @@ impl<'a> BuiltinBuilder<'a> { name: "n".into(), ty: self.option_tvar.ty, default_value: None, + is_vararg: false, }], ret: self.primitives.option, vars: into_var_map([self.option_tvar]), @@ -1029,6 +1058,7 @@ impl<'a> BuiltinBuilder<'a> { name: "n".into(), ty: self.num_or_ndarray_ty.ty, default_value: None, + is_vararg: false, }], ret: self.num_or_ndarray_ty.ty, vars: self.num_or_ndarray_var_map.clone(), @@ -1248,16 +1278,23 @@ impl<'a> BuiltinBuilder<'a> { simple_name: prim.simple_name().into(), signature: self.unifier.add_ty(TypeEnum::TFunc(FunSignature { args: vec![ - FuncArg { name: "object".into(), ty: tv.ty, default_value: None }, + FuncArg { + name: "object".into(), + ty: tv.ty, + default_value: None, + is_vararg: false, + }, FuncArg { name: "copy".into(), ty: bool, default_value: Some(SymbolValue::Bool(true)), + is_vararg: false, }, FuncArg { name: "ndmin".into(), ty: int32, default_value: Some(SymbolValue::U32(0)), + is_vararg: false, }, ], ret: ndarray, @@ -1299,17 +1336,24 @@ impl<'a> BuiltinBuilder<'a> { simple_name: prim.simple_name().into(), signature: self.unifier.add_ty(TypeEnum::TFunc(FunSignature { args: vec![ - FuncArg { name: "N".into(), ty: int32, default_value: None }, + FuncArg { + name: "N".into(), + ty: int32, + default_value: None, + is_vararg: false, + }, // TODO(Derppening): Default values current do not work? FuncArg { name: "M".into(), ty: int32, default_value: Some(SymbolValue::OptionNone), + is_vararg: false, }, FuncArg { name: "k".into(), ty: int32, default_value: Some(SymbolValue::I32(0)), + is_vararg: false, }, ], ret: self.ndarray_float_2d, @@ -1353,7 +1397,12 @@ impl<'a> BuiltinBuilder<'a> { name: prim.name().into(), simple_name: prim.simple_name().into(), signature: self.unifier.add_ty(TypeEnum::TFunc(FunSignature { - args: vec![FuncArg { name: "s".into(), ty: str, default_value: None }], + args: vec![FuncArg { + name: "s".into(), + ty: str, + default_value: None, + is_vararg: false, + }], ret: str, vars: VarMap::default(), })), @@ -1439,7 +1488,12 @@ impl<'a> BuiltinBuilder<'a> { name: prim.name().into(), simple_name: prim.simple_name().into(), signature: self.unifier.add_ty(TypeEnum::TFunc(FunSignature { - args: vec![FuncArg { name: "ls".into(), ty: arg_ty.ty, default_value: None }], + args: vec![FuncArg { + name: "ls".into(), + ty: arg_ty.ty, + default_value: None, + is_vararg: false, + }], ret: int32, vars: into_var_map([tvar, arg_ty]), })), @@ -1544,8 +1598,18 @@ impl<'a> BuiltinBuilder<'a> { simple_name: prim.simple_name().into(), signature: self.unifier.add_ty(TypeEnum::TFunc(FunSignature { args: vec![ - FuncArg { name: "m".into(), ty: self.num_ty.ty, default_value: None }, - FuncArg { name: "n".into(), ty: self.num_ty.ty, default_value: None }, + FuncArg { + name: "m".into(), + ty: self.num_ty.ty, + default_value: None, + is_vararg: false, + }, + FuncArg { + name: "n".into(), + ty: self.num_ty.ty, + default_value: None, + is_vararg: false, + }, ], ret: self.num_ty.ty, vars: self.num_var_map.clone(), @@ -1627,7 +1691,12 @@ impl<'a> BuiltinBuilder<'a> { signature: self.unifier.add_ty(TypeEnum::TFunc(FunSignature { args: param_ty .iter() - .map(|p| FuncArg { name: p.1.into(), ty: p.0, default_value: None }) + .map(|p| FuncArg { + name: p.1.into(), + ty: p.0, + default_value: None, + is_vararg: false, + }) .collect(), ret: ret_ty.ty, vars: into_var_map([x1_ty, x2_ty, ret_ty]), @@ -1668,6 +1737,7 @@ impl<'a> BuiltinBuilder<'a> { name: "n".into(), ty: self.num_or_ndarray_ty.ty, default_value: None, + is_vararg: false, }], ret: self.num_or_ndarray_ty.ty, vars: self.num_or_ndarray_var_map.clone(), @@ -1856,7 +1926,12 @@ impl<'a> BuiltinBuilder<'a> { signature: self.unifier.add_ty(TypeEnum::TFunc(FunSignature { args: param_ty .iter() - .map(|p| FuncArg { name: p.1.into(), ty: p.0, default_value: None }) + .map(|p| FuncArg { + name: p.1.into(), + ty: p.0, + default_value: None, + is_vararg: false, + }) .collect(), ret: ret_ty.ty, vars: into_var_map([x1_ty, x2_ty, ret_ty]), diff --git a/nac3core/src/toplevel/composer.rs b/nac3core/src/toplevel/composer.rs index 6111f0df2..547c7e276 100644 --- a/nac3core/src/toplevel/composer.rs +++ b/nac3core/src/toplevel/composer.rs @@ -921,6 +921,7 @@ impl TopLevelComposer { name: vararg.node.arg, ty, default_value: Some(SymbolValue::Tuple(Vec::default())), + is_vararg: true, }) }) .transpose()?; @@ -1026,13 +1027,14 @@ impl TopLevelComposer { v }), }, + is_vararg: false, }) }) .collect::, _>>()? }; if let Some(vararg) = vararg { - arg_types.push(vararg) + arg_types.push(vararg); }; let arg_types = arg_types; @@ -1288,6 +1290,7 @@ impl TopLevelComposer { }) } }, + is_vararg: false, }; // push the dummy type and the type annotation // into the list for later unification @@ -1713,21 +1716,25 @@ impl TopLevelComposer { name: "msg".into(), ty: string, default_value: Some(SymbolValue::Str(String::new())), + is_vararg: false, }, FuncArg { name: "param0".into(), ty: int64, default_value: Some(SymbolValue::I64(0)), + is_vararg: false, }, FuncArg { name: "param1".into(), ty: int64, default_value: Some(SymbolValue::I64(0)), + is_vararg: false, }, FuncArg { name: "param2".into(), ty: int64, default_value: Some(SymbolValue::I64(0)), + is_vararg: false, }, ], ret: self_type, @@ -1937,6 +1944,7 @@ impl TopLevelComposer { name: a.name, ty: unifier.subst(a.ty, &subst).unwrap_or(a.ty), default_value: a.default_value.clone(), + is_vararg: false, }) .collect_vec() }; diff --git a/nac3core/src/toplevel/helper.rs b/nac3core/src/toplevel/helper.rs index 598a80e9d..21aeb9dba 100644 --- a/nac3core/src/toplevel/helper.rs +++ b/nac3core/src/toplevel/helper.rs @@ -505,6 +505,7 @@ impl TopLevelComposer { name: "value".into(), ty: ndarray_dtype_tvar.ty, default_value: None, + is_vararg: false, }], ret: none, vars: into_var_map([ndarray_dtype_tvar, ndarray_ndims_tvar]), diff --git a/nac3core/src/typecheck/magic_methods.rs b/nac3core/src/typecheck/magic_methods.rs index 8547193e7..b5a0608c5 100644 --- a/nac3core/src/typecheck/magic_methods.rs +++ b/nac3core/src/typecheck/magic_methods.rs @@ -197,6 +197,7 @@ pub fn impl_binop( ty: other_ty, default_value: None, name: "other".into(), + is_vararg: false, }], })), false, @@ -261,6 +262,7 @@ pub fn impl_cmpop( ty: other_ty, default_value: None, name: "other".into(), + is_vararg: false, }], })), false, diff --git a/nac3core/src/typecheck/type_inferencer/mod.rs b/nac3core/src/typecheck/type_inferencer/mod.rs index cd02e0e33..24fe7a12a 100644 --- a/nac3core/src/typecheck/type_inferencer/mod.rs +++ b/nac3core/src/typecheck/type_inferencer/mod.rs @@ -759,7 +759,7 @@ impl<'a> Inferencer<'a> { let fun = FunSignature { args: fn_args .iter() - .map(|(k, ty)| FuncArg { name: *k, ty: *ty, default_value: None }) + .map(|(k, ty)| FuncArg { name: *k, ty: *ty, default_value: None, is_vararg: false }) .collect(), ret, vars: VarMap::default(), @@ -1106,6 +1106,7 @@ impl<'a> Inferencer<'a> { name: "n".into(), ty: arg0.custom.unwrap(), default_value: None, + is_vararg: false, }], ret, vars: VarMap::new(), @@ -1142,8 +1143,18 @@ impl<'a> Inferencer<'a> { let custom = self.unifier.add_ty(TypeEnum::TFunc(FunSignature { args: vec![ - FuncArg { name: "x1".into(), ty: arg0.custom.unwrap(), default_value: None }, - FuncArg { name: "x2".into(), ty: arg1.custom.unwrap(), default_value: None }, + FuncArg { + name: "x1".into(), + ty: arg0.custom.unwrap(), + default_value: None, + is_vararg: false, + }, + FuncArg { + name: "x2".into(), + ty: arg1.custom.unwrap(), + default_value: None, + is_vararg: false, + }, ], ret, vars: VarMap::new(), @@ -1182,6 +1193,7 @@ impl<'a> Inferencer<'a> { name: "a".into(), ty: arg0.custom.unwrap(), default_value: None, + is_vararg: false, }], ret, vars: VarMap::new(), @@ -1282,8 +1294,18 @@ impl<'a> Inferencer<'a> { let custom = self.unifier.add_ty(TypeEnum::TFunc(FunSignature { args: vec![ - FuncArg { name: "x1".into(), ty: arg0.custom.unwrap(), default_value: None }, - FuncArg { name: "x2".into(), ty: arg1.custom.unwrap(), default_value: None }, + FuncArg { + name: "x1".into(), + ty: arg0.custom.unwrap(), + default_value: None, + is_vararg: false, + }, + FuncArg { + name: "x2".into(), + ty: arg1.custom.unwrap(), + default_value: None, + is_vararg: false, + }, ], ret, vars: VarMap::new(), @@ -1363,6 +1385,7 @@ impl<'a> Inferencer<'a> { name: "n".into(), ty: arg0.custom.unwrap(), default_value: None, + is_vararg: false, }], ret, vars: VarMap::new(), @@ -1404,6 +1427,7 @@ impl<'a> Inferencer<'a> { name: "shape".into(), ty: shape.custom.unwrap(), default_value: None, + is_vararg: false, }], ret, vars: VarMap::new(), @@ -1437,11 +1461,17 @@ impl<'a> Inferencer<'a> { let custom = self.unifier.add_ty(TypeEnum::TFunc(FunSignature { args: vec![ - FuncArg { name: "x1".into(), ty: arg0.custom.unwrap(), default_value: None }, + FuncArg { + name: "x1".into(), + ty: arg0.custom.unwrap(), + default_value: None, + is_vararg: false, + }, FuncArg { name: "shape".into(), ty: shape.custom.unwrap(), default_value: None, + is_vararg: false, }, ], ret, @@ -1485,11 +1515,17 @@ impl<'a> Inferencer<'a> { let ret = make_ndarray_ty(self.unifier, self.primitives, Some(ty), Some(ndims)); let custom = self.unifier.add_ty(TypeEnum::TFunc(FunSignature { args: vec![ - FuncArg { name: "shape".into(), ty: arg0.custom.unwrap(), default_value: None }, + FuncArg { + name: "shape".into(), + ty: arg0.custom.unwrap(), + default_value: None, + is_vararg: false, + }, FuncArg { name: "fill_value".into(), ty: arg1.custom.unwrap(), default_value: None, + is_vararg: false, }, ], ret, @@ -1544,16 +1580,19 @@ impl<'a> Inferencer<'a> { name: "object".into(), ty: arg0.custom.unwrap(), default_value: None, + is_vararg: false, }, FuncArg { name: "copy".into(), ty: self.primitives.bool, default_value: Some(SymbolValue::Bool(true)), + is_vararg: false, }, FuncArg { name: "ndmin".into(), ty: self.primitives.int32, default_value: Some(SymbolValue::U32(0)), + is_vararg: false, }, ], ret, diff --git a/nac3core/src/typecheck/type_inferencer/test.rs b/nac3core/src/typecheck/type_inferencer/test.rs index 0a367ae75..75293a3ad 100644 --- a/nac3core/src/typecheck/type_inferencer/test.rs +++ b/nac3core/src/typecheck/type_inferencer/test.rs @@ -83,7 +83,12 @@ impl TestEnvironment { }); with_fields(&mut unifier, int32, |unifier, fields| { let add_ty = unifier.add_ty(TypeEnum::TFunc(FunSignature { - args: vec![FuncArg { name: "other".into(), ty: int32, default_value: None }], + args: vec![FuncArg { + name: "other".into(), + ty: int32, + default_value: None, + is_vararg: false, + }], ret: int32, vars: VarMap::new(), })); @@ -224,7 +229,12 @@ impl TestEnvironment { }); with_fields(&mut unifier, int32, |unifier, fields| { let add_ty = unifier.add_ty(TypeEnum::TFunc(FunSignature { - args: vec![FuncArg { name: "other".into(), ty: int32, default_value: None }], + args: vec![FuncArg { + name: "other".into(), + ty: int32, + default_value: None, + is_vararg: false, + }], ret: int32, vars: VarMap::new(), })); diff --git a/nac3core/src/typecheck/typedef/mod.rs b/nac3core/src/typecheck/typedef/mod.rs index 845e84067..cd1d89d2f 100644 --- a/nac3core/src/typecheck/typedef/mod.rs +++ b/nac3core/src/typecheck/typedef/mod.rs @@ -115,6 +115,7 @@ pub struct FuncArg { pub name: StrRef, pub ty: Type, pub default_value: Option, + pub is_vararg: bool, } impl FuncArg {