def visit_fn(self, fn): c_fn_name = self.fresh_name(fn.name) arg_types = [to_ctype(t) for t in fn.input_types] arg_names = [self.name(old_arg) for old_arg in fn.arg_names] return_types = self.return_types(fn) n_return = len(return_types) if n_return == 1: return_type = to_ctype(return_types[0]) self.return_void = return_type == NoneType self.return_by_ref = False elif n_return == 0: return_type = "void" self.return_void = True self.return_by_ref = False else: return_type = "void" self.return_void = True self.return_by_ref = True self.return_var_types = [to_ctype(t) for t in return_types] self.return_var_names = [self.fresh_name("return_value%d" % i) for i in xrange(n_return)] arg_types = arg_types + ["%s*" % t for t in self.return_var_types] arg_names = arg_names + self.return_var_names args_str = ", ".join("%s %s" % (t, name) for (t, name) in zip(arg_types, arg_names)) body_str = self.visit_block(fn.body) sig = "%s %s(%s)" % (return_type, c_fn_name, args_str) src = "%s { %s }" % (sig, body_str) return c_fn_name, sig, src
def declare(self, parakeet_name, parakeet_type, init_value=None): c_name = self.name(parakeet_name) t = to_ctype(parakeet_type) if init_value is None: self.append("%s %s;" % (t, c_name)) else: self.append("%s %s = %s;" % (t, c_name, init_value))
def visit_Cast(self, expr): x = self.visit_expr(expr.value) ct = to_ctype(expr.type) if isinstance(expr, (Const, Var)): return "(%s) %s" % (ct, x) else: return "((%s) (%s))" % (ct, x)
def visit_Assign(self, stmt): lhs = self.visit_expr(stmt.lhs) rhs = self.visit_expr(stmt.rhs) if stmt.lhs.__class__ is Var: return "%s %s = %s;" % (to_ctype(stmt.lhs.type), lhs, rhs) else: return "%s = %s;" % (lhs, rhs)
def box_scalar(self, x, t): if isinstance(t, BoolT): return "PyBool_FromLong(%s)" % x elif isinstance(t, NoneT): self.append("Py_INCREF(Py_None);") return "Py_None" if x.replace("_", "").isalpha(): scalar = x else: scalar = self.fresh_name("scalar") self.append("%s %s = %s;" % (to_ctype(t), scalar, x)) return "PyArray_Scalar(&%s, PyArray_DescrFromType(%s), NULL)" % (scalar, to_dtype(t))
def fresh_var(self, t, prefix = None, init = None): if prefix is None: prefix = "temp" name = self.fresh_name(prefix) if isinstance(t, str): t_str = t else: t_str = to_ctype(t) if init is None: self.append("%s %s;" % (t_str, name)) else: self.append("%s %s = %s;" % (t_str, name, init)) return name
def visit_ForLoop(self, stmt): s = self.visit_merge_left(stmt.merge, fresh_vars=True) start = self.visit_expr(stmt.start) stop = self.visit_expr(stmt.stop) step = self.visit_expr(stmt.step) var = self.visit_expr(stmt.var) t = to_ctype(stmt.var.type) body = self.visit_block(stmt.body) body += self.visit_merge_right(stmt.merge) body = self.indent("\n" + body) s += "\n %(t)s %(var)s;" s += "\nfor (%(var)s = %(start)s; %(var)s < %(stop)s; %(var)s += %(step)s) {%(body)s}" return s % locals()
def tuple_to_stack_array(self, expr, name="array_from_tuple", elt_type=None): t0 = expr.type.elt_types[0] assert expr.type.__class__ is TupleT assert all(t == t0 for t in expr.type.elt_types[1:]) if expr.__class__ is Tuple: elts = [self.visit_expr(elt_expr) for elt_expr in expr.elts] else: tup = self.visit_expr(expr) self.check_tuple(tup) elts = self.tuple_elts(tup, expr.type.elt_types) array_name = self.fresh_name(name) n = len(expr.type.elt_types) if elt_type is None: elt_type = to_ctype(t0) self.append("%s %s[%d];" % (elt_type, array_name, n)) for i, elt in enumerate(elts): self.append("%s[%d] = %s;" % (array_name, i, elt)) return array_name
def visit_Index(self, expr): arr = self.visit_expr(expr.value) idx = self.visit_expr(expr.index) elt_t = expr.value.type.elt_type ptr_t = "%s*" % to_ctype(elt_t) return "( (%s) (PyArray_DATA(%s)))[%s]" % (ptr_t, arr, idx)