def register(self, ptype): """register ptype as a local typedef""" # Too many of them leads to memory burst if len(self.typedefs) < cfg.getint('typing', 'max_combiner'): self.typedefs.append(ptype) return True return False
def generate(self, ctx): # gather all underlying types and make sure they do not appear twice mct = cfg.getint('typing', 'max_container_type') all_types = self.all_types() def fot0(t): return isinstance(t, IndexableType) def fot1(t): return isinstance(t, ContainerType) def fit(t): return not fot0(t) and not fot1(t) it = [t for t in all_types if fit(t)] it = sorted(it, key=lambda t: t.iscore, reverse=True) ot0 = [t for t in all_types if fot0(t)] ot1 = [t for t in all_types if fot1(t)] icombined = sorted({ctx(t).generate(ctx) for t in it if t.iscore}) icombined += sorted({ctx(t).generate(ctx) for t in it if not t.iscore}) lcombined0 = sorted({ctx(t).generate(ctx) for t in ot0})[-mct:] lcombined1 = sorted({ctx(t).generate(ctx) for t in ot1})[-mct:] combined = icombined + lcombined0 + lcombined1 if len(combined) == 1: return combined[0] else: return 'typename __combined<{0}>::type'.format(",".join(combined))
def generate(self, ctx): # gather all underlying types and make sure they do not appear twice mct = cfg.getint('typing', 'max_container_type') all_types = self.all_types() def fot0(t): return type(t) is IndexableType def fot1(t): return type(t) is ContainerType def fit(t): return not fot0(t) and not fot1(t) it = filter(fit, all_types) ot0 = filter(fot0, all_types) ot1 = filter(fot1, all_types) icombined = sorted(set(ctx(t).generate(ctx) for t in it)) lcombined0 = sorted(set(ctx(t).generate(ctx) for t in ot0))[-mct:] lcombined1 = sorted(set(ctx(t).generate(ctx) for t in ot1))[-mct:] combined = icombined + lcombined0 + lcombined1 if len(combined) == 1: return combined[0] else: return 'typename __combined<{0}>::type'.format(",".join(combined))
def __call__(self, text, input_file=None): self.exports = defaultdict(tuple) self.native_exports = defaultdict(tuple) self.export_info = defaultdict(tuple) self.input_text = text self.input_file = input_file lines = [] in_pythran_export = False for line in text.split("\n"): if re.match(r'\s*#\s*pythran', line): in_pythran_export = True lines.append(re.sub(r'\s*#\s*pythran', '#pythran', line)) elif in_pythran_export: stripped = line.strip() if stripped.startswith('#'): lines.append(line.replace('#', '')) else: in_pythran_export = not stripped lines.append('') else: in_pythran_export &= not line.strip() lines.append('') pythran_data = '\n'.join(lines) self.parser.parse(pythran_data, lexer=self.lexer, debug=False) for key, overloads in self.native_exports.items(): if len(overloads) > 1: msg = "Overloads not supported for capsule '{}'".format(key) loc = self.export_info[key][-1] raise self.PythranSpecError(msg, loc) self.native_exports[key] = overloads[0] for key, overloads in self.exports.items(): if len(overloads) > cfg.getint("typing", "max_export_overloads"): raise self.PythranSpecError( "Too many overloads for function '{}', probably due to " "automatic generation of C-style and Fortran-style memory " "layout. Please force a layout using `order(C)` or " "`order(F)` in the array signature".format(key)) for i, ty_i in enumerate(overloads): sty_i = spec_to_string(key, ty_i) for ty_j in overloads[i+1:]: sty_j = spec_to_string(key, ty_j) if sty_i == sty_j: msg = "Duplicate export entry {}.".format(sty_i) loc = self.export_info[key][-1] raise self.PythranSpecError(msg, loc) if ambiguous_types(ty_i, ty_j): msg = "Ambiguous overloads\n\t{}\n\t{}.".format(sty_i, sty_j) loc = self.export_info[key][i] raise self.PythranSpecError(msg, loc) return Spec(self.exports, self.native_exports)
def __call__(self, path_or_text): self.exports = defaultdict(tuple) self.native_exports = defaultdict(tuple) self.input_file = None data = self.read_path_or_text(path_or_text) lines = [] in_pythran_export = False for line in data.split("\n"): if re.match(r'\s*#\s*pythran', line): in_pythran_export = True lines.append(re.sub(r'\s*#\s*pythran', '#pythran', line)) elif in_pythran_export: stripped = line.strip() if stripped.startswith('#'): lines.append(line.replace('#', '')) else: in_pythran_export = not stripped lines.append('') else: in_pythran_export &= not line.strip() lines.append('') pythran_data = '\n'.join(lines) self.parser.parse(pythran_data, lexer=self.lexer, debug=False) for key, overloads in self.native_exports.items(): if len(overloads) > 1: raise PythranSyntaxError( "Overloads not supported for capsule '{}'".format(key)) self.native_exports[key] = overloads[0] for key, overloads in self.exports.items(): if len(overloads) > cfg.getint("typing", "max_export_overloads"): raise PythranSyntaxError("Too many overloads for function '{}', probably due to automatic generation of C-style and Fortran-style memory layout. Please force a layout using `order(C)` or `order(F)` in the array signature".format(key)) for i, ty_i in enumerate(overloads): sty_i = spec_to_string(key, ty_i) for ty_j in overloads[i+1:]: sty_j = spec_to_string(key, ty_j) if sty_i == sty_j: raise PythranSyntaxError( "Duplicate export entry {}.".format(sty_i)) if ambiguous_types(ty_i, ty_j): msg = "Ambiguous overloads\n\t{}\n\t{}.".format(sty_i, sty_j) raise PythranSyntaxError(msg) return Spec(self.exports, self.native_exports)