def create_typedef_vt(): d = Declaration() res = d.parse( ''' typedef struct _kc_Object Object; struct _kc_vt_Object { void (*clean)(Object *); int (*isKindOf)(Object *, const char *); int (*isKindOf)(Object *, Object *); int (*isInstanceOf)(Object *, const char *); int (*isInstanceOf)(Object *, Object *); }; ''') res2 = d.parse( ''' typedef struct _kc_Object Object; void clean(Object *); int isKindOf(Object *, const char *); int isKindOf(Object *, Object *); int isInstanceOf(Object *, const char *); int isInstanceOf(Object *, Object *); ''') res2.body.pop(0) for decl in res.body: if isinstance(decl._ctype, cnorm.nodes.ComposedType) and decl._ctype._identifier == '_kc_vt_Object': for (dcl, proto) in zip(decl._ctype.fields, res2.body): dcl._name = mangler.mimpleSangle(proto) global typedef_vt_object typedef_vt_object = decl
def add_legacy_fcts(self): d = Declaration() res = d.parse(""" typedef struct _kc_%s %s; void delete(%s*); """ % (self.ident, self.ident, self.ident)) decl = res.body[1] decl._name = mangler.muckFangle(decl, self.ident) setattr(decl, 'saved_name', 'delete') self.members.append(decl)
def add_new_proto(self, decl): d = Declaration() res = d.parse(""" typedef struct _kc_%s %s; %s *new(%s); """ % (self.ident, self.ident, self.ident, ', '.join([str(c.to_c()).rstrip() for c in decl._ctype.params]).replace(';', ''))) dcl = res.body[1] dcl._name = mangler.muckFangle(dcl, self.ident) setattr(decl, 'saved_name', 'new') self.protos.append(dcl)
def add_new_proto(self, decl): d = Declaration() res = d.parse(""" typedef struct _kc_%s %s; %s *new(%s); """ % (self.ident, self.ident, self.ident, ', '.join( [str(c.to_c()).rstrip() for c in decl._ctype.params]).replace(';', ''))) dcl = res.body[1] dcl._name = mangler.muckFangle(dcl, self.ident) setattr(decl, 'saved_name', 'new') self.protos.append(dcl)
def instanciate_vtable(): global implementations d = Declaration() res = d.parse(""" typedef struct _kc_Object Object; typedef struct _kc_vt_Object vt_Object; vt_Object vtable_Object = {&clean, &isKindOf, &isKindOf, &isInstanceOf, &isInstanceOf}; """) for decl in res.body: if hasattr(decl, '_name') and decl._name == 'vtable_Object': for (elem, imp) in zip(decl._assign_expr.body, implementations[0].imps): elem.params[0].value = imp._name global obj_vtable obj_vtable = decl return decl return None
def new_scope(self): from kooc import glist global glist global scope global isscope global decl from mangle import mangle from implementation import implement isscope = True scope = decl if not hasattr(glist, scope): glist[scope] = [] if implement["type"] == "CM": parse = Declaration() nod = parse.parse("struct " + implement["name"] + " * self;") glist[scope].append(mangle(nod.body[0], "nonename", "M")) return True
def create_alloc_fct(self): d = Declaration() res = d.parse(""" typedef struct _kc_%s %s; %s *alloc() { %s *self; self = malloc(sizeof(%s)); return (self); } """ % (self.ident, self.ident, self.ident, self.ident, self.ident)) for decl in res.body: if isinstance(decl._ctype, cnorm.nodes.FuncType): decl._name = mangler.muckFangle(decl, self.ident) self.alloc_fct = decl self.imps.append(decl)
def create_decl_malloc(self, inheri): size = len(inheri) lDecl = [] d = Declaration() res = d.parse( """ typedef struct _kc_Object Object; typedef struct _kc_%s %s; void dummy() { %s* self; ((Object *)self)->vt = &vtable_%s; ((Object *)self)->inheritance = malloc((%d + 1) * sizeof(char *)); ((Object *)self)->inheritance[%d] = "YOLO"; ((Object *)self)->inheritance[%d] = 0; } """ % (self.ident, self.ident, self.ident, self.ident, size, size, size)) for decl in res.body: if hasattr(decl, '_name') and decl._name == 'dummy': for dcl in decl.body.body: if isinstance(dcl, cnorm.nodes.ExprStmt): if isinstance( dcl.expr.params[len(dcl.expr.params) - 1], cnorm.nodes.Literal): if dcl.expr.params[len(dcl.expr.params) - 1].value == '0': declNull = dcl else: declToChange = dcl else: lDecl.append(dcl) declTmp = declToChange for idx, decl in enumerate(inheri): for dcl in declTmp.expr.params: if isinstance(dcl, cnorm.nodes.Literal): dcl.value = ("\"" + decl + "\"") declTmp.expr.params[0].params[0].value = str(idx) lDecl.append(deepcopy(declTmp)) lDecl.append(declNull) return lDecl
def create_delete_fct(self): d = Declaration() res = d.parse(""" typedef struct _kc_Object Object; typedef struct _kc_%s %s; typedef struct _kc_vt_%s vt_%s; void delete(%s *self) { ((vt_%s*)((Object*)self)->vt)->clean(self); } """ % (self.ident, self.ident, self.ident, self.ident, self.ident, self.ident)) for decl in res.body: if isinstance(decl._ctype, cnorm.nodes.FuncType): decl._name = mangler.muckFangle(decl, self.ident) for dcl in decl.body.body: if hasattr(dcl.expr, 'call_expr') and hasattr(dcl.expr.call_expr, 'params') \ and dcl.expr.call_expr.params[0].value == 'clean': dcl.expr.call_expr.params[0].value = 'clean$$void' self.imps.append(decl)
def create_new_fct(self, ini): params = [] if len(ini._ctype._params) >= 1: params = ini._ctype._params[1:] d = Declaration() res = d.parse(""" typedef struct _kc_Object Object; typedef struct _kc_%s %s; %s *new(%s) { %s* self; self = alloc(); init(self, %s); ((Object*)self)->name = "%s"; return (self); } """ % (self.ident, self.ident, self.ident, ', '.join( [str(c.to_c()).rstrip() for c in params]).replace(';', ''), self.ident, ', '.join( [c._name for c in params]), self.ident)) for decl in res.body: if hasattr(decl, '_name') and decl._name == 'new': decl._name = mangler.muckFangle(decl, self.ident) decl.body.body[4:4] = self.create_decl_malloc( self.get_inheritance(self.ident, [])) for dcl in decl.body.body: if isinstance(dcl, cnorm.nodes.ExprStmt): if isinstance(dcl.expr, cnorm.nodes.Binary) and\ (isinstance(dcl.expr.params[0], cnorm.nodes.Arrow) or \ isinstance(dcl.expr.params[0], cnorm.nodes.Array)): pass elif isinstance(dcl.expr, cnorm.nodes.Binary): dcl.expr.params[ 1].call_expr.value = self.alloc_fct._name elif isinstance(dcl.expr, cnorm.nodes.Func): dcl.expr.call_expr.value = ini._name self.imps.append(decl)
def create_new_fct(self, ini): params = [] if len(ini._ctype._params) >= 1: params = ini._ctype._params[1:] d = Declaration() res = d.parse(""" typedef struct _kc_Object Object; typedef struct _kc_%s %s; %s *new(%s) { %s* self; self = alloc(); init(self, %s); ((Object*)self)->name = "%s"; return (self); } """ % (self.ident, self.ident, self.ident, ', '.join([str(c.to_c()).rstrip() for c in params]).replace(';', ''), self.ident, ', '.join([c._name for c in params]), self.ident)) for decl in res.body: if hasattr(decl, '_name') and decl._name == 'new': decl._name = mangler.muckFangle(decl, self.ident) decl.body.body[4:4] = self.create_decl_malloc(self.get_inheritance(self.ident, [])) for dcl in decl.body.body: if isinstance(dcl, cnorm.nodes.ExprStmt): if isinstance(dcl.expr, cnorm.nodes.Binary) and\ (isinstance(dcl.expr.params[0], cnorm.nodes.Arrow) or \ isinstance(dcl.expr.params[0], cnorm.nodes.Array)): pass elif isinstance(dcl.expr, cnorm.nodes.Binary): dcl.expr.params[1].call_expr.value = self.alloc_fct._name elif isinstance(dcl.expr, cnorm.nodes.Func): dcl.expr.call_expr.value = ini._name self.imps.append(decl)
def add_call(self, call, mod, var, spe): from kooc import mlist, clist, slist, glist from drecovery import scope global mlist global slist global clist global glist global scope scope_list = [] type_object = "" ptr = "" if mod.value in mlist: scope_list = mlist type_object = "M" elif mod.value in clist: scope_list = clist type_object = "C" else: tmp = None for item in glist[scope]: if item["name"] == mod.value and len(item["type"]) > 3 and item["type"][:3] == "2Sp": if item["type"][3:] in clist: tmp = item break if tmp == None: print_error("error no module called : " + mod.value) return False scope_list = slist ptr = mod.value + "->" mod.value = tmp["type"][3:] type_object = "CM" if spe.value == "": return algo(call, mod, var, scope_list, ptr) else: cparse = Declaration() ast = cparse.parse(spe.value + " " + var.value + ";") m = mangle(ast.body[0], mod.value, type_object)["mangle"] return algo_spe(call, mod, var, m, scope_list, ptr) return True
def new_dcl(self, decl): from kooc import glist, mlist, clist, vlist from copy import deepcopy from mangle import mangle from implementation import implement global glist global scope global isscope global implement if isscope == True and implement["name"] != "": m = mangle(decl.node, implement["name"], implement["type"]) test = clist if implement["type"] == "M": test = mlist if implement["type"] == "CM": parse = Declaration() nod = parse.parse("struct " + implement["name"] + " * self;") decl.node._ctype._params.append(nod.body[0]) test = vlist found = False for item in test[implement["name"]]: if item["mangle"] == m["mangle"]: found = True if found == False: print_error("Error function not declared :" + implement["name"] + " " + m["name"]) return False else: tmp = deepcopy(decl) m = mangle(tmp.node, "nonename", "M") for item in glist[scope]: if item["mangle"].split("_")[3] == "F": if item["mangle"] == m["mangle"]: return True glist[scope].append(m) isscope = False return True
def create_decl_malloc(self, inheri): size = len(inheri) lDecl = [] d = Declaration() res = d.parse(""" typedef struct _kc_Object Object; typedef struct _kc_%s %s; void dummy() { %s* self; ((Object *)self)->vt = &vtable_%s; ((Object *)self)->inheritance = malloc((%d + 1) * sizeof(char *)); ((Object *)self)->inheritance[%d] = "YOLO"; ((Object *)self)->inheritance[%d] = 0; } """ % (self.ident, self.ident, self.ident, self.ident, size, size, size)) for decl in res.body: if hasattr(decl, '_name') and decl._name == 'dummy': for dcl in decl.body.body: if isinstance(dcl, cnorm.nodes.ExprStmt): if isinstance(dcl.expr.params[len(dcl.expr.params) - 1], cnorm.nodes.Literal): if dcl.expr.params[len(dcl.expr.params) - 1].value == '0': declNull = dcl else: declToChange = dcl else: lDecl.append(dcl) declTmp = declToChange for idx, decl in enumerate(inheri): for dcl in declTmp.expr.params: if isinstance(dcl, cnorm.nodes.Literal): dcl.value = ("\"" + decl + "\"") declTmp.expr.params[0].params[0].value = str(idx) lDecl.append(deepcopy(declTmp)) lDecl.append(declNull) return lDecl
class UnittestModule(unittest.TestCase): def setUp(self): self.cparse = Declaration() self.kparse = KoocG() def tearDown(self): self.cparse = None self.kparse = None KoocFile.debugCleanAll() if hasattr(self, "res") and not hasattr(self.res, "to_c"): self.assertFalse(self.res.diagnostic.get_content()) ## SIMPLE TO MORE COMPLEX TEST OF VALIDS MODULES def test_empty_module(self): self.res = self.kparse.parse(""" @module Test { } """) self.assertEqual(str(self.res.to_c()), "") def test_declaration_variable(self): self.res = self.kparse.parse(""" @module Test { void test; } """) self.assertEqual(str(self.res.to_c()), "extern void M4Test__v4test;\n") def test_declaration_assignement_variable(self): self.res = self.kparse.parse(""" @module Test { int test = 42; } """) self.assertEqual(str(self.res.to_c()), "extern int M4Test__i4test;\n") def test_declaration_function_implicit_void(self): self.res = self.kparse.parse(""" @module Test { void test(); } """) self.assertEqual(str(self.res.to_c()), "extern void M4Test__v4testv();\n") def test_declaration_function_explicit_void(self): self.res = self.kparse.parse(""" @module Test { void test(void); } """) self.assertEqual(str(self.res.to_c()), "extern void M4Test__v4testv(void);\n") def test_declaration_function(self): self.res = self.kparse.parse(""" @module Test { char *test(int **toto, float tata[]); } """) self.assertEqual( str(self.res.to_c()), "extern char *M4Test__Pc4testPPiAf(int **toto, float tata[]);\n") def test_variable_overload(self): self.res = self.kparse.parse(""" @module Mayuri { int tuturu; float tuturu; } """) self.assertEqual( str(self.res.to_c()), "extern int M6Mayuri__i6tuturu;\nextern float M6Mayuri__f6tuturu;\n" ) def test_variable_and_function_with_no_param(self): self.res = self.kparse.parse(""" @module Mayuri { int tuturu; int tuturu(); } """) self.assertEqual( str(self.res.to_c()), "extern int M6Mayuri__i6tuturu;\nextern int M6Mayuri__i6tuturuv();\n" ) def test_function_return_value_overload(self): self.res = self.kparse.parse(""" @module Mayuri { int tuturu(float toto); float tuturu(float tutu); } """) self.assertEqual( str(self.res.to_c()), "extern int M6Mayuri__i6tuturuf(float toto);\n\ extern float M6Mayuri__f6tuturuf(float tutu);\n") def test_function_params_value_overload(self): self.res = self.kparse.parse(""" @module Mayuri { double **tuturu(char toto[], void* ptr[]); double** tuturu(int tutu); } """) self.assertEqual( str(self.res.to_c()), "extern double **M6Mayuri__PPd6tuturuAcAPv(char toto[], void *ptr[]);\n\ extern double **M6Mayuri__PPd6tuturui(int tutu);\n") ## TODO : TESTS WITH SOME FUNCTION POINTER ## TEST OF OVERLOADS WITH DIFFERENTS STORAGES, QUALIFIERS OR SPECIFIER def test_auto_variable(self): waited = self.cparse.parse(""" extern auto int M4Test__i4test; """) self.res = self.kparse.parse(""" @module Test { auto int test; } """) self.assertEqual(str(self.res.to_c()), str(waited.to_c())) def test_register_variable(self): waited = self.cparse.parse(""" extern register int M4Test__i4test; """) self.res = self.kparse.parse(""" @module Test { register int test; } """) self.assertEqual(str(self.res.to_c()), str(waited.to_c())) def test_typedef_variable(self): waited = self.cparse.parse(""" extern typedef int M4Test__i4test; """) self.res = self.kparse.parse(""" @module Test { typedef int test; } """) self.assertEqual(str(self.res.to_c()), str(waited.to_c())) def test_static_variable(self): waited = self.cparse.parse(""" extern static int M4Test__i4test; """) self.res = self.kparse.parse(""" @module Test { static int test; } """) self.assertEqual(str(self.res.to_c()), str(waited.to_c())) def test_extern_variable(self): waited = self.cparse.parse(""" extern extern int M4Test__i4test; """) self.res = self.kparse.parse(""" @module Test { extern int test; } """) self.assertEqual(str(self.res.to_c()), str(waited.to_c())) def test_inline_variable(self): with self.assertRaises(KoocException) as cm: print( self.kparse.parse(""" @module Test { inline int test; } """)) # def test_virtual_variable(self): # waited = self.cparse.parse(""" # extern virtual int M4Test__i4test; # """) # self.res = self.kparse.parse( # """ # @module Test # { # virtual int test; # } # """) # self.assertEqual(str(self.res.to_c()), str(waited.to_c())) # def test_explicit_variable(self): # waited = self.cparse.parse(""" # extern explicit int M4Test__i4test; # """) # self.res = self.kparse.parse( # """ # @module Test # { # explicit int test; # } # """) # self.assertEqual(str(self.res.to_c()), str(waited.to_c())) # def test_forceinline_variable(self): # waited = self.cparse.parse(""" # extern forceinline int M4Test__i4test; # """) # self.res = self.kparse.parse( # """ # @module Test # { # forceinline int test; # } # """) # self.assertEqual(str(self.res.to_c()), str(waited.to_c())) # def test_thread_variable(self): # waited = self.cparse.parse(""" # extern thread int M4Test__i4test; # """) # self.res = self.kparse.parse( # """ # @module Test # { # thread int test; # } # """) # self.assertEqual(str(self.res.to_c()), str(waited.to_c())) def test_volatile_variable(self): waited = self.cparse.parse(""" extern volatile int M4Test__V_i4test; """) self.res = self.kparse.parse(""" @module Test { volatile int test; } """) self.assertEqual(str(self.res.to_c()), str(waited.to_c())) def test_restrict_variable(self): waited = self.cparse.parse(""" extern restrict int M4Test__R_i4test; """) self.res = self.kparse.parse(""" @module Test { restrict int test; } """) self.assertEqual(str(self.res.to_c()), str(waited.to_c())) def test_long_variable(self): waited = self.cparse.parse(""" extern long int M4Test__li4test; """) self.res = self.kparse.parse(""" @module Test { long int test; } """) self.assertEqual(str(self.res.to_c()), str(waited.to_c())) def test_long_long_variable(self): waited = self.cparse.parse(""" extern long long int M4Test__lli4test; """) self.res = self.kparse.parse(""" @module Test { long long int test; } """) self.assertEqual(str(self.res.to_c()), str(waited.to_c())) def test_short_variable(self): waited = self.cparse.parse(""" extern short int M4Test__si4test; """) self.res = self.kparse.parse(""" @module Test { short int test; } """) self.assertEqual(str(self.res.to_c()), str(waited.to_c())) def test_const_ptr_variable(self): waited = self.cparse.parse(""" extern const int *M4Test__PC_i4test; """) self.res = self.kparse.parse(""" @module Test { int const* test; } """) self.assertEqual(str(self.res.to_c()), str(waited.to_c())) def test_complex_variable(self): self.res = self.kparse.parse(""" @module Test { auto unsigned int const* const* test; } """) waited = self.cparse.parse(""" extern auto unsigned int const* const* M4Test__PC_PC_Ui4test; """) self.assertEqual(str(self.res.to_c()), str(waited.to_c()))
class UnittestKooccall(unittest.TestCase): def setUp(self): self.cparse = Declaration() self.kparse = KoocG() def tearDown(self): self.cparse = None self.kparse = None KoocFile.debugCleanAll() if hasattr(self, "res") and not hasattr(self.res, "to_c"): self.assertFalse(self.res.diagnostic.get_content()) def test_simple_function_call(self): self.res = self.kparse.parse( """ @module Test { int test(void); } int main() { [Test test]; } """) waited = self.cparse.parse(""" extern int M4Test__i4testv(void); int main() { M4Test__i4testv(); } """) self.assertEqual(str(self.res.to_c()), str(waited.to_c())) def test_simple_variable_call(self): self.res = self.kparse.parse( """ @module Test { int test; } int main() { [Test.test]; } """) waited = self.cparse.parse(""" extern int M4Test__i4test; int main() { M4Test__i4test; } """) self.assertEqual(str(self.res.to_c()), str(waited.to_c())) def test_complex_variable_call(self): self.res = self.kparse.parse( """ @module Test { auto unsigned int const* const* test; } int main() { [Test.test]; } """) #TODO : c'est quoi le mangling de cette merde ? waited = self.cparse.parse(""" extern const unsigned int *const *M4Test__PC_PC_Ui4test; int main() { M4Test__PC_PC_Ui4test; } """) self.assertEqual(str(self.res.to_c()), str(waited.to_c())) # def test_simple_variable_call(self): # self.res = self.kparse.parse( # """ # int main() # { # [Test.test]; # } # """) # print(res.diagnostic.get_content()) # waited = self.cparse.parse(""" # M4Test__i4test; # """).to_c()) # print("RESULT = ", res, "\n") # print("WAITED = ", waited, "\n") # self.assertEqual(res, waited) def test_simple_variable_assign_call(self): self.res = self.kparse.parse( """ @module Test { int test; } int main() { int a = [Test.test]; } """) waited = self.cparse.parse(""" extern int M4Test__i4test; int main() { int a = M4Test__i4test; } """) self.assertEqual(str(self.res.to_c()), str(waited.to_c())) def test_function_one_arg_call(self): self.res = self.kparse.parse( """ @module Test { int test(int toto); } int main() { [Test test :(int)42]; } """) waited = self.cparse.parse(""" extern int M4Test__i4testi(int toto); int main() { M4Test__i4testi(42); } """) self.assertEqual(str(self.res.to_c()), str(waited.to_c())) def test_function_one_arg_call_invalid_arg_type(self): self.res = self.kparse.parse( """ @module Test { int test(int toto); } int main() { [Test test :(invalid)42]; } """) waited = self.cparse.parse(""" extern int M4Test__i4testi(int toto); int main() { M4Test__i4testi(42); } """) self.assertEqual(str(self.res.to_c()), str(waited.to_c())) def test_function_two_arg_call(self): self.res = self.kparse.parse( """ @module Titor { void send_dmail(void *this, char *mail); } int main() { char *mail = "Watashi wa mad scientist !"; @!(void)[Titor send_dmail :(void *)0 :(char *)mail]; } """) waited = self.cparse.parse(""" extern void M5Titor__v10send_dmailPvPc(void *this, char *mail); int main() { char *mail = "Watashi wa mad scientist !"; M5Titor__v10send_dmailPvPc(0, mail); } """) self.assertEqual(str(self.res.to_c()), str(waited.to_c())) def test_function_return_type_inferred_call(self): self.res = self.kparse.parse( """ @module Titor { void send_dmail(void *this, char *mail); void send_dmail(char *mail); } int main() { char *mail = "Watashi wa mad scientist !"; [Titor send_dmail :(void *)0 :(char *)mail]; } """) waited = self.cparse.parse(""" extern void M5Titor__v10send_dmailPvPc(void *this, char *mail); extern void M5Titor__v10send_dmailPc(char *mail); int main() { char *mail = "Watashi wa mad scientist !"; M5Titor__v10send_dmailPvPc(0, mail); } """) self.assertEqual(str(self.res.to_c()), str(waited.to_c())) def test_function_empty_params_types_inferred_call(self): self.res = self.kparse.parse( """ @module Titor { char *get_dmail(void); } //@implementation Titor { char *get_dmail(void) {return "tutu";} } int main() { printf("%s\n", @!(char *)[Titor get_dmail]); } """) waited = self.cparse.parse(""" extern char* M5Titor__Pc9get_dmailv(void); int main() { printf("%s\n", M5Titor__Pc9get_dmailv()); } """) self.assertEqual(str(self.res.to_c()), str(waited.to_c())) def test_function_int_params_types_inferred_call(self): self.res = self.kparse.parse( """ @module Titor { char *get_dmail(int index); void *get_dmail(int index); } int main() { printf("%s\n", @!(char *)[Titor get_dmail :42]); } """) waited = self.cparse.parse(""" extern char* M5Titor__Pc9get_dmaili(int index); extern void* M5Titor__Pv9get_dmaili(int index); int main() { printf("%s\n", M5Titor__Pc9get_dmaili(42)); } """) self.assertEqual(str(self.res.to_c()), str(waited.to_c())) def test_function_all_inferred_call(self): self.res = self.kparse.parse( """ @module Titor { char *get_dmail(int index); } int main() { printf("%s\n", [Titor get_dmail :42]); } """) waited = self.cparse.parse(""" extern char* M5Titor__Pc9get_dmaili(int index); int main() { printf("%s\n", M5Titor__Pc9get_dmaili(42)); } """) self.assertEqual(str(self.res.to_c()), str(waited.to_c())) def test_function_overload_charptr_call(self): self.res = self.kparse.parse( """ @module Titor { char *get_dmail(int index); float get_dmail(int index); } int main() { printf("%s\n", @!(char *)[Titor get_dmail :(int)42]); } """) waited = self.cparse.parse( """ extern char* M5Titor__Pc9get_dmaili(int index); extern float M5Titor__f9get_dmaili(int index); int main() { printf("%s\n", M5Titor__Pc9get_dmaili(42)); } """) self.assertEqual(str(self.res.to_c()), str(waited.to_c())) def test_function_overload_floatcall(self): self.res = self.kparse.parse( """ @module Titor { char *get_dmail(int index); float get_dmail(int index); } int main() { printf("%s\n", @!(float)[Titor get_dmail :(int)42]); } """) waited = self.cparse.parse( """ extern char* M5Titor__Pc9get_dmaili(int index); extern float M5Titor__f9get_dmaili(int index); int main() { printf("%s\n", M5Titor__f9get_dmaili(42)); } """) self.assertEqual(str(self.res.to_c()), str(waited.to_c())) def test_function_impossible_inferred_return_type(self): with self.assertRaises(RuntimeError) as cm: print(self.kparse.parse( """ @module Titor { char *get_dmail(int index); float get_dmail(int index); } int main() { printf("%s\n", [Titor get_dmail :(int)42]); } """)) def test_function_impossible_inferred_params_type(self): with self.assertRaises(RuntimeError) as cm: print(self.kparse.parse( """ @module Titor { char *get_dmail(int index); char *get_dmail(float date); } int main() { printf("%s\n", [Titor get_dmail :42]); } """))
def getPrimaryType(param): decl = Declaration() typ = decl.parse(param + ';').body[0]._ctype return typ
def update_type(self, ast, typ): decl = Declaration() ast.typ = decl.parse(self.value(typ) + ';').body[0]._ctype return True
def add_cl(self, ast, ret): from cnorm import nodes from copy import deepcopy global clist global mlist global vlist if ret.mname in mlist or ret.mname in clist: print_error("Error module or class already declared : " + ret.mname) return False if not ret.mname in clist: clist[ret.mname] = [] for item in ret.node.body: clist[ret.mname].append(mangle(item, ret.mname, "C")) ast.node.body.extend(ret.node.body) test = "<class \'cnorm.nodes.FuncType\'>" private_var = [ item for item in ret.private.body if str(type(item._ctype)) != test ] private_func = [ item for item in ret.private.body if str(type(item._ctype)) == test ] if not hasattr(slist, ret.mname): slist[ret.mname] = [] for item in private_var: slist[ret.mname].append(mangle(item, ret.mname, "CM")) st = nodes.Decl(ret.mname) st._ctype = nodes.ComposedType(ret.mname) st._ctype._specifier = 1 st._ctype._storage = 2 st._ctype.fields = private_var ast.node.body.append(st) if not hasattr(vlist, ret.mname): vlist[ret.mname] = [] parse = Declaration() nod = parse.parse("struct " + ret.mname + " * self;") for item in private_func: vlist[ret.mname].append(mangle(item, ret.mname, "CM")) item._ctype._params.append(nod.body[0]) ntmp = deepcopy(item) ast.node.body.append(ntmp) item._name = "(*" + item._name + ")" st = nodes.Decl("vtable_" + ret.mname) st._ctype = nodes.ComposedType("vtable_" + ret.mname) st._ctype._specifier = 1 st._ctype._storage = 2 st._ctype.fields = private_func ast.node.body.append(st) parse = Declaration() cl = ret.mname vt = "vtable_" + cl free = "void delete() { void *fr = (void*)(self - sizeof(struct " + vt + ")); free(fr);}" d_free = parse.parse(free) m_free = mangle(d_free.body[0], cl, "CM") vlist[cl].append(m_free) free = "void delete(struct " + cl + " *self) { void *fr = (void*)( ((struct " + vt + " *)(self)) - 1); free(fr);}" d_free = parse.parse(free) d_free.body[0]._name = m_free["mangle"] ast.node.body.append(d_free.body[0]) tmp = deepcopy(d_free) tmp.body[0]._name = "(*" + tmp.body[0]._name + ")" tmp.body[0].body = None st._ctype.fields.append(tmp.body[0]) ptr_func = "" for item in vlist[cl]: ptr_func += "ptr->" + item["mangle"] + " = &" + item["mangle"] + ";" dl = "struct " + cl + " *alloc" code = vt + " *ptr = (struct " + vt + " *) malloc(sizeof(struct " + cl + ") + sizeof(struct " + vt + "));" \ + ptr_func + "return (struct " + cl + " *)(ptr + 1);" alloc = dl + "(){" + code + "}" d_alloc = parse.parse(alloc) m_alloc = mangle(d_alloc.body[0], cl, "C") clist[cl].append(m_alloc) ast.node.body.append(d_alloc.body[0]) dn = "struct " + cl + " *new" code = "struct " + cl + " *ptr = " + m_alloc["mangle"] + "(); return ptr;" new = dn + "(){" + code + "}" d_new = parse.parse(new) m_new = mangle(d_new.body[0], ret.mname, "C") clist[cl].append(m_new) ast.node.body.append(d_new.body[0]) return True
def mangle_func(self, call, spe, mod, var, params): from kooc import mlist, clist, glist, vlist from drecovery import scope from listToStr import listToListStr global mlist, clist, glist, scope, vlist scope_list = [] type_object = "" ptr = "" nnname = "" if mod.value in mlist: scope_list = mlist type_object = "M" elif mod.value in clist: scope_list = clist type_object = "C" else: tmp = None for item in glist[scope]: if item["name"] == mod.value and len(item["type"]) > 3 and item["type"][:3] == "2Sp": if item["type"][3:] in clist: tmp = item break if tmp == None: print_error("error no module called : " + mod.value) return False scope_list = vlist ptr = "(((struct vtable_" + tmp["type"][3:] + " *)" + mod.value + ")-1)->" nnname = mod.value mod.value = tmp["type"][3:] type_object = "CM" cparse = Declaration() list_params = [] all_params = [""] found = False if hasattr(params, "node"): for item in params.node: if "<class 'cnorm.nodes.Func'>" != str(type(item)): tmp = resolve(item, [mlist, clist]) else: tmp = resolve(item.call_expr, [mlist, clist]) if tmp == []: print_error("Error ambiguious statement") return False list_params.append(tmp) all_params = listToListStr(list_params) for item in all_params: if spe.value == "": m = mangle_func_from(mod.value, type_object, var.value, None, item) res = func_algo(call, mod, var, m, scope_list, ptr) else: ast = cparse.parse(spe.value + " " + var.value + "()" ";") m = mangle_func_from(mod.value, type_object, var.value, ast.body[0], item) res = func_algo_spe(call, mod, var, m, scope_list, ptr) if res == True and found == True: print_error("ambiguious function : " + mod.value + " " + var.value) return False if res == True: found = True if found == False: print_error("Don't found function : " + mod.value + " " + var.value) return False if not hasattr(params, "node"): params.node = [] if nnname != "": params.node.append(nodes.Id(nnname)) return True
class UnittestModule(unittest.TestCase): def setUp(self): self.cparse = Declaration() self.kparse = KoocG() def tearDown(self): self.cparse = None self.kparse = None KoocFile.debugCleanAll() if hasattr(self, "res") and not hasattr(self.res, "to_c"): self.assertFalse(self.res.diagnostic.get_content()) ## SIMPLE TO MORE COMPLEX TEST OF VALIDS MODULES def test_empty_module(self): self.res = self.kparse.parse( """ @module Test { } """) self.assertEqual(str(self.res.to_c()), "") def test_declaration_variable(self): self.res = self.kparse.parse( """ @module Test { void test; } """) self.assertEqual(str(self.res.to_c()), "extern void M4Test__v4test;\n") def test_declaration_assignement_variable(self): self.res = self.kparse.parse( """ @module Test { int test = 42; } """) self.assertEqual(str(self.res.to_c()), "extern int M4Test__i4test;\n") def test_declaration_function_implicit_void(self): self.res = self.kparse.parse( """ @module Test { void test(); } """) self.assertEqual(str(self.res.to_c()), "extern void M4Test__v4testv();\n") def test_declaration_function_explicit_void(self): self.res = self.kparse.parse( """ @module Test { void test(void); } """) self.assertEqual(str(self.res.to_c()), "extern void M4Test__v4testv(void);\n") def test_declaration_function(self): self.res = self.kparse.parse( """ @module Test { char *test(int **toto, float tata[]); } """) self.assertEqual(str(self.res.to_c()), "extern char *M4Test__Pc4testPPiAf(int **toto, float tata[]);\n") def test_variable_overload(self): self.res = self.kparse.parse( """ @module Mayuri { int tuturu; float tuturu; } """) self.assertEqual(str(self.res.to_c()), "extern int M6Mayuri__i6tuturu;\nextern float M6Mayuri__f6tuturu;\n") def test_variable_and_function_with_no_param(self): self.res = self.kparse.parse( """ @module Mayuri { int tuturu; int tuturu(); } """) self.assertEqual(str(self.res.to_c()), "extern int M6Mayuri__i6tuturu;\nextern int M6Mayuri__i6tuturuv();\n") def test_function_return_value_overload(self): self.res = self.kparse.parse( """ @module Mayuri { int tuturu(float toto); float tuturu(float tutu); } """) self.assertEqual(str(self.res.to_c()), "extern int M6Mayuri__i6tuturuf(float toto);\n\ extern float M6Mayuri__f6tuturuf(float tutu);\n") def test_function_params_value_overload(self): self.res = self.kparse.parse( """ @module Mayuri { double **tuturu(char toto[], void* ptr[]); double** tuturu(int tutu); } """) self.assertEqual(str(self.res.to_c()), "extern double **M6Mayuri__PPd6tuturuAcAPv(char toto[], void *ptr[]);\n\ extern double **M6Mayuri__PPd6tuturui(int tutu);\n") ## TODO : TESTS WITH SOME FUNCTION POINTER ## TEST OF OVERLOADS WITH DIFFERENTS STORAGES, QUALIFIERS OR SPECIFIER def test_auto_variable(self): waited = self.cparse.parse(""" extern auto int M4Test__i4test; """) self.res = self.kparse.parse( """ @module Test { auto int test; } """) self.assertEqual(str(self.res.to_c()), str(waited.to_c())) def test_register_variable(self): waited = self.cparse.parse(""" extern register int M4Test__i4test; """) self.res = self.kparse.parse( """ @module Test { register int test; } """) self.assertEqual(str(self.res.to_c()), str(waited.to_c())) def test_typedef_variable(self): waited = self.cparse.parse(""" extern typedef int M4Test__i4test; """) self.res = self.kparse.parse( """ @module Test { typedef int test; } """) self.assertEqual(str(self.res.to_c()), str(waited.to_c())) def test_static_variable(self): waited = self.cparse.parse(""" extern static int M4Test__i4test; """) self.res = self.kparse.parse( """ @module Test { static int test; } """) self.assertEqual(str(self.res.to_c()), str(waited.to_c())) def test_extern_variable(self): waited = self.cparse.parse(""" extern extern int M4Test__i4test; """) self.res = self.kparse.parse( """ @module Test { extern int test; } """) self.assertEqual(str(self.res.to_c()), str(waited.to_c())) def test_inline_variable(self): with self.assertRaises(KoocException) as cm: print(self.kparse.parse( """ @module Test { inline int test; } """)) # def test_virtual_variable(self): # waited = self.cparse.parse(""" # extern virtual int M4Test__i4test; # """) # self.res = self.kparse.parse( # """ # @module Test # { # virtual int test; # } # """) # self.assertEqual(str(self.res.to_c()), str(waited.to_c())) # def test_explicit_variable(self): # waited = self.cparse.parse(""" # extern explicit int M4Test__i4test; # """) # self.res = self.kparse.parse( # """ # @module Test # { # explicit int test; # } # """) # self.assertEqual(str(self.res.to_c()), str(waited.to_c())) # def test_forceinline_variable(self): # waited = self.cparse.parse(""" # extern forceinline int M4Test__i4test; # """) # self.res = self.kparse.parse( # """ # @module Test # { # forceinline int test; # } # """) # self.assertEqual(str(self.res.to_c()), str(waited.to_c())) # def test_thread_variable(self): # waited = self.cparse.parse(""" # extern thread int M4Test__i4test; # """) # self.res = self.kparse.parse( # """ # @module Test # { # thread int test; # } # """) # self.assertEqual(str(self.res.to_c()), str(waited.to_c())) def test_volatile_variable(self): waited = self.cparse.parse(""" extern volatile int M4Test__V_i4test; """) self.res = self.kparse.parse( """ @module Test { volatile int test; } """) self.assertEqual(str(self.res.to_c()), str(waited.to_c())) def test_restrict_variable(self): waited = self.cparse.parse(""" extern restrict int M4Test__R_i4test; """) self.res = self.kparse.parse( """ @module Test { restrict int test; } """) self.assertEqual(str(self.res.to_c()), str(waited.to_c())) def test_long_variable(self): waited = self.cparse.parse(""" extern long int M4Test__li4test; """) self.res = self.kparse.parse( """ @module Test { long int test; } """) self.assertEqual(str(self.res.to_c()), str(waited.to_c())) def test_long_long_variable(self): waited = self.cparse.parse(""" extern long long int M4Test__lli4test; """) self.res = self.kparse.parse( """ @module Test { long long int test; } """) self.assertEqual(str(self.res.to_c()), str(waited.to_c())) def test_short_variable(self): waited = self.cparse.parse(""" extern short int M4Test__si4test; """) self.res = self.kparse.parse( """ @module Test { short int test; } """) self.assertEqual(str(self.res.to_c()), str(waited.to_c())) def test_const_ptr_variable(self): waited = self.cparse.parse(""" extern const int *M4Test__PC_i4test; """) self.res = self.kparse.parse( """ @module Test { int const* test; } """) self.assertEqual(str(self.res.to_c()), str(waited.to_c())) def test_complex_variable(self): self.res = self.kparse.parse( """ @module Test { auto unsigned int const* const* test; } """) waited = self.cparse.parse(""" extern auto unsigned int const* const* M4Test__PC_PC_Ui4test; """) self.assertEqual(str(self.res.to_c()), str(waited.to_c()))