From 47f563908a7965e4cebd20c97f092bdecdabb077 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Tue, 2 Nov 2021 23:22:37 +0800 Subject: [PATCH] basic string support (#30) --- nac3core/src/codegen/expr.rs | 4 ++ nac3core/src/codegen/mod.rs | 2 + nac3core/src/toplevel/composer.rs | 26 +++++++++++- nac3core/src/toplevel/helper.rs | 7 +++- ...el__test__test_analyze__generic_class.snap | 12 +++--- ...t__test_analyze__inheritance_override.snap | 18 ++++---- ...est__test_analyze__list_tuple_generic.snap | 14 +++---- ...__toplevel__test__test_analyze__self1.snap | 14 +++---- ...t__test_analyze__simple_class_compose.snap | 22 +++++----- ...t__test_analyze__simple_pass_in_class.snap | 2 +- nac3core/src/toplevel/type_annotation.rs | 2 + nac3core/src/typecheck/type_inferencer/mod.rs | 2 + .../src/typecheck/type_inferencer/test.rs | 42 ++++++++++++------- 13 files changed, 109 insertions(+), 58 deletions(-) diff --git a/nac3core/src/codegen/expr.rs b/nac3core/src/codegen/expr.rs index a5f35cc7..7d3656cc 100644 --- a/nac3core/src/codegen/expr.rs +++ b/nac3core/src/codegen/expr.rs @@ -135,6 +135,10 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> { let ty = self.ctx.struct_type(&types, false); ty.const_named_struct(&values).into() } + Constant::Str(v) => { + assert!(self.unifier.unioned(ty, self.primitives.str)); + self.builder.build_global_string_ptr(v, "const").as_pointer_value().into() + } _ => unreachable!(), } } diff --git a/nac3core/src/codegen/mod.rs b/nac3core/src/codegen/mod.rs index e93dff0a..8a982337 100644 --- a/nac3core/src/codegen/mod.rs +++ b/nac3core/src/codegen/mod.rs @@ -291,6 +291,7 @@ pub fn gen_func<'ctx, G: CodeGenerator + ?Sized>( bool: unifier.get_representative(primitives.bool), none: unifier.get_representative(primitives.none), range: unifier.get_representative(primitives.range), + str: unifier.get_representative(primitives.str), }; let mut type_cache: HashMap<_, _> = [ @@ -298,6 +299,7 @@ pub fn gen_func<'ctx, G: CodeGenerator + ?Sized>( (unifier.get_representative(primitives.int64), context.i64_type().into()), (unifier.get_representative(primitives.float), context.f64_type().into()), (unifier.get_representative(primitives.bool), context.bool_type().into()), + (unifier.get_representative(primitives.str), context.i8_type().ptr_type(AddressSpace::Generic).into()), ] .iter() .cloned() diff --git a/nac3core/src/toplevel/composer.rs b/nac3core/src/toplevel/composer.rs index 4de5593f..8676d887 100644 --- a/nac3core/src/toplevel/composer.rs +++ b/nac3core/src/toplevel/composer.rs @@ -46,6 +46,7 @@ impl TopLevelComposer { let float = primitives.0.float; let boolean = primitives.0.bool; let range = primitives.0.range; + let string = primitives.0.str; let num_ty = primitives.1.get_fresh_var_with_range(&[int32, int64, float, boolean]); let var_map: HashMap<_, _> = vec![(num_ty.1, num_ty.0)].into_iter().collect(); @@ -77,6 +78,12 @@ impl TopLevelComposer { "range".into(), None, ))), + Arc::new(RwLock::new(Self::make_top_level_class_def( + 6, + None, + "str".into(), + None, + ))), Arc::new(RwLock::new(TopLevelDef::Function { name: "int32".into(), simple_name: "int32".into(), @@ -372,6 +379,22 @@ impl TopLevelComposer { Some(ptr.into()) })))), })), + Arc::new(RwLock::new(TopLevelDef::Function { + name: "str".into(), + simple_name: "str".into(), + signature: primitives.1.add_ty(TypeEnum::TFunc(RefCell::new(FunSignature { + args: vec![FuncArg { name: "_".into(), ty: string, default_value: None }], + ret: string, + vars: Default::default(), + }))), + var_id: Default::default(), + instance_to_symbol: Default::default(), + instance_to_stmt: Default::default(), + resolver: None, + codegen_callback: Some(Arc::new(GenCall::new(Box::new(|_, _, _, args| + Some(args[0].1) + )))), + })), ]; let ast_list: Vec>> = (0..top_level_def_list.len()).map(|_| None).collect(); @@ -391,6 +414,7 @@ impl TopLevelComposer { "none".into(), "None".into(), "range".into(), + "str".into(), "self".into(), "Kernel".into(), "KernelImmutable".into(), @@ -402,7 +426,7 @@ impl TopLevelComposer { let mut built_in_ty: HashMap = Default::default(); for (id, name) in - ["int32", "int64", "float", "round", "round64", "range"].iter().rev().enumerate() + ["int32", "int64", "float", "round", "round64", "range", "str"].iter().rev().enumerate() { let name = (**name).into(); let id = definition_ast_list.len() - id - 1; diff --git a/nac3core/src/toplevel/helper.rs b/nac3core/src/toplevel/helper.rs index b3d76004..ec4bd184 100644 --- a/nac3core/src/toplevel/helper.rs +++ b/nac3core/src/toplevel/helper.rs @@ -87,7 +87,12 @@ impl TopLevelComposer { fields: HashMap::new().into(), params: HashMap::new().into(), }); - let primitives = PrimitiveStore { int32, int64, float, bool, none, range }; + let str = unifier.add_ty(TypeEnum::TObj { + obj_id: DefinitionId(6), + fields: HashMap::new().into(), + params: HashMap::new().into(), + }); + let primitives = PrimitiveStore { int32, int64, float, bool, none, range, str }; crate::typecheck::magic_methods::set_primitives_magic_methods(&primitives, &mut unifier); (primitives, unifier) } diff --git a/nac3core/src/toplevel/snapshots/nac3core__toplevel__test__test_analyze__generic_class.snap b/nac3core/src/toplevel/snapshots/nac3core__toplevel__test__test_analyze__generic_class.snap index 063c296f..c7944a61 100644 --- a/nac3core/src/toplevel/snapshots/nac3core__toplevel__test__test_analyze__generic_class.snap +++ b/nac3core/src/toplevel/snapshots/nac3core__toplevel__test__test_analyze__generic_class.snap @@ -4,10 +4,10 @@ expression: res_vec --- [ - "12: Class {\nname: \"Generic_A\",\ndef_id: DefinitionId(12),\nancestors: [CustomClassKind { id: DefinitionId(12), params: [TypeVarKind(UnificationKey(109))] }, CustomClassKind { id: DefinitionId(15), params: [] }],\nfields: [(\"aa\", \"class3\"), (\"a\", \"class1\")],\nmethods: [(\"__init__\", \"fn[[], class4]\", DefinitionId(13)), (\"foo\", \"fn[[b=tvar3], class4]\", DefinitionId(17)), (\"fun\", \"fn[[a=class0], tvar4]\", DefinitionId(14))],\ntype_vars: [UnificationKey(109)]\n}\n", - "13: Function {\nname: \"Generic_A.__init__\",\nsig: \"fn[[], class4]\",\nvar_id: [4]\n}\n", - "14: Function {\nname: \"Generic_A.fun\",\nsig: \"fn[[a=class0], tvar4]\",\nvar_id: [4]\n}\n", - "15: Class {\nname: \"B\",\ndef_id: DefinitionId(15),\nancestors: [CustomClassKind { id: DefinitionId(15), params: [] }],\nfields: [(\"aa\", \"class3\")],\nmethods: [(\"__init__\", \"fn[[], class4]\", DefinitionId(16)), (\"foo\", \"fn[[b=tvar3], class4]\", DefinitionId(17))],\ntype_vars: []\n}\n", - "16: Function {\nname: \"B.__init__\",\nsig: \"fn[[], class4]\",\nvar_id: []\n}\n", - "17: Function {\nname: \"B.foo\",\nsig: \"fn[[b=tvar3], class4]\",\nvar_id: [3]\n}\n", + "14: Class {\nname: \"Generic_A\",\ndef_id: DefinitionId(14),\nancestors: [CustomClassKind { id: DefinitionId(14), params: [TypeVarKind(UnificationKey(111))] }, CustomClassKind { id: DefinitionId(17), params: [] }],\nfields: [(\"aa\", \"class3\"), (\"a\", \"class1\")],\nmethods: [(\"__init__\", \"fn[[], class4]\", DefinitionId(15)), (\"foo\", \"fn[[b=tvar3], class4]\", DefinitionId(19)), (\"fun\", \"fn[[a=class0], tvar4]\", DefinitionId(16))],\ntype_vars: [UnificationKey(111)]\n}\n", + "15: Function {\nname: \"Generic_A.__init__\",\nsig: \"fn[[], class4]\",\nvar_id: [4]\n}\n", + "16: Function {\nname: \"Generic_A.fun\",\nsig: \"fn[[a=class0], tvar4]\",\nvar_id: [4]\n}\n", + "17: Class {\nname: \"B\",\ndef_id: DefinitionId(17),\nancestors: [CustomClassKind { id: DefinitionId(17), params: [] }],\nfields: [(\"aa\", \"class3\")],\nmethods: [(\"__init__\", \"fn[[], class4]\", DefinitionId(18)), (\"foo\", \"fn[[b=tvar3], class4]\", DefinitionId(19))],\ntype_vars: []\n}\n", + "18: Function {\nname: \"B.__init__\",\nsig: \"fn[[], class4]\",\nvar_id: []\n}\n", + "19: Function {\nname: \"B.foo\",\nsig: \"fn[[b=tvar3], class4]\",\nvar_id: [3]\n}\n", ] diff --git a/nac3core/src/toplevel/snapshots/nac3core__toplevel__test__test_analyze__inheritance_override.snap b/nac3core/src/toplevel/snapshots/nac3core__toplevel__test__test_analyze__inheritance_override.snap index 6fdb6a72..c683c255 100644 --- a/nac3core/src/toplevel/snapshots/nac3core__toplevel__test__test_analyze__inheritance_override.snap +++ b/nac3core/src/toplevel/snapshots/nac3core__toplevel__test__test_analyze__inheritance_override.snap @@ -4,13 +4,13 @@ expression: res_vec --- [ - "12: Class {\nname: \"A\",\ndef_id: DefinitionId(12),\nancestors: [CustomClassKind { id: DefinitionId(12), params: [TypeVarKind(UnificationKey(108))] }],\nfields: [(\"a\", \"class0\"), (\"b\", \"tvar3\"), (\"c\", \"class12[3->class1]\")],\nmethods: [(\"__init__\", \"fn[[t=tvar3], class4]\", DefinitionId(13)), (\"fun\", \"fn[[a=class0, b=tvar3], list[virtual[class16[4->class3]]]]\", DefinitionId(14)), (\"foo\", \"fn[[c=class19], class4]\", DefinitionId(15))],\ntype_vars: [UnificationKey(108)]\n}\n", - "13: Function {\nname: \"A.__init__\",\nsig: \"fn[[t=tvar3], class4]\",\nvar_id: [3]\n}\n", - "14: Function {\nname: \"A.fun\",\nsig: \"fn[[a=class0, b=tvar3], list[virtual[class16[4->class3]]]]\",\nvar_id: [3]\n}\n", - "15: Function {\nname: \"A.foo\",\nsig: \"fn[[c=class19], class4]\",\nvar_id: [3]\n}\n", - "16: Class {\nname: \"B\",\ndef_id: DefinitionId(16),\nancestors: [CustomClassKind { id: DefinitionId(16), params: [TypeVarKind(UnificationKey(109))] }, CustomClassKind { id: DefinitionId(12), params: [PrimitiveKind(UnificationKey(2))] }],\nfields: [(\"a\", \"class0\"), (\"b\", \"tvar3\"), (\"c\", \"class12[3->class1]\"), (\"d\", \"class19\")],\nmethods: [(\"__init__\", \"fn[[], class4]\", DefinitionId(17)), (\"fun\", \"fn[[a=class0, b=tvar3], list[virtual[class16[4->class3]]]]\", DefinitionId(18)), (\"foo\", \"fn[[c=class19], class4]\", DefinitionId(15))],\ntype_vars: [UnificationKey(109)]\n}\n", - "17: Function {\nname: \"B.__init__\",\nsig: \"fn[[], class4]\",\nvar_id: [4]\n}\n", - "18: Function {\nname: \"B.fun\",\nsig: \"fn[[a=class0, b=tvar3], list[virtual[class16[4->class3]]]]\",\nvar_id: [3, 4]\n}\n", - "19: Class {\nname: \"C\",\ndef_id: DefinitionId(19),\nancestors: [CustomClassKind { id: DefinitionId(19), params: [] }, CustomClassKind { id: DefinitionId(16), params: [PrimitiveKind(UnificationKey(3))] }, CustomClassKind { id: DefinitionId(12), params: [PrimitiveKind(UnificationKey(2))] }],\nfields: [(\"a\", \"class0\"), (\"b\", \"tvar3\"), (\"c\", \"class12[3->class1]\"), (\"d\", \"class19\"), (\"e\", \"class1\")],\nmethods: [(\"__init__\", \"fn[[], class4]\", DefinitionId(20)), (\"fun\", \"fn[[a=class0, b=tvar3], list[virtual[class16[4->class3]]]]\", DefinitionId(18)), (\"foo\", \"fn[[c=class19], class4]\", DefinitionId(15))],\ntype_vars: []\n}\n", - "20: Function {\nname: \"C.__init__\",\nsig: \"fn[[], class4]\",\nvar_id: []\n}\n", + "14: Class {\nname: \"A\",\ndef_id: DefinitionId(14),\nancestors: [CustomClassKind { id: DefinitionId(14), params: [TypeVarKind(UnificationKey(110))] }],\nfields: [(\"a\", \"class0\"), (\"b\", \"tvar3\"), (\"c\", \"class14[3->class1]\")],\nmethods: [(\"__init__\", \"fn[[t=tvar3], class4]\", DefinitionId(15)), (\"fun\", \"fn[[a=class0, b=tvar3], list[virtual[class18[4->class3]]]]\", DefinitionId(16)), (\"foo\", \"fn[[c=class21], class4]\", DefinitionId(17))],\ntype_vars: [UnificationKey(110)]\n}\n", + "15: Function {\nname: \"A.__init__\",\nsig: \"fn[[t=tvar3], class4]\",\nvar_id: [3]\n}\n", + "16: Function {\nname: \"A.fun\",\nsig: \"fn[[a=class0, b=tvar3], list[virtual[class18[4->class3]]]]\",\nvar_id: [3]\n}\n", + "17: Function {\nname: \"A.foo\",\nsig: \"fn[[c=class21], class4]\",\nvar_id: [3]\n}\n", + "18: Class {\nname: \"B\",\ndef_id: DefinitionId(18),\nancestors: [CustomClassKind { id: DefinitionId(18), params: [TypeVarKind(UnificationKey(111))] }, CustomClassKind { id: DefinitionId(14), params: [PrimitiveKind(UnificationKey(2))] }],\nfields: [(\"a\", \"class0\"), (\"b\", \"tvar3\"), (\"c\", \"class14[3->class1]\"), (\"d\", \"class21\")],\nmethods: [(\"__init__\", \"fn[[], class4]\", DefinitionId(19)), (\"fun\", \"fn[[a=class0, b=tvar3], list[virtual[class18[4->class3]]]]\", DefinitionId(20)), (\"foo\", \"fn[[c=class21], class4]\", DefinitionId(17))],\ntype_vars: [UnificationKey(111)]\n}\n", + "19: Function {\nname: \"B.__init__\",\nsig: \"fn[[], class4]\",\nvar_id: [4]\n}\n", + "20: Function {\nname: \"B.fun\",\nsig: \"fn[[a=class0, b=tvar3], list[virtual[class18[4->class3]]]]\",\nvar_id: [3, 4]\n}\n", + "21: Class {\nname: \"C\",\ndef_id: DefinitionId(21),\nancestors: [CustomClassKind { id: DefinitionId(21), params: [] }, CustomClassKind { id: DefinitionId(18), params: [PrimitiveKind(UnificationKey(3))] }, CustomClassKind { id: DefinitionId(14), params: [PrimitiveKind(UnificationKey(2))] }],\nfields: [(\"a\", \"class0\"), (\"b\", \"tvar3\"), (\"c\", \"class14[3->class1]\"), (\"d\", \"class21\"), (\"e\", \"class1\")],\nmethods: [(\"__init__\", \"fn[[], class4]\", DefinitionId(22)), (\"fun\", \"fn[[a=class0, b=tvar3], list[virtual[class18[4->class3]]]]\", DefinitionId(20)), (\"foo\", \"fn[[c=class21], class4]\", DefinitionId(17))],\ntype_vars: []\n}\n", + "22: Function {\nname: \"C.__init__\",\nsig: \"fn[[], class4]\",\nvar_id: []\n}\n", ] diff --git a/nac3core/src/toplevel/snapshots/nac3core__toplevel__test__test_analyze__list_tuple_generic.snap b/nac3core/src/toplevel/snapshots/nac3core__toplevel__test__test_analyze__list_tuple_generic.snap index 48d49a91..4bc6dcbb 100644 --- a/nac3core/src/toplevel/snapshots/nac3core__toplevel__test__test_analyze__list_tuple_generic.snap +++ b/nac3core/src/toplevel/snapshots/nac3core__toplevel__test__test_analyze__list_tuple_generic.snap @@ -4,11 +4,11 @@ expression: res_vec --- [ - "12: Function {\nname: \"foo\",\nsig: \"fn[[a=list[class0], b=tuple[tvar3, class2]], class13[3->class17, 4->class3]]\",\nvar_id: [3]\n}\n", - "13: Class {\nname: \"A\",\ndef_id: DefinitionId(13),\nancestors: [CustomClassKind { id: DefinitionId(13), params: [TypeVarKind(UnificationKey(108)), TypeVarKind(UnificationKey(109))] }],\nfields: [(\"a\", \"tvar3\"), (\"b\", \"tvar4\")],\nmethods: [(\"__init__\", \"fn[[v=tvar4], class4]\", DefinitionId(14)), (\"fun\", \"fn[[a=tvar3], tvar4]\", DefinitionId(15))],\ntype_vars: [UnificationKey(108), UnificationKey(109)]\n}\n", - "14: Function {\nname: \"A.__init__\",\nsig: \"fn[[v=tvar4], class4]\",\nvar_id: [3, 4]\n}\n", - "15: Function {\nname: \"A.fun\",\nsig: \"fn[[a=tvar3], tvar4]\",\nvar_id: [3, 4]\n}\n", - "16: Function {\nname: \"gfun\",\nsig: \"fn[[a=class13[3->list[class2], 4->class0]], class4]\",\nvar_id: []\n}\n", - "17: Class {\nname: \"B\",\ndef_id: DefinitionId(17),\nancestors: [CustomClassKind { id: DefinitionId(17), params: [] }],\nfields: [],\nmethods: [(\"__init__\", \"fn[[], class4]\", DefinitionId(18))],\ntype_vars: []\n}\n", - "18: Function {\nname: \"B.__init__\",\nsig: \"fn[[], class4]\",\nvar_id: []\n}\n", + "14: Function {\nname: \"foo\",\nsig: \"fn[[a=list[class0], b=tuple[tvar3, class2]], class15[3->class19, 4->class3]]\",\nvar_id: [3]\n}\n", + "15: Class {\nname: \"A\",\ndef_id: DefinitionId(15),\nancestors: [CustomClassKind { id: DefinitionId(15), params: [TypeVarKind(UnificationKey(110)), TypeVarKind(UnificationKey(111))] }],\nfields: [(\"a\", \"tvar3\"), (\"b\", \"tvar4\")],\nmethods: [(\"__init__\", \"fn[[v=tvar4], class4]\", DefinitionId(16)), (\"fun\", \"fn[[a=tvar3], tvar4]\", DefinitionId(17))],\ntype_vars: [UnificationKey(110), UnificationKey(111)]\n}\n", + "16: Function {\nname: \"A.__init__\",\nsig: \"fn[[v=tvar4], class4]\",\nvar_id: [3, 4]\n}\n", + "17: Function {\nname: \"A.fun\",\nsig: \"fn[[a=tvar3], tvar4]\",\nvar_id: [3, 4]\n}\n", + "18: Function {\nname: \"gfun\",\nsig: \"fn[[a=class15[3->list[class2], 4->class0]], class4]\",\nvar_id: []\n}\n", + "19: Class {\nname: \"B\",\ndef_id: DefinitionId(19),\nancestors: [CustomClassKind { id: DefinitionId(19), params: [] }],\nfields: [],\nmethods: [(\"__init__\", \"fn[[], class4]\", DefinitionId(20))],\ntype_vars: []\n}\n", + "20: Function {\nname: \"B.__init__\",\nsig: \"fn[[], class4]\",\nvar_id: []\n}\n", ] diff --git a/nac3core/src/toplevel/snapshots/nac3core__toplevel__test__test_analyze__self1.snap b/nac3core/src/toplevel/snapshots/nac3core__toplevel__test__test_analyze__self1.snap index 60832b44..26b36ebb 100644 --- a/nac3core/src/toplevel/snapshots/nac3core__toplevel__test__test_analyze__self1.snap +++ b/nac3core/src/toplevel/snapshots/nac3core__toplevel__test__test_analyze__self1.snap @@ -4,11 +4,11 @@ expression: res_vec --- [ - "12: Class {\nname: \"A\",\ndef_id: DefinitionId(12),\nancestors: [CustomClassKind { id: DefinitionId(12), params: [TypeVarKind(UnificationKey(108)), TypeVarKind(UnificationKey(109))] }],\nfields: [(\"a\", \"class12[3->class2, 4->class3]\"), (\"b\", \"class15\")],\nmethods: [(\"__init__\", \"fn[[a=class12[3->class2, 4->class3], b=class15], class4]\", DefinitionId(13)), (\"fun\", \"fn[[a=class12[3->class2, 4->class3]], class12[3->class3, 4->class0]]\", DefinitionId(14))],\ntype_vars: [UnificationKey(108), UnificationKey(109)]\n}\n", - "13: Function {\nname: \"A.__init__\",\nsig: \"fn[[a=class12[3->class2, 4->class3], b=class15], class4]\",\nvar_id: [3, 4]\n}\n", - "14: Function {\nname: \"A.fun\",\nsig: \"fn[[a=class12[3->class2, 4->class3]], class12[3->class3, 4->class0]]\",\nvar_id: [3, 4]\n}\n", - "15: Class {\nname: \"B\",\ndef_id: DefinitionId(15),\nancestors: [CustomClassKind { id: DefinitionId(15), params: [] }, CustomClassKind { id: DefinitionId(12), params: [PrimitiveKind(UnificationKey(1)), PrimitiveKind(UnificationKey(3))] }],\nfields: [(\"a\", \"class12[3->class2, 4->class3]\"), (\"b\", \"class15\")],\nmethods: [(\"__init__\", \"fn[[], class4]\", DefinitionId(16)), (\"fun\", \"fn[[a=class12[3->class2, 4->class3]], class12[3->class3, 4->class0]]\", DefinitionId(14)), (\"foo\", \"fn[[b=class15], class15]\", DefinitionId(17)), (\"bar\", \"fn[[a=class12[3->list[class15], 4->class0]], tuple[class12[3->virtual[class12[3->class15, 4->class0]], 4->class3], class15]]\", DefinitionId(18))],\ntype_vars: []\n}\n", - "16: Function {\nname: \"B.__init__\",\nsig: \"fn[[], class4]\",\nvar_id: []\n}\n", - "17: Function {\nname: \"B.foo\",\nsig: \"fn[[b=class15], class15]\",\nvar_id: []\n}\n", - "18: Function {\nname: \"B.bar\",\nsig: \"fn[[a=class12[3->list[class15], 4->class0]], tuple[class12[3->virtual[class12[3->class15, 4->class0]], 4->class3], class15]]\",\nvar_id: []\n}\n", + "14: Class {\nname: \"A\",\ndef_id: DefinitionId(14),\nancestors: [CustomClassKind { id: DefinitionId(14), params: [TypeVarKind(UnificationKey(110)), TypeVarKind(UnificationKey(111))] }],\nfields: [(\"a\", \"class14[3->class2, 4->class3]\"), (\"b\", \"class17\")],\nmethods: [(\"__init__\", \"fn[[a=class14[3->class2, 4->class3], b=class17], class4]\", DefinitionId(15)), (\"fun\", \"fn[[a=class14[3->class2, 4->class3]], class14[3->class3, 4->class0]]\", DefinitionId(16))],\ntype_vars: [UnificationKey(110), UnificationKey(111)]\n}\n", + "15: Function {\nname: \"A.__init__\",\nsig: \"fn[[a=class14[3->class2, 4->class3], b=class17], class4]\",\nvar_id: [3, 4]\n}\n", + "16: Function {\nname: \"A.fun\",\nsig: \"fn[[a=class14[3->class2, 4->class3]], class14[3->class3, 4->class0]]\",\nvar_id: [3, 4]\n}\n", + "17: Class {\nname: \"B\",\ndef_id: DefinitionId(17),\nancestors: [CustomClassKind { id: DefinitionId(17), params: [] }, CustomClassKind { id: DefinitionId(14), params: [PrimitiveKind(UnificationKey(1)), PrimitiveKind(UnificationKey(3))] }],\nfields: [(\"a\", \"class14[3->class2, 4->class3]\"), (\"b\", \"class17\")],\nmethods: [(\"__init__\", \"fn[[], class4]\", DefinitionId(18)), (\"fun\", \"fn[[a=class14[3->class2, 4->class3]], class14[3->class3, 4->class0]]\", DefinitionId(16)), (\"foo\", \"fn[[b=class17], class17]\", DefinitionId(19)), (\"bar\", \"fn[[a=class14[3->list[class17], 4->class0]], tuple[class14[3->virtual[class14[3->class17, 4->class0]], 4->class3], class17]]\", DefinitionId(20))],\ntype_vars: []\n}\n", + "18: Function {\nname: \"B.__init__\",\nsig: \"fn[[], class4]\",\nvar_id: []\n}\n", + "19: Function {\nname: \"B.foo\",\nsig: \"fn[[b=class17], class17]\",\nvar_id: []\n}\n", + "20: Function {\nname: \"B.bar\",\nsig: \"fn[[a=class14[3->list[class17], 4->class0]], tuple[class14[3->virtual[class14[3->class17, 4->class0]], 4->class3], class17]]\",\nvar_id: []\n}\n", ] diff --git a/nac3core/src/toplevel/snapshots/nac3core__toplevel__test__test_analyze__simple_class_compose.snap b/nac3core/src/toplevel/snapshots/nac3core__toplevel__test__test_analyze__simple_class_compose.snap index a10d819c..c436efd3 100644 --- a/nac3core/src/toplevel/snapshots/nac3core__toplevel__test__test_analyze__simple_class_compose.snap +++ b/nac3core/src/toplevel/snapshots/nac3core__toplevel__test__test_analyze__simple_class_compose.snap @@ -4,15 +4,15 @@ expression: res_vec --- [ - "12: Class {\nname: \"A\",\ndef_id: DefinitionId(12),\nancestors: [CustomClassKind { id: DefinitionId(12), params: [] }],\nfields: [(\"a\", \"class0\")],\nmethods: [(\"__init__\", \"fn[[], class4]\", DefinitionId(13)), (\"fun\", \"fn[[b=class16], class4]\", DefinitionId(14)), (\"foo\", \"fn[[a=tvar3, b=tvar4], class4]\", DefinitionId(15))],\ntype_vars: []\n}\n", - "13: Function {\nname: \"A.__init__\",\nsig: \"fn[[], class4]\",\nvar_id: []\n}\n", - "14: Function {\nname: \"A.fun\",\nsig: \"fn[[b=class16], class4]\",\nvar_id: []\n}\n", - "15: Function {\nname: \"A.foo\",\nsig: \"fn[[a=tvar3, b=tvar4], class4]\",\nvar_id: [3, 4]\n}\n", - "16: Class {\nname: \"B\",\ndef_id: DefinitionId(16),\nancestors: [CustomClassKind { id: DefinitionId(16), params: [] }, CustomClassKind { id: DefinitionId(18), params: [] }, CustomClassKind { id: DefinitionId(12), params: [] }],\nfields: [(\"a\", \"class0\")],\nmethods: [(\"__init__\", \"fn[[], class4]\", DefinitionId(17)), (\"fun\", \"fn[[b=class16], class4]\", DefinitionId(20)), (\"foo\", \"fn[[a=tvar3, b=tvar4], class4]\", DefinitionId(15))],\ntype_vars: []\n}\n", - "17: Function {\nname: \"B.__init__\",\nsig: \"fn[[], class4]\",\nvar_id: []\n}\n", - "18: Class {\nname: \"C\",\ndef_id: DefinitionId(18),\nancestors: [CustomClassKind { id: DefinitionId(18), params: [] }, CustomClassKind { id: DefinitionId(12), params: [] }],\nfields: [(\"a\", \"class0\")],\nmethods: [(\"__init__\", \"fn[[], class4]\", DefinitionId(19)), (\"fun\", \"fn[[b=class16], class4]\", DefinitionId(20)), (\"foo\", \"fn[[a=tvar3, b=tvar4], class4]\", DefinitionId(15))],\ntype_vars: []\n}\n", - "19: Function {\nname: \"C.__init__\",\nsig: \"fn[[], class4]\",\nvar_id: []\n}\n", - "20: Function {\nname: \"C.fun\",\nsig: \"fn[[b=class16], class4]\",\nvar_id: []\n}\n", - "21: Function {\nname: \"foo\",\nsig: \"fn[[a=class12], class4]\",\nvar_id: []\n}\n", - "22: Function {\nname: \"ff\",\nsig: \"fn[[a=tvar3], tvar4]\",\nvar_id: [3, 4]\n}\n", + "14: Class {\nname: \"A\",\ndef_id: DefinitionId(14),\nancestors: [CustomClassKind { id: DefinitionId(14), params: [] }],\nfields: [(\"a\", \"class0\")],\nmethods: [(\"__init__\", \"fn[[], class4]\", DefinitionId(15)), (\"fun\", \"fn[[b=class18], class4]\", DefinitionId(16)), (\"foo\", \"fn[[a=tvar3, b=tvar4], class4]\", DefinitionId(17))],\ntype_vars: []\n}\n", + "15: Function {\nname: \"A.__init__\",\nsig: \"fn[[], class4]\",\nvar_id: []\n}\n", + "16: Function {\nname: \"A.fun\",\nsig: \"fn[[b=class18], class4]\",\nvar_id: []\n}\n", + "17: Function {\nname: \"A.foo\",\nsig: \"fn[[a=tvar3, b=tvar4], class4]\",\nvar_id: [3, 4]\n}\n", + "18: Class {\nname: \"B\",\ndef_id: DefinitionId(18),\nancestors: [CustomClassKind { id: DefinitionId(18), params: [] }, CustomClassKind { id: DefinitionId(20), params: [] }, CustomClassKind { id: DefinitionId(14), params: [] }],\nfields: [(\"a\", \"class0\")],\nmethods: [(\"__init__\", \"fn[[], class4]\", DefinitionId(19)), (\"fun\", \"fn[[b=class18], class4]\", DefinitionId(22)), (\"foo\", \"fn[[a=tvar3, b=tvar4], class4]\", DefinitionId(17))],\ntype_vars: []\n}\n", + "19: Function {\nname: \"B.__init__\",\nsig: \"fn[[], class4]\",\nvar_id: []\n}\n", + "20: Class {\nname: \"C\",\ndef_id: DefinitionId(20),\nancestors: [CustomClassKind { id: DefinitionId(20), params: [] }, CustomClassKind { id: DefinitionId(14), params: [] }],\nfields: [(\"a\", \"class0\")],\nmethods: [(\"__init__\", \"fn[[], class4]\", DefinitionId(21)), (\"fun\", \"fn[[b=class18], class4]\", DefinitionId(22)), (\"foo\", \"fn[[a=tvar3, b=tvar4], class4]\", DefinitionId(17))],\ntype_vars: []\n}\n", + "21: Function {\nname: \"C.__init__\",\nsig: \"fn[[], class4]\",\nvar_id: []\n}\n", + "22: Function {\nname: \"C.fun\",\nsig: \"fn[[b=class18], class4]\",\nvar_id: []\n}\n", + "23: Function {\nname: \"foo\",\nsig: \"fn[[a=class14], class4]\",\nvar_id: []\n}\n", + "24: Function {\nname: \"ff\",\nsig: \"fn[[a=tvar3], tvar4]\",\nvar_id: [3, 4]\n}\n", ] diff --git a/nac3core/src/toplevel/snapshots/nac3core__toplevel__test__test_analyze__simple_pass_in_class.snap b/nac3core/src/toplevel/snapshots/nac3core__toplevel__test__test_analyze__simple_pass_in_class.snap index 606663aa..fc148008 100644 --- a/nac3core/src/toplevel/snapshots/nac3core__toplevel__test__test_analyze__simple_pass_in_class.snap +++ b/nac3core/src/toplevel/snapshots/nac3core__toplevel__test__test_analyze__simple_pass_in_class.snap @@ -4,5 +4,5 @@ expression: res_vec --- [ - "12: Class {\nname: \"A\",\ndef_id: DefinitionId(12),\nancestors: [CustomClassKind { id: DefinitionId(12), params: [] }],\nfields: [],\nmethods: [],\ntype_vars: []\n}\n", + "14: Class {\nname: \"A\",\ndef_id: DefinitionId(14),\nancestors: [CustomClassKind { id: DefinitionId(14), params: [] }],\nfields: [],\nmethods: [],\ntype_vars: []\n}\n", ] diff --git a/nac3core/src/toplevel/type_annotation.rs b/nac3core/src/toplevel/type_annotation.rs index 7f33e823..1731be21 100644 --- a/nac3core/src/toplevel/type_annotation.rs +++ b/nac3core/src/toplevel/type_annotation.rs @@ -41,6 +41,8 @@ pub fn parse_ast_to_type_annotation_kinds( Ok(TypeAnnotation::PrimitiveKind(primitives.bool)) } else if id == &"None".into() { Ok(TypeAnnotation::PrimitiveKind(primitives.none)) + } else if id == &"str".into() { + Ok(TypeAnnotation::PrimitiveKind(primitives.str)) } else if let Some(obj_id) = resolver.get_identifier_def(*id) { let type_vars = { let def_read = top_level_defs[obj_id.0].try_read(); diff --git a/nac3core/src/typecheck/type_inferencer/mod.rs b/nac3core/src/typecheck/type_inferencer/mod.rs index ce3698a3..37190934 100644 --- a/nac3core/src/typecheck/type_inferencer/mod.rs +++ b/nac3core/src/typecheck/type_inferencer/mod.rs @@ -36,6 +36,7 @@ pub struct PrimitiveStore { pub bool: Type, pub none: Type, pub range: Type, + pub str: Type, } pub struct FunctionData { @@ -731,6 +732,7 @@ impl<'a> Inferencer<'a> { let ty: Result, _> = vals.iter().map(|x| self.infer_constant(x)).collect(); Ok(self.unifier.add_ty(TypeEnum::TTuple { ty: ty? })) } + ast::Constant::Str(_) => Ok(self.primitives.str), _ => Err("not supported".into()), } } diff --git a/nac3core/src/typecheck/type_inferencer/test.rs b/nac3core/src/typecheck/type_inferencer/test.rs index 1e5d006b..f4e3f16d 100644 --- a/nac3core/src/typecheck/type_inferencer/test.rs +++ b/nac3core/src/typecheck/type_inferencer/test.rs @@ -102,7 +102,12 @@ impl TestEnvironment { fields: HashMap::new().into(), params: HashMap::new().into(), }); - let primitives = PrimitiveStore { int32, int64, float, bool, none, range }; + let str = unifier.add_ty(TypeEnum::TObj { + obj_id: DefinitionId(6), + fields: HashMap::new().into(), + params: HashMap::new().into(), + }); + let primitives = PrimitiveStore { int32, int64, float, bool, none, range, str }; set_primitives_magic_methods(&primitives, &mut unifier); let id_to_name = [ @@ -112,6 +117,7 @@ impl TestEnvironment { (3, "bool".into()), (4, "none".into()), (5, "range".into()), + (6, "str".into()), ] .iter() .cloned() @@ -191,8 +197,13 @@ impl TestEnvironment { fields: HashMap::new().into(), params: HashMap::new().into(), }); + let str = unifier.add_ty(TypeEnum::TObj { + obj_id: DefinitionId(6), + fields: HashMap::new().into(), + params: HashMap::new().into(), + }); identifier_mapping.insert("None".into(), none); - for (i, name) in ["int32", "int64", "float", "bool", "none", "range"].iter().enumerate() { + for (i, name) in ["int32", "int64", "float", "bool", "none", "range", "str"].iter().enumerate() { top_level_defs.push( RwLock::new(TopLevelDef::Class { name: (*name).into(), @@ -208,19 +219,19 @@ impl TestEnvironment { ); } - let primitives = PrimitiveStore { int32, int64, float, bool, none, range }; + let primitives = PrimitiveStore { int32, int64, float, bool, none, range, str }; let (v0, id) = unifier.get_fresh_var(); let foo_ty = unifier.add_ty(TypeEnum::TObj { - obj_id: DefinitionId(6), + obj_id: DefinitionId(7), fields: [("a".into(), v0)].iter().cloned().collect::>().into(), params: [(id, v0)].iter().cloned().collect::>().into(), }); top_level_defs.push( RwLock::new(TopLevelDef::Class { name: "Foo".into(), - object_id: DefinitionId(6), + object_id: DefinitionId(7), type_vars: vec![v0], fields: [("a".into(), v0)].into(), methods: Default::default(), @@ -247,7 +258,7 @@ impl TestEnvironment { FunSignature { args: vec![], ret: int32, vars: Default::default() }.into(), )); let bar = unifier.add_ty(TypeEnum::TObj { - obj_id: DefinitionId(7), + obj_id: DefinitionId(8), fields: [("a".into(), int32), ("b".into(), fun)] .iter() .cloned() @@ -258,7 +269,7 @@ impl TestEnvironment { top_level_defs.push( RwLock::new(TopLevelDef::Class { name: "Bar".into(), - object_id: DefinitionId(7), + object_id: DefinitionId(8), type_vars: Default::default(), fields: [("a".into(), int32), ("b".into(), fun)].into(), methods: Default::default(), @@ -276,7 +287,7 @@ impl TestEnvironment { ); let bar2 = unifier.add_ty(TypeEnum::TObj { - obj_id: DefinitionId(8), + obj_id: DefinitionId(9), fields: [("a".into(), bool), ("b".into(), fun)] .iter() .cloned() @@ -287,7 +298,7 @@ impl TestEnvironment { top_level_defs.push( RwLock::new(TopLevelDef::Class { name: "Bar2".into(), - object_id: DefinitionId(8), + object_id: DefinitionId(9), type_vars: Default::default(), fields: [("a".into(), bool), ("b".into(), fun)].into(), methods: Default::default(), @@ -312,9 +323,10 @@ impl TestEnvironment { (3, "bool".into()), (4, "none".into()), (5, "range".into()), - (6, "Foo".into()), - (7, "Bar".into()), - (8, "Bar2".into()), + (6, "str".into()), + (7, "Foo".into()), + (8, "Bar".into()), + (9, "Bar2".into()), ] .iter() .cloned() @@ -329,9 +341,9 @@ impl TestEnvironment { let resolver = Arc::new(Resolver { id_to_type: identifier_mapping.clone(), id_to_def: [ - ("Foo".into(), DefinitionId(6)), - ("Bar".into(), DefinitionId(7)), - ("Bar2".into(), DefinitionId(8)), + ("Foo".into(), DefinitionId(7)), + ("Bar".into(), DefinitionId(8)), + ("Bar2".into(), DefinitionId(9)), ] .iter() .cloned()