From f240202d6bb842db342a023e84dbbe106c7e1d09 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 --- nac3artiq/src/codegen.rs | 1 + nac3artiq/src/lib.rs | 4 +- nac3core/src/codegen/concrete_type.rs | 1 + nac3core/src/codegen/expr.rs | 5 +- 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 | 32 +++++- .../src/typecheck/type_inferencer/test.rs | 14 ++- nac3core/src/typecheck/typedef/mod.rs | 1 + 13 files changed, 169 insertions(+), 25 deletions(-) diff --git a/nac3artiq/src/codegen.rs b/nac3artiq/src/codegen.rs index 914798c0..9b0b00d9 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 7e3825a4..8601de13 100644 --- a/nac3artiq/src/lib.rs +++ b/nac3artiq/src/lib.rs @@ -264,7 +264,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() => { @@ -863,6 +863,7 @@ impl Nac3 { name: "t".into(), ty: primitive.int64, default_value: None, + is_vararg: false, }], ret: primitive.none, vars: VarMap::new(), @@ -882,6 +883,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 6488ec61..e4a78037 100644 --- a/nac3core/src/codegen/concrete_type.rs +++ b/nac3core/src/codegen/concrete_type.rs @@ -277,6 +277,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 c42c8444..678351cd 100644 --- a/nac3core/src/codegen/expr.rs +++ b/nac3core/src/codegen/expr.rs @@ -852,7 +852,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 17952369..5e68aff2 100644 --- a/nac3core/src/codegen/mod.rs +++ b/nac3core/src/codegen/mod.rs @@ -700,6 +700,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: false, }) .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 be4fa140..c84fa00f 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(), @@ -253,7 +263,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 bcb3c433..328c3818 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(), @@ -613,17 +634,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, @@ -879,6 +907,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]), @@ -1013,6 +1042,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(), @@ -1232,16 +1262,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, @@ -1283,17 +1320,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, @@ -1337,7 +1381,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(), })), @@ -1423,7 +1472,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]), })), @@ -1528,8 +1582,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(), @@ -1611,7 +1675,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]), @@ -1652,6 +1721,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(), @@ -1840,7 +1910,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 e70d9201..fe7a47c6 100644 --- a/nac3core/src/toplevel/composer.rs +++ b/nac3core/src/toplevel/composer.rs @@ -919,6 +919,7 @@ impl TopLevelComposer { name: vararg.node.arg, ty, default_value: Some(SymbolValue::Tuple(Vec::default())), + is_vararg: true, }) }) .transpose()?; @@ -1023,13 +1024,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; @@ -1284,6 +1286,7 @@ impl TopLevelComposer { }) } }, + is_vararg: false, }; // push the dummy type and the type annotation // into the list for later unification @@ -1708,21 +1711,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, @@ -1928,6 +1935,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 5560f41c..51db91d8 100644 --- a/nac3core/src/toplevel/helper.rs +++ b/nac3core/src/toplevel/helper.rs @@ -448,6 +448,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 8547193e..b5a0608c 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 d9380ab1..f4640746 100644 --- a/nac3core/src/typecheck/type_inferencer/mod.rs +++ b/nac3core/src/typecheck/type_inferencer/mod.rs @@ -763,7 +763,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(), @@ -1110,6 +1110,7 @@ impl<'a> Inferencer<'a> { name: "n".into(), ty: arg0.custom.unwrap(), default_value: None, + is_vararg: false, }], ret, vars: VarMap::new(), @@ -1148,6 +1149,7 @@ impl<'a> Inferencer<'a> { name: "a".into(), ty: arg0.custom.unwrap(), default_value: None, + is_vararg: false, }], ret, vars: VarMap::new(), @@ -1248,8 +1250,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(), @@ -1329,6 +1341,7 @@ impl<'a> Inferencer<'a> { name: "n".into(), ty: arg0.custom.unwrap(), default_value: None, + is_vararg: false, }], ret, vars: VarMap::new(), @@ -1370,6 +1383,7 @@ impl<'a> Inferencer<'a> { name: "shape".into(), ty: shape.custom.unwrap(), default_value: None, + is_vararg: false, }], ret, vars: VarMap::new(), @@ -1413,11 +1427,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, @@ -1472,16 +1492,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, @@ -1539,6 +1562,7 @@ impl<'a> Inferencer<'a> { loc: Some(location), operator_info: None, }; + println!("{}", self.unifier.stringify(func.custom.unwrap())); self.unifier.unify_call(&call, func.custom.unwrap(), sign).map_err(|e| { HashSet::from([e.at(Some(location)).to_display(self.unifier).to_string()]) })?; diff --git a/nac3core/src/typecheck/type_inferencer/test.rs b/nac3core/src/typecheck/type_inferencer/test.rs index 0a367ae7..75293a3a 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 845e8406..cd1d89d2 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 {