def visit_main_class(self, node, *args): return { 'main': ir.Method( postprocess_ir([self.visit(node.statement), ir.Return(None)])) }
def bsort_expr(n, datatype): def assign(var, val): return ir.Stmt((ir.assignment, var, val)) def item(name): return ir.Struct_item(ir.Primitive_type(datatype), (name)) t = ir.Struct(ir.Scoped_id([("s")], ('Vector'), ''), [item('m%d'%i) for i in range(1, n+1)], '') a = ir.Arg([], ir.in_, t, 'a') b = ir.Arg([], ir.inout, t, 'b') copy = [ir.Stmt(ir.Set_struct_item(t, (ir.deref, "b"), item('m%d'%i), ir.Get_struct_item(t, (ir.deref, "a"), item('m%d'%i)))) for i in range(1, n+1)] sort = [(ir.var_decl, ir.pt_bool, ("swapped")), (ir.var_decl, ir.pt_int, ("tmp")), (ir.do_while, ("swapped"), # if A[i-1] > A[i] [assign(("swapped"), ir.Bool(ir.false))]+ [[(ir.if_, (ir.Infix_expr(ir.gt, ir.Get_struct_item(t, (ir.deref, "b"), item('m%d'%(i-1))), ir.Get_struct_item(t, (ir.deref, "b"), item('m%d'%i)))), # swap( A[i-1], A[i] ) # swapped = true [assign(("tmp"), ir.Get_struct_item(t, (ir.deref, "b"), item('m%d'%i))), ir.Stmt(ir.Set_struct_item(t, (ir.deref, "b"), item('m%d'%i), ir.Get_struct_item(t, (ir.deref, "b"), item('m%d'%(i-1))))), ir.Stmt(ir.Set_struct_item(t, (ir.deref, "b"), item('m%d'%(i-1)), ("tmp"))), assign(("swapped"), ir.Bool(ir.true))])] for i in range(2, n+1)])] return copy+sort+[ir.Stmt(ir.Return(retval(n, datatype)))]
def reverse_expr(n, datatype): 'b_i = a_{n-i}' def item(name): return ir.Struct_item(ir.Primitive_type(datatype), (name)) t = ir.Struct(ir.Scoped_id([("s")], ('Vector'), ''), [ir.Struct_item(ir.Primitive_type(datatype), ('m%d'%i)) for i in range(1, n+1)], '') revs = [ir.Stmt(ir.Set_struct_item(t, (ir.deref, "b"), item('m%d'%i), ir.Get_struct_item(t, (ir.deref, "a"), item('m%d'%(n-i+1))))) for i in range(1, n+1)] return revs+[ir.Stmt(ir.Return(retval(n, datatype)))]
def const_access_expr(n, datatype): def add(a, b): return ir.Plus(a, b) def item(name): return ir.Struct_item(ir.Primitive_type(datatype), (name)) t = ir.Struct(ir.Scoped_id([("s")], ('Vector'), ''), [ir.Struct_item(ir.Primitive_type(datatype), ('m%d'%i)) for i in range(1, n+1)], '') e = reduce(add, map(lambda i: ("*", ir.Get_struct_item(t, (ir.deref, "a"), item('m%d'%(i%n+1))), ir.Get_struct_item(t, (ir.deref, "b"), item('m%d'%(i%n+1)))), range(1, 129))) return ir.Stmt(ir.Return(e))
def visit_method_declaration(self, node, *args): self.clear_counter() self.method_name = node.name table = [] for stmt in node.statement: table.append(self.visit(stmt)) ret = self.get_id() table = { (self.class_name + '.' + node.name): ir.Method( postprocess_ir(table + [self.visit(node.retexpr, ir.EXPR, ret)] + [ir.Return(ret)])) } self.method_name = None return table
def dotproduct_expr(n, datatype): def add(a, b): return ir.Plus(a, b) def item(name): return ir.Struct_item(ir.Primitive_type(datatype), (name)) a = ir.Struct(ir.Scoped_id([("s")], ('Vector'), ''), [ir.Struct_item(ir.Primitive_type(datatype), ('m%d'%i)) for i in range(1, n+1)], '') b = a e = reduce(add, map(lambda i: ("*", ir.Get_struct_item(a, (ir.deref, "a"), 'm%d'%i), ir.Get_struct_item(b, (ir.deref, "b"), 'm%d'%i)), range(1, n+1))) return ir.Stmt(ir.Return(e))
def sum_expr(n, datatype): e = reduce(ir.Plus, ['a%d' % i for i in range(0, n)], 0) return [ir.Stmt(ir.Return(e))]
def nop_expr(n, datatype): return ir.Stmt(ir.Return(retval(n, datatype)))
def visit_Return(self, node: ast.Return): pos = extract_positional_info(node) value = self.visit(node.value) if node.value is not None else None stmt = ir.Return(value, pos) self.body.append(stmt)
def ret(self, _): self.stmt(ir.Return(self.pop()))
def generate_server_method(self, symbol_table, method, ci): """ Generate server code for a method interface. This function generates a C-callable skeleton for the method and generates a Skeleton of Chapel code complete with splicer blocks for the user to fill in. \param method s-expression of the method's SIDL declaration \param symbol_table the symbol table of the SIDL file \param ci a ClassInfo object """ def convert_arg((arg, attrs, mode, typ, name)): """ Extract name and generate argument conversions """ iorname = name return iorname, (arg, attrs, mode, typ, name) # Chapel skeleton (Method, Type, (MName, Name, Extension), Attrs, Args, Except, From, Requires, Ensures, DocComment) = method #ior_args = drop_rarray_ext_args(Args) # ci.epv.add_method((Method, Type, (MName, Name, Extension), Attrs, ior_args, # Except, From, Requires, Ensures, DocComment)) abstract = member_chk(sidlir.abstract, Attrs) static = member_chk(sidlir.static, Attrs) #final = member_chk(sidlir.static, Attrs) if abstract: # nothing to be done for an abstract function return decls = [] pre_call = [] call_args = [] post_call = [] ior_args = babel.lower_ir(symbol_table, Args, lower_scoped_ids=False) ctype = babel.lower_ir(symbol_table, Type, lower_scoped_ids=False) return_stmt = [] skel = ci.chpl_skel opt = skel.cstub.optional qname = '_'.join(ci.co.qualified_name + [Name]) callee = qname + '_impl' # Argument conversions # --------------------- # self this_arg = [] if static else [ir.Arg([], ir.in_, ir.void_ptr, '_this')] # IN map( lambda (arg, attr, mode, typ, name): conv.codegen( (strip(typ), deref(mode, typ, name)), ('chpl', strip(typ)), pre_call, skel, '_CHPL_' + name, typ), filter(incoming, ior_args)) # OUT map( lambda (arg, attr, mode, typ, name): conv.codegen( (('chpl', strip(typ)), '_CHPL_' + name), strip( typ), post_call, skel, '(*%s)' % name, typ), filter(outgoing, ior_args)) # RETURN value type conversion -- treated just like an OUT argument rarg = (ir.arg, [], ir.out, ctype, '_retval') conv.codegen((('chpl', strip(ctype)), '_CHPL__retval'), strip(ctype), post_call, skel, '_retval', ctype) chpl_rarg = conv.ir_arg_to_chpl(rarg) _, _, _, chpltype, _ = chpl_rarg if Type <> sidlir.void: decls.append(ir.Stmt(ir.Var_decl(ctype, '_retval'))) # def pointerize_struct((arg, attr, mode, typ, name)): # # FIXME: this is borked.. instead we should remove this # # _and_ the code in codegenerator that strips the # # pointer_type again # if typ[0] == ir.struct: # return (arg, attr, mode, (ir.pointer_type, typ), name) # else: return (arg, attr, mode, typ, name) # chpl_args = map(pointerize_struct, map(conv.ir_arg_to_chpl, ior_args)) chpl_args = map(conv.ir_arg_to_chpl, ior_args) # Proxy declarations / revised names of call arguments is_retval = True for (_,attrs,mode,chpl_t,name), (_,_,_,c_t,_) \ in zip([chpl_rarg]+chpl_args, [rarg]+ior_args): if chpl_t <> c_t: is_struct = False proxy_t = chpl_t if c_t[0] == ir.pointer_type and c_t[1][0] == ir.struct: # inefficient!!! opt.add(str(c_gen(ir.Type_decl(chpl_t[1])))) c_t = c_t[1] is_struct = True proxy_t = chpl_t[1] # FIXME see comment in chpl_to_ior name = '_CHPL_' + name decls.append(ir.Stmt(ir.Var_decl(proxy_t, name))) if (mode <> sidlir.in_ or is_struct # TODO this should be handled by a conversion rule or (mode == sidlir.in_ and (c_t == ir.pt_fcomplex or c_t == ir.pt_dcomplex))): name = ir.Pointer_expr(name) if name == 'self' and member_chk(ir.pure, attrs): # part of the hack for self dereferencing upcast = ( '({0}*)(((struct sidl_BaseInterface__object*)self)->d_object)' .format(c_gen(c_t[1]))) call_args.append(upcast) else: if is_retval: is_retval = False else: call_args.append(name) call_args.append('_ex') if not static: call_args = ['self->d_data'] + call_args # The actual function call if Type == sidlir.void: Type = ir.pt_void call = [ir.Stmt(ir.Call(callee, call_args))] else: if post_call: call = [ ir.Stmt( ir.Assignment('_CHPL__retval', ir.Call(callee, call_args))) ] return_stmt = [ir.Stmt(ir.Return('_retval'))] else: call = [ir.Stmt(ir.Return(ir.Call(callee, call_args)))] #TODO: ior_args = drop_rarray_ext_args(Args) skeldefn = (ir.fn_defn, [], ctype, qname + '_skel', babel.epv_args(Attrs, Args, ci.epv.symbol_table, ci.epv.name), decls + pre_call + call + post_call + return_stmt, DocComment) def skel_args((arg, attr, mode, typ, name)): # lower array args if typ[0] == sidlir.array: return arg, attr, mode, ir.pt_void, name # complex is always passed as a pointer since chpl 1.5 elif mode == ir.in_ and typ[0] == ir.typedef_type and ( typ[1] == '_complex64' or typ[1] == '_complex128'): return arg, attr, mode, ir.Pointer_type(typ), name else: return arg, attr, mode, typ, name ex_arg = [ir.Arg([], ir.inout, babel.ir_baseinterface_type(), '_ex')] impl_args = this_arg + map(skel_args, chpl_args) + ex_arg impldecl = (ir.fn_decl, [], chpltype, callee, impl_args, DocComment) splicer = '.'.join(ci.epv.symbol_table.prefix + [ci.epv.name, Name]) impldefn = (ir.fn_defn, ['export ' + callee], chpltype, Name, impl_args, [ 'set_to_null(_ex);', '// DO-NOT-DELETE splicer.begin(%s)' % splicer, '// DO-NOT-DELETE splicer.end(%s)' % splicer ], DocComment) c_gen(skeldefn, ci.stub) c_gen(impldecl, ci.stub) upc_gen(impldefn, ci.impl)
def generate_client_method(self, symbol_table, method, ci, has_impl): """ Generate client code for a method interface. \param method s-expression of the method's SIDL declaration \param symbol_table the symbol table of the SIDL file \param ci a ClassInfo object This is currently a no-op, since the UPC calling convention is identical to the IOR. """ (Method, Type, (MName, Name, Extension), Attrs, Args, Except, From, Requires, Ensures, DocComment) = method abstract = member_chk(sidlir.abstract, Attrs) #final = member_chk(sidlir.final, Attrs) static = member_chk(sidlir.static, Attrs) attrs = [] if abstract: # we still need to output a stub for an abstract function, # since it might me a virtual function call through an # abstract interface pass if static: attrs.append(ir.static) ior_type = babel.lower_ir(symbol_table, Type) ior_args = babel.epv_args(Attrs, Args, symbol_table, ci.epv.name) call_args = map(lambda arg: ir.arg_id(arg), ior_args) cdecl = ir.Fn_decl(attrs, ior_type, Name + Extension, ior_args, DocComment) qname = '_'.join(ci.co.qualified_name + [Name]) + Extension if self.server and has_impl: # if we are generating server code we can take a shortcut # and directly invoke the implementation modname = '_'.join(ci.co.symbol_table.prefix + ['Impl']) if not static: qname = '_'.join(ci.co.qualified_name + ['Impl']) # FIXME! callee = '_'.join([modname, ir.fn_decl_id(cdecl)]) else: callee = babel.build_function_call(ci, cdecl, static) if Type == sidlir.void: call = [ir.Stmt(ir.Call(callee, call_args))] else: call = [ir.Stmt(ir.Return(ir.Call(callee, call_args)))] cdecl = ir.Fn_decl(attrs, ior_type, qname, ior_args, DocComment) cdefn = ir.Fn_defn(attrs, ior_type, qname, ior_args, call, DocComment) if static: # TODO: [performance] we would only need to put the # _externals variable into the _Stub.c, not necessarily # all the function definitions ci.stub.gen(cdecl) ci.stub.new_def('#pragma weak ' + qname) ci.stub.gen(cdefn) else: # FIXME: can't UPC handle the inline keyword?? ci.stub.new_header_def('static inline') ci.stub.genh(cdefn)