def test_custom2(self): """Resolve typing on params with differents node""" source = """ @module Test { int foo; char foo; double bar; int func(int foo); double func(double foo); } int main() { int a = [Test func :[Test.foo]]; } """ print("\n~~~~~~~~~~ test_custom2 ~~~~~~~~~~\n") ast = self.parser.parse(source) runners = [visitors.linkchecks.LinkChecks(), visitors.typing.Typing()] for runner in runners: runner.register() runner.run(ast) self.assertEqual( ast.body[1].body.body[0]._assign_expr.params[0].expr_type.__dict__, nodes.PrimaryType("int").__dict__) self.assertEqual( ast.body[1].body.body[0]._assign_expr.expr_type.__dict__, nodes.PrimaryType("int").__dict__)
def get_object_virtual_methods(self): class_instance_ctype = nodes.PrimaryType('Object') class_instance_ctype.push(nodes.PointerType()) class_instance_decl = nodes.Decl('', class_instance_ctype) string_ctype = nodes.PrimaryType('char') string_ctype.push(nodes.PointerType()) string_decl = nodes.Decl('', string_ctype) virtuals = {} virtuals['isKindOf'] = [] virtuals['isInstanceOf'] = [] # int isKindOf(Class *, Class *other) isKindOf_ctype = nodes.FuncType('int', [class_instance_decl, class_instance_decl]) virtuals['isKindOf'].append(nodes.Decl('isKindOf', isKindOf_ctype)) # int isKindOf(Class *, char *name) isKindOfStr_ctype = nodes.FuncType('int', [class_instance_decl, string_decl]) virtuals['isKindOf'].append(nodes.Decl('isKindOfStr', isKindOfStr_ctype)) # int isInstanceOf(Class *, Class *other) isInstanceOf_ctype = nodes.FuncType('int', [class_instance_decl, class_instance_decl]) virtuals['isInstanceOf'].append(nodes.Decl('isInstanceOf', isInstanceOf_ctype)) # int isInstanceOf(Class *, char *name) isInstanceOfStr_ctype = nodes.FuncType('int', [class_instance_decl, string_decl]) virtuals['isInstanceOf'].append(nodes.Decl('isInstanceOfStr', isInstanceOfStr_ctype)) return virtuals
def resolve_Id(self, id_expr): """Resolve the typing for an Id node""" if (self.is_typed(id_expr)): return id_expr id_expr_type = None id_name = id_expr.value # Search among all declaration the id declaration by it's name root = self.get_root(id_expr) while root is not None: for decl in root.body: if isinstance(decl, nodes.Decl) is not True or hasattr( decl, "_name") is not True: continue elif decl._name == id_name: if id_expr_type is None: id_expr_type = nodes.PrimaryType( decl._ctype._identifier) else: raise KVisitorError( "Multiple definition of Id for the same signature for '" + id_name + "'") root = self.get_root(root) # Check if a type has been found and set it if id_expr_type is None: # we are in a function ? search in func params root = self.get_root(id_expr) while root is not None: if hasattr(root, 'parent') and root.parent(): parent = root.parent() if hasattr(parent, '_ctype') and isinstance( parent._ctype, nodes.FuncType): params = parent._ctype.params for decl in params: if isinstance(decl, nodes.Decl) is not True or hasattr( decl, "_name") is not True: continue elif decl._name == id_name: id_expr_type = nodes.PrimaryType( decl._ctype._identifier) root = self.get_root(root) if id_expr_type is None: raise KVisitorError("Cant find any definition of Id '" + id_name + "'") else: id_expr.expr_type = id_expr_type else: id_expr.expr_type = id_expr_type return id_expr
def test_param_Func(self): """Resolve typing on param with Func node""" source = """ @module Test { void func(int var); void func(double var); void func(); } int titi(); int main() { double toto(); [Test func :titi()]; [Test func :toto()]; [Test func]; } """ print("\n~~~~~~~~~~ test_Param_Func ~~~~~~~~~~\n") ast = self.parser.parse(source) runners = [visitors.linkchecks.LinkChecks(), visitors.typing.Typing()] for runner in runners: runner.register() runner.run(ast) # Check funcInt funcInt = ast.body[2].body.body[1].expr self.assertEqual( funcInt.expr_type.__dict__, nodes.PrimaryType("void").__dict__) # Function return type self.assertEqual( funcInt.params[0].expr_type.__dict__, nodes.PrimaryType("int").__dict__) # Function param0 type # Check funcFloat funcDouble = ast.body[2].body.body[2].expr self.assertEqual( funcDouble.expr_type.__dict__, nodes.PrimaryType("void").__dict__) # Function return type self.assertEqual( funcDouble.params[0].expr_type.__dict__, nodes.PrimaryType("double").__dict__) # Function param0 type # Check funcVoid funcVoid = ast.body[2].body.body[3].expr self.assertEqual( funcDouble.expr_type.__dict__, nodes.PrimaryType("void").__dict__) # Function return type
def test_param_KcLookup(self): """Resolve typing on one param with KcLookup node""" source = """ @module Test { int foo = 42; double bar = 42.42; void funcInt(int var); void funcDouble(double var); void funcVoid(); } int main() { [Test funcInt :[Test.foo]]; [Test funcDouble :[Test.bar]]; [Test funcVoid]; } """ print("\n~~~~~~~~~~ test_param_KcLookup ~~~~~~~~~~\n") ast = self.parser.parse(source) runners = [visitors.linkchecks.LinkChecks(), visitors.typing.Typing()] for runner in runners: runner.register() runner.run(ast) # Check funcInt funcInt = ast.body[1].body.body[0].expr self.assertEqual( funcInt.expr_type.__dict__, nodes.PrimaryType("void").__dict__) # Function return type self.assertEqual( funcInt.params[0].expr_type.__dict__, nodes.PrimaryType("int").__dict__) # Function param0 type # Check funcFloat funcDouble = ast.body[1].body.body[1].expr self.assertEqual( funcDouble.expr_type.__dict__, nodes.PrimaryType("void").__dict__) # Function return type self.assertEqual( funcDouble.params[0].expr_type.__dict__, nodes.PrimaryType("double").__dict__) # Function param0 type # Check funcVoid funcVoid = ast.body[1].body.body[2].expr self.assertEqual( funcVoid.expr_type.__dict__, nodes.PrimaryType("void").__dict__) # Function return type
def resolve_KcCall(self, kccall_expr): """Resolve the typing for a KcCall node""" if (self.is_typed(kccall_expr)): return kccall_expr kccall_expr.params = self.resolve_params(kccall_expr.params) kccall_expr_type = list() kccall_name = kccall_expr.function # Search among the context the KcCall declarations by it's name for decl in kccall_expr.context().body: if isinstance(decl, nodes.Decl) is not True or isinstance( decl._ctype, nodes.FuncType) is not True: continue elif decl._name == kccall_name and len(decl._ctype.params) == len( kccall_expr.params) and self.compare_params_type_KcCall( kccall_expr.params, decl._ctype.params) is True: kccall_expr_type.append( nodes.PrimaryType(decl._ctype._identifier)) # Check if at least a type has been found and set them if len(kccall_expr_type) <= 0: raise KVisitorError( "Cant find any definition of KcCall '" + kccall_name + "'") # TODO : Precise the params as criteria for search else: if len(kccall_expr_type) == 1: kccall_expr.expr_type = kccall_expr_type[0] else: kccall_expr.expr_type = kccall_expr_type if isinstance(kccall_expr.expr_type, list) is not True: kccall_expr = self.set(kccall_expr, kccall_expr.expr_type) return kccall_expr
def resolve_KcLookup(self, kclookup_expr): """Resolve the typing for KcLookup node""" if self.is_typed(kclookup_expr) is True: return kclookup_expr kclookup_expr_type = list() kclookup_name = kclookup_expr.member # Search among the context the KcLookup declarations by it's name and add the expr_type found for decl in kclookup_expr.context().body: if isinstance(decl, nodes.Decl) is not True or hasattr( decl, "_name") is not True: continue elif decl._name == kclookup_name: kclookup_expr_type.append( nodes.PrimaryType(decl._ctype._identifier)) # Check if at least a type has been found and set them if len(kclookup_expr_type) <= 0: raise KVisitorError("Cant find any definition of KcLookup '" + kclookup_name + "'") else: if len(kclookup_expr_type) == 1: kclookup_expr.expr_type = kclookup_expr_type[0] else: kclookup_expr.expr_type = kclookup_expr_type return kclookup_expr
def build_interface_struct(self, klass): interface_struct_ctype = nodes.ComposedType('kc_' + klass.name + '_interface') interface_struct_ctype._specifier = nodes.Specifiers.STRUCT interface_struct_ctype._attr_composed = ['__attribute__((packed))'] interface_struct_ctype.fields = [] # meta field meta_ctype = nodes.PrimaryType('kc_' + klass.name + '_metadata') meta_ctype.push(nodes.PointerType()) interface_struct_ctype.fields.append(nodes.Decl('meta', meta_ctype)) # instance field instance_ctype = nodes.PrimaryType('kc_' + klass.name + '_instance') interface_struct_ctype.fields.append(nodes.Decl('instance', instance_ctype)) return nodes.Decl('', interface_struct_ctype)
def build_metadata_struct(self, klass): struct_ctype = nodes.ComposedType('kc_' + klass.name + '_metadata') struct_ctype._specifier = nodes.Specifiers.STRUCT struct_ctype._attr_composed = ['__attribute__((packed))'] struct_ctype.fields = [] # class name cname_ctype = nodes.PrimaryType('char') cname_ctype.push(nodes.PointerType()) struct_ctype.fields.append(nodes.Decl('name', cname_ctype)) # inheritance list inhlist_ctype = nodes.PrimaryType('char') inhlist_ctype.push(nodes.PointerType()) struct_ctype.fields.append(nodes.Decl('inheritance_list', inhlist_ctype)) # vtable vtable_ctype = nodes.PrimaryType('kc_' + klass.name + '_vtable') struct_ctype.fields.append(nodes.Decl('vtable', vtable_ctype)) return nodes.Decl('', struct_ctype)
def test_params_Id(self): """Resolve typing on multiple params with Id nodes""" source = """ @module Test { void funcIntDouble(int foo, double bar); void funcDoubleInt(double foo, int bar); } int main() { int foo = 42; double bar = 42.42; [Test funcIntDouble :foo :bar]; [Test funcDoubleInt :bar :foo]; } """ print("\n~~~~~~~~~~ test_params_Id ~~~~~~~~~~\n") ast = self.parser.parse(source) runners = [visitors.linkchecks.LinkChecks(), visitors.typing.Typing()] for runner in runners: runner.register() runner.run(ast) # Check funcInt funcIntDouble = ast.body[1].body.body[2].expr self.assertEqual( funcIntDouble.expr_type.__dict__, nodes.PrimaryType("void").__dict__) # Function return type self.assertEqual( funcIntDouble.params[0].expr_type.__dict__, nodes.PrimaryType("int").__dict__) # Function param0 type self.assertEqual( funcIntDouble.params[1].expr_type.__dict__, nodes.PrimaryType("double").__dict__) # Function param1 type # Check funcFloat funcDoubleInt = ast.body[1].body.body[3].expr self.assertEqual( funcDoubleInt.expr_type.__dict__, nodes.PrimaryType("void").__dict__) # Function return type self.assertEqual( funcDoubleInt.params[0].expr_type.__dict__, nodes.PrimaryType("double").__dict__) # Function param0 type self.assertEqual( funcDoubleInt.params[1].expr_type.__dict__, nodes.PrimaryType("int").__dict__) # Function param1 type
def new_decl_spec(self, lspec, i, current_block): idsetval = "" i_value = self.value(i) if i_value in Idset: idsetval = Idset[i_value] # don't f**k with reserved keywords if idsetval == "reserved": return False # not for asm or attribute if idsetval != "" and idsetval[0] != 'a': lspec.ctype = nodes.makeCType(i_value, lspec.ctype) return True if ((hasattr(current_block.ref, 'types') and i_value in current_block.ref.types)): if lspec.ctype is None: lspec.ctype = nodes.PrimaryType(i_value) else: lspec.ctype._identifier = i_value lspec.ctype._identifier = i_value return True return False
def test_params_Unary(self): """Resolve typing on params with Unary nodes""" source = """ @module Test { void func(int foo, double bar); void func(double foo, int bar); } int main() { [Test func :-(1 ? 42+42 : 42+42) :-(1 ? 42.42+42.42 : 42.42+42.42)]; [Test func :-(1 ? 42.42+42.42 : 42.42+42.42) :-(1 ? 42+42 : 42+42)]; } """ print("\n~~~~~~~~~~ test_param_Unary ~~~~~~~~~~\n") ast = self.parser.parse(source) runners = [visitors.linkchecks.LinkChecks(), visitors.typing.Typing()] for runner in runners: runner.register() runner.run(ast) # Check funcInt funcInt = ast.body[1].body.body[0].expr self.assertEqual( funcInt.expr_type.__dict__, nodes.PrimaryType("void").__dict__) # Function return type self.assertEqual( funcInt.params[0].expr_type.__dict__, nodes.PrimaryType("int").__dict__) # Function param0 type self.assertEqual( funcInt.params[1].expr_type.__dict__, nodes.PrimaryType("double").__dict__) # Function param1 type # Check funcFloat funcDouble = ast.body[1].body.body[1].expr self.assertEqual( funcDouble.expr_type.__dict__, nodes.PrimaryType("void").__dict__) # Function return type self.assertEqual( funcDouble.params[0].expr_type.__dict__, nodes.PrimaryType("double").__dict__) # Function param0 type self.assertEqual( funcDouble.params[1].expr_type.__dict__, nodes.PrimaryType("int").__dict__) # Function param1 type
def resolve_Func(self, func_expr): """Resolve the typing for an Func node""" if (self.is_typed(func_expr)): return func_expr func_expr_type = None func_name = func_expr.call_expr.value # Search among all declaration the func declaration by it's name root = self.get_root(func_expr) while root is not None: for decl in root.body: if isinstance(decl, nodes.Decl) is not True or hasattr( decl, "_name") is not True: continue elif decl._name == func_name: if func_expr_type is None: func_expr_type = nodes.PrimaryType( decl._ctype._identifier) else: raise KVisitorError( "Multiple definition of Func for the same signature for '" + func_name + "'") root = self.get_root(root) # Check if a type has been found and set it if func_expr_type is None: raise KVisitorError("Cant find any definition of Func '" + func_name + "'") else: func_expr.expr_type = func_expr_type if isinstance(func_expr.expr_type, list) is not True: func_expr = self.set(func_expr, func_expr.expr_type) return func_expr
def func_add_param_self(func, class_name): instance_type = nodes.PrimaryType(class_name) instance_type.push(nodes.PointerType()) self_param = nodes.Decl('self', instance_type) func._params.insert(0, self_param)
def kc_new_literal_char(self, ast, val): ast.set(knodes.KcTypedLiteral(self.value(val), nodes.PrimaryType('char'))) return True
def kc_new_literal_string(self, ast, val): string_type = nodes.PrimaryType('char') string_type.push(nodes.PointerType()) ast.set(knodes.KcTypedLiteral(self.value(val), string_type)) return True
def test_01_basicdecl(self): """Test cnorm nodes construction""" d = nodes.Decl('a') self.assertEqual(str(d.to_c()), "int a;\n", "Failed to convert to C") vars(d)["_name"] = 'b' qual = d.ctype qual = qual.link(nodes.PointerType()) qual = qual.link(nodes.QualType(nodes.Qualifiers.VOLATILE)) self.assertEqual(str(d.to_c()), "volatile int *b;\n", "Failed to convert to C") vars(d)["_name"] = 'c' qual = d.ctype qual = qual.link(nodes.QualType(nodes.Qualifiers.CONST)) qual = qual.link(nodes.PointerType()) qual = qual.link(nodes.QualType(nodes.Qualifiers.VOLATILE)) self.assertEqual(str(d.to_c()), "volatile int *const c;\n", "Failed to convert to C") vars(d)["_name"] = 'd' qual = d.ctype qual = qual.link(nodes.PointerType()) qual = qual.link(nodes.ParenType()) qual = qual.link(nodes.QualType(nodes.Qualifiers.CONST)) qual = qual.link(nodes.PointerType()) qual = qual.link(nodes.QualType(nodes.Qualifiers.VOLATILE)) self.assertEqual(str(d.to_c()), "volatile int *const (*d);\n", "Failed to convert to C") vars(d)["_name"] = 'e' qual = d.ctype qual = qual.link(nodes.ArrayType()) qual = qual.link(nodes.ArrayType()) qual = qual.link(nodes.PointerType()) qual = qual.link(nodes.ParenType()) qual = qual.link(nodes.QualType(nodes.Qualifiers.CONST)) qual = qual.link(nodes.PointerType()) qual = qual.link(nodes.QualType(nodes.Qualifiers.VOLATILE)) self.assertEqual(str(d.to_c()), "volatile int *const (*e[][]);\n", "Failed to convert to C") d = nodes.Decl('tf', nodes.PrimaryType('double')) qual = d.ctype qual = qual.link(nodes.ArrayType()) qual = qual.link(nodes.QualType(nodes.Qualifiers.CONST)) self.assertEqual(str(d.to_c()), "const double tf[];\n", "Failed to convert to C") ft = nodes.FuncType('double', [ nodes.Decl('a', nodes.PrimaryType('size_t')), nodes.Decl('b', nodes.PrimaryType('int')) ]) f = nodes.Decl('f', ft) self.assertEqual(str(f.to_c()), "double f(size_t a, int b);\n", "Failed to convert to C") f = nodes.Decl('f', nodes.PrimaryType('double')) qual = f.ctype qual = qual.link(nodes.PointerType()) qual = qual.link( nodes.ParenType([ nodes.Decl('a', nodes.PrimaryType('size_t')), nodes.Decl('b', nodes.PrimaryType('int')) ])) self.assertEqual(str(f.to_c()), "double (*f)(size_t a, int b);\n", "Failed to convert to C") ft2 = nodes.FuncType('double', [nodes.Decl('p', nodes.PrimaryType('ext_func'))]) f2 = nodes.Decl('f2', ft2) qual = f2.ctype qual = qual.link(nodes.PointerType()) qual = qual.link( nodes.ParenType([ nodes.Decl('a', nodes.PrimaryType('size_t')), nodes.Decl('b', nodes.PrimaryType('int')) ])) self.assertEqual(str(f2.to_c()), "double (*f2(ext_func p))(size_t a, int b);\n", "Failed to convert to C") ## test CTYPE construction ctype = nodes.makeCType('int') d = nodes.Decl('ghh', ctype) self.assertEqual(str(d.to_c()), "int ghh;\n", "Failed to convert to C") ctype = nodes.makeCType('const') ctype = nodes.makeCType('double', ctype) d = nodes.Decl('ghh', ctype) self.assertEqual(str(d.to_c()), "const double ghh;\n", "Failed to convert to C") ctype = nodes.makeCType('__int8', ctype) ctype = nodes.makeCType('__unsigned__', ctype) ctype = nodes.makeCType('extern', ctype) d = nodes.Decl('ghh', ctype) self.assertEqual(str(d.to_c()), "extern const unsigned __int8 ghh;\n", "Failed to convert to C") d = nodes.Decl('GG', nodes.PrimaryType('XXX')) qual = d.ctype qual = qual.link(nodes.QualType(nodes.Qualifiers.CONST)) qual = qual.link(nodes.PointerType()) qual = qual.link(nodes.ParenType()) qual = qual.link(nodes.ArrayType(nodes.Literal("12"))) qual = qual.link(nodes.ParenType()) qual = qual.link(nodes.ArrayType(nodes.Literal("66"))) self.assertEqual(str(d.to_c()), "XXX ((*const GG)[12])[66];\n", "Failed to convert to C") ft = nodes.FuncType('HHHHH', [ nodes.Decl('a', nodes.PrimaryType('size_t')), nodes.Decl('b', nodes.PrimaryType('int')) ]) d = nodes.Decl('func', ft) self.assertEqual(str(d.to_c()), "HHHHH func(size_t a, int b);\n", "Failed to convert to C")
def add_typeof(self, lspec, tof): lspec.ctype = nodes.PrimaryType("typeof" + self.value(tof)) return True