def __init__(self, line, depth=0): self._depth = depth m = re.match(r"(>|<) (.*)\((.*)\)", line) if m: # m.group(1) = '>' or '<' self._pkg, self._cls, self._mtd = util.explode_mname(m.group(2)) vals = map(op.methodcaller("strip"), m.group(3).split(',')) self._vals = util.ffilter(vals) # to remove empty strings else: raise Exception("wrong call sequences", line)
def rm_subs(clss): # { cname: Clazz(cname, ...), ... } decls = { cls.name: cls for cls in clss } # remove subclasses for cname in decls.keys(): if util.is_collection(cname): continue cls = class_lookup(cname) if not cls.is_class: continue for sub in cls.subs: if sub.name in decls: logging.debug("{} < {}".format(sub.name, cname)) del decls[sub.name] for sup in util.ffilter([cls.sup]): if sup in decls and cname in decls: logging.debug("{} < {}".format(cname, sup)) del decls[cname] return decls.values()
def rm_subs(clss): # { cname: Clazz(cname, ...), ... } decls = { cls.name: cls for cls in clss } # remove subclasses for cname in decls.keys(): if util.is_collection(cname): continue cls = class_lookup(cname) if not cls.is_class: continue if cls.is_aux: continue # virtual relations; don't remove sub classes for sub in cls.subs: if sub.name in decls: logging.debug("{} < {}".format(sub.name, cname)) del decls[sub.name] for sup in util.ffilter([cls.sup]): if sup in decls and cname in decls: logging.debug("{} < {}".format(cname, sup)) del decls[cname] return decls.values()
def gen_type_sk(sk_dir, bases): buf = cStringIO.StringIO() buf.write("package type;\n") buf.write(_const) cols, decls = util.partition(lambda c: util.is_collection(c.name), bases) decls = filter(lambda c: not util.is_array(c.name), decls) itfs, clss = util.partition(op.attrgetter("is_itf"), decls) logging.debug("# interface(s): {}".format(len(itfs))) logging.debug("# class(es): {}".format(len(clss))) # convert interfaces first, then usual classes buf.write('\n'.join(util.ffilter(map(to_struct, itfs)))) buf.write('\n'.join(util.ffilter(map(to_struct, clss)))) # convert collections at last logging.debug("# collection(s): {}".format(len(cols))) buf.write('\n'.join(map(col_to_struct, cols))) # argument number of methods arg_num = map(lambda mtd: len(mtd.params), methods()) buf.write(""" #define _{0} {{ {1} }} int {0}(int id) {{ return _{0}[id]; }} """.format(C.typ.argNum, ", ".join(map(str, arg_num)))) # argument types of methods def get_args_typ(mtd): def get_arg_typ(param): return str(class_lookup(param[0]).id) return '{' + ", ".join(map(get_arg_typ, mtd.params)) + '}' args_typ = map(get_args_typ, methods()) buf.write(""" #define _{0} {{ {1} }} int {0}(int id, int idx) {{ return _{0}[id][idx]; }} """.format(C.typ.argType, ", ".join(args_typ))) # return type of methods def get_ret_typ(mtd): cls = class_lookup(mtd.typ) if cls: return cls.id else: return -1 ret_typ = map(get_ret_typ, methods()) buf.write(""" #define _{0} {{ {1} }} int {0}(int id) {{ return _{0}[id]; }} """.format(C.typ.retType, ", ".join(map(str, ret_typ)))) # belonging class of methods belongs = map(lambda mtd: mtd.clazz.id, methods()) buf.write(""" #define _{0} {{ {1} }} int {0}(int id) {{ return _{0}[id]; }} """.format(C.typ.belongsTo, ", ".join(map(str, belongs)))) subcls = \ map(lambda cls_i: '{' + ", ".join( \ map(lambda cls_j: str(cls_i <= cls_j).lower(), classes()) \ ) + '}', classes()) buf.write(""" #define _{0} {{ {1} }} bit {0}(int i, int j) {{ return _{0}[i][j]; }} """.format(C.typ.subcls, ", ".join(subcls))) ## sub type relations #subcls = [] #for cls_i in classes(): # row = [] # for cls_j in classes(): # row.append(int(cls_i <= cls_j)) # subcls.append(row) ## sub type relations in yale format #_, IA, JA = util.yale_format(subcls) #li, lj = len(IA), len(JA) #si = ", ".join(map(str, IA)) #sj = ", ".join(map(str, JA)) #buf.write(""" # #define _iA {{ {si} }} # #define _jA {{ {sj} }} # int iA(int i) {{ # return _iA[i]; # }} # int jA(int j) {{ # return _jA[j]; # }} # bit subcls(int i, int j) {{ # int col_i = iA(i); # int col_j = iA(i+1); # for (int col = col_i; col < col_j; col++) {{ # if (j == jA(col)) return true; # }} # return false; # }} #""".format(**locals())) with open(os.path.join(sk_dir, "type.sk"), 'w') as f: f.write(buf.getvalue()) logging.info("encoding " + f.name) buf.close()
def gen_type_sk(sk_dir, bases): buf = cStringIO.StringIO() buf.write("package type;\n") buf.write(_const) buf.write(trans_lib()) buf.write('\n') cols, decls = util.partition(lambda c: util.is_collection(c.name), bases) decls = filter(lambda c: not util.is_array(c.name), decls) itfs, clss = util.partition(op.attrgetter("is_itf"), decls) logging.debug("# interface(s): {}".format(len(itfs))) logging.debug("# class(es): {}".format(len(clss))) # convert interfaces first, then usual classes buf.write('\n'.join(util.ffilter(map(to_struct, itfs)))) buf.write('\n'.join(util.ffilter(map(to_struct, clss)))) # convert collections at last logging.debug("# collection(s): {}".format(len(cols))) buf.write('\n'.join(map(col_to_struct, cols))) # argument number of methods arg_num = map(lambda mtd: len(mtd.params), methods()) buf.write(""" #define _{0} {{ {1} }} int {0}(int id) {{ return _{0}[id]; }} """.format(C.typ.argNum, ", ".join(map(str, arg_num)))) # argument types of methods def get_args_typ(mtd): def get_arg_typ(param): return str(class_lookup(param[0]).id) return '{' + ", ".join(map(get_arg_typ, mtd.params)) + '}' args_typ = map(get_args_typ, methods()) buf.write(""" #define _{0} {{ {1} }} int {0}(int id, int idx) {{ return _{0}[id][idx]; }} """.format(C.typ.argType, ", ".join(args_typ))) # return type of methods def get_ret_typ(mtd): cls = class_lookup(mtd.typ) if cls: return cls.id else: return -1 ret_typ = map(get_ret_typ, methods()) buf.write(""" #define _{0} {{ {1} }} int {0}(int id) {{ return _{0}[id]; }} """.format(C.typ.retType, ", ".join(map(str, ret_typ)))) # belonging class of methods belongs = map(lambda mtd: mtd.clazz.id, methods()) buf.write(""" #define _{0} {{ {1} }} int {0}(int id) {{ return _{0}[id]; }} """.format(C.typ.belongsTo, ", ".join(map(str, belongs)))) subcls = \ map(lambda cls_i: '{' + ", ".join( \ map(lambda cls_j: str(cls_i <= cls_j).lower(), classes()) \ ) + '}', classes()) buf.write(""" #define _{0} {{ {1} }} bit {0}(int i, int j) {{ return _{0}[i][j]; }} """.format(C.typ.subcls, ", ".join(subcls))) ## sub type relations #subcls = [] #for cls_i in classes(): # row = [] # for cls_j in classes(): # row.append(int(cls_i <= cls_j)) # subcls.append(row) ## sub type relations in yale format #_, IA, JA = util.yale_format(subcls) #li, lj = len(IA), len(JA) #si = ", ".join(map(str, IA)) #sj = ", ".join(map(str, JA)) #buf.write(""" # #define _iA {{ {si} }} # #define _jA {{ {sj} }} # int iA(int i) {{ # return _iA[i]; # }} # int jA(int j) {{ # return _jA[j]; # }} # bit subcls(int i, int j) {{ # int col_i = iA(i); # int col_j = iA(i+1); # for (int col = col_i; col < col_j; col++) {{ # if (j == jA(col)) return true; # }} # return false; # }} #""".format(**locals())) with open(os.path.join(sk_dir, "type.sk"), 'w') as f: f.write(buf.getvalue()) logging.info("encoding " + f.name) buf.close()
def to_func(smpls, mtd): buf = cStringIO.StringIO() if C.mod.GN in mtd.mods: buf.write(C.mod.GN + ' ') elif C.mod.HN in mtd.mods: buf.write(C.mod.HN + ' ') ret_ty = trans_ty(mtd.typ) cname = unicode(repr(mtd.clazz)) mname = mtd.name arg_typs = mtd.param_typs buf.write(ret_ty + ' ' + trans_mname(cname, mname, arg_typs) + '(') @takes(tuple_of(unicode)) @returns(unicode) def trans_param( (ty, nm) ): return ' '.join([trans_ty(ty), nm]) # for instance methods, add "this" pointer into parameters if mtd.is_static: params = mtd.params[:] else: self_ty = trans_ty(unicode(repr(mtd.clazz))) params = [ (self_ty, C.SK.self) ] + mtd.params[:] # add "logging" flag into parameters # to check log conformity only if invocations cross the boundary if not mtd.is_init and not mtd.is_clinit: params.append( (C.SK.z, u"logging") ) if len(params) > 0: buf.write(", ".join(map(trans_param, params))) buf.write(") {\n") # once function signature is dumped out, remove "logging" flag if not mtd.is_init and not mtd.is_clinit: params.pop() clss = util.flatten_classes([mtd.clazz], "subs") logged = (not mtd.is_init) and sample.mtd_appears(smpls, clss, mtd.name) mid = unicode(repr(mtd)) m_ent = mid + "_ent()" m_ext = mid + "_ext()" if logged: global _mids _mids.add(mid) if logged: # logging method entry (>) _log_params = map(log_param, params) _retrievals, _hashes = util.split([(u'', m_ent)] + _log_params) ent_retrievals = util.ffilter(_retrievals) ent_hashes = util.ffilter(_hashes) buf.write("""{} int[P] __params = {{ {} }}; if (logging) check_log@log(__params); """.format(u''.join(ent_retrievals), u", ".join(ent_hashes))) is_void = C.J.v == mtd.typ if mtd.body: if not is_void and not mtd.is_init: bodies = mtd.body[:-1] # exclude the last 'return' statement else: bodies = mtd.body buf.write('\n'.join(map(partial(trans_s, mtd), bodies))) if logged: # logging method exit (<) _log_params = [] if mtd.body and not is_void and not mtd.is_init: ret_v = mtd.body[-1].e ret_u = unicode(trans_e(mtd, ret_v)) # retrieve the return value to a temporary variable buf.write(u""" {} __ret = {}; """.format(ret_ty, ret_u)) # then, try to obtain a hash from that temporary variable _log_params.append(log_param( (ret_ty, u"__ret") )) _retrievals, _hashes = util.split([(u'', m_ext)] + _log_params) ext_retrievals = util.ffilter(_retrievals) ext_hashes = util.ffilter(_hashes) buf.write("""{} __params = {{ {} }}; if (logging) check_log@log(__params); """.format(u''.join(ext_retrievals), u", ".join(ext_hashes))) if mtd.body and not is_void and not mtd.is_init: buf.write(os.linesep) if logged: # return the return value stored at the temporary variable buf.write("return __ret;") else: buf.write(trans_s(mtd, mtd.body[-1])) if mtd.is_init: evt_srcs = map(util.sanitize_ty, sample.evt_sources(smpls)) cname = unicode(repr(mtd.clazz)) if cname in evt_srcs: global _inits _inits.add(cname) buf.write("\nreturn {};".format(C.SK.self)) buf.write("\n}\n") return buf.getvalue()