def p_scopedId(p): '''scopedId : maybeDot names empty | maybeDot names EXTENSION''' if p[3] == []: p[0] = sidlir.Scoped_id((p[2][:-1]), p[2][-1], '') else: p[0] = sidlir.Scoped_id((p[2][:-1]), p[2][-1], p[3])
def object_type(package, name): """ \return the SIDL node for the type of a Babel object 'name' \param name the name of the object \param package the list of IDs making up the package """ if isinstance(name, tuple): name = name[1] return sidlir.Scoped_id(package, name, '')
def get_parents(self): """ Return a list of the names of all base classes and implemented interfaces of a class in \c all_parents """ if self.all_parents: return self.all_parents start = sidlir.Scoped_id(self.symbol_table.prefix, sidlir.type_id(self.data), '') visit_hierarchy(start, lambda _st, ext, _id: self.all_parents.append(ext), self.symbol_table, []) return self.all_parents
def p_interface(p): '''interface : INTERFACE name extendsList LBRACE invariants methods RBRACE''' no_comma(p[7]) # Every interface implicitly inherits from BaseInterface if p[3]: exts = p[3] else: if p[2] <> 'BaseInterface': exts = [ sidlir.Extends(sidlir.Scoped_id(['sidl'], 'BaseInterface', '')) ] else: exts = [] p[0] = sidlir.Interface(p[2], exts, (p[5]), (p[6]), scanner.last_doc_comment())
def p_class(p): '''class : CLASS name maybeExtendsOne implementsSomeAllLists LBRACE invariants methods RBRACE''' no_comma(p[8]) # Every class implicitly inherits from BaseClass if not p[3]: if p[2] <> 'BaseClass': ext = [sidlir.Extends(sidlir.Scoped_id(['sidl'], 'BaseClass', ''))] else: ext = [] else: ext = p[3] if p[4]: impl = list(itertools.chain.from_iterable(p[4])) else: impl = p[4] p[0] = sidlir.Class(p[2], ext, impl, (p[6]), (p[7]), scanner.last_doc_comment())
def build_symbol_table(node, symbol_table, verbose=True): """ Build a hierarchical \c SymbolTable() for \c node. For the time being, we store the fully scoped name (= \c [package,subpackage,classname] ) for each class in the symbol table. """ def gen(node): return build_symbol_table(node, symbol_table, verbose) with match(node): if (sidlir.class_, Name, Extends, Implements, Invariants, Methods, DocComment): symbol_table[Name] = \ ( sidlir.class_, (sidlir.scoped_id, symbol_table.prefix, Name, ''), Extends, Implements, Invariants, Methods, DocComment ) elif (sidlir.interface, Name, Extends, Invariants, Methods, DocComment): symbol_table[Name] = \ ( sidlir.interface, (sidlir.scoped_id, symbol_table.prefix, Name, ''), Extends, Invariants, Methods, DocComment ) elif (sidlir.enum, Name, Items, DocComment): symbol_table[Name] = node elif (sidlir.struct, Name, Items, DocComment): symbol_table[Name] = \ ( sidlir.struct, ( sidlir.scoped_id, symbol_table.prefix, Name, ''), Items, DocComment ) elif (sidlir.package, Name, Version, UserTypes, DocComment): if (verbose): import sys sys.stdout.write('\r'+' '*80) sys.stdout.write("\rBuilding symbols for package %s" %'.'.join(symbol_table.prefix+[Name])) sys.stdout.flush() symbol_table[Name] = SymbolTable(symbol_table, symbol_table.prefix+[Name]) build_symbol_table(UserTypes, symbol_table[sidlir.Scoped_id([], Name, '')][1], verbose) elif (sidlir.user_type, Attrs, Cipse): gen(Cipse) elif (sidlir.file, Requires, Imports, UserTypes): gen(Imports) gen(UserTypes) elif (sidlir.import_, (sidlir.scoped_id, [], 'sidl', '')): # imported by default pass elif A: if (isinstance(A, list)): for defn in A: gen(defn) else: raise Exception("build_symbol_table: NOT YET IMPLEMENTED:"+repr(A)) else: raise Exception("match error") return symbol_table
def get_scoped_id(self): """ \return the scoped id of this extendable. """ return sidlir.Scoped_id(self.symbol_table.prefix, self.name)
def generate_glue_code(self, node, data, symbol_table): """ Generate glue code for \c node . """ def gen(node): return self.generate_glue_code(node, data, symbol_table) def generate_ext_stub(cls): """ shared code for class/interface """ # Qualified name (C Version) qname = '_'.join(symbol_table.prefix + [cls.name]) self.exts.append(qname) if self.config.verbose: import sys mod_name = '.'.join(symbol_table.prefix[1:] + [cls.name]) sys.stdout.write('\r' + ' ' * 80) sys.stdout.write('\rgenerating glue code for %s' % mod_name) sys.stdout.flush() # Consolidate all methods, defined and inherited cls.scan_methods() # chpl_defs = ChapelScope(chpl_stub) ci = self.ClassInfo(cls) # if self.server: # ci.impl = self.pkg_impl ci.stub.new_def(babel.externals(cls.get_scoped_id())) ci.stub.new_def(babel.builtin_stub_functions(cls.get_scoped_id())) has_contracts = ior_template.generateContractChecks(cls) self.gen_default_methods(cls, has_contracts, ci) #print qname, map(lambda x: x[2][1]+x[2][2], cls.all_methods) for method in cls.all_methods: (Method, Type, Name, Attrs, Args, Except, From, Requires, Ensures, DocComment) = method ci.epv.add_method((method, Type, Name, Attrs, babel.drop_rarray_ext_args(Args), Except, From, Requires, Ensures, DocComment)) # all the methods for which we would generate a server impl impl_methods = babel.builtins + cls.get_methods() impl_methods_names = [ sidlir.method_method_name(m) for m in impl_methods ] # client for method in cls.all_methods: has_impl = sidlir.method_method_name( method) in impl_methods_names self.generate_client_method(symbol_table, method, ci, has_impl) if self.server: class_methods = filter(sidlir.is_not_static, impl_methods) static_methods = filter(sidlir.is_static, impl_methods) # # Class # ci.impl.new_def(gen_doc_comment(cls.doc_comment, chpl_stub)+ # 'class %s_Impl {'%qname) # splicer = '.'.join(cls.qualified_name+['Impl']) # ci.impl.new_def('// DO-NOT-DELETE splicer.begin(%s)'%splicer) # ci.impl.new_def('// DO-NOT-DELETE splicer.end(%s)'%splicer) # for method in class_methods: # self.generate_server_method(symbol_table, method, ci) # ci.impl.new_def('} // class %s_Impl'%qname) # ci.impl.new_def('') # ci.impl.new_def('') # # Static # if static_methods: # ci.impl.new_def('// all static member functions of '+qname) # ci.impl.new_def(gen_doc_comment(cls.doc_comment, chpl_stub)+ # '// FIXME: chpl allows only one module per library //'+ # ' module %s_static_Impl {'%qname) # for method in static_methods: # self.generate_server_method(symbol_table, method, ci) # ci.impl.new_def('//} // module %s_static_Impl'%qname) # ci.impl.new_def('') # ci.impl.new_def('') # # Chapel Stub (client-side Chapel bindings) # self.generate_chpl_stub(chpl_stub, qname, ci) # # Because of Chapel's implicit (filename-based) modules it # # is important for the Chapel stub to be one file, but we # # generate separate files for the cstubs # self.pkg_chpl_stub.new_def(chpl_stub) # Stub (in C), the order of these definitions is somewhat sensitive ci.stub.genh_top(ir.Import(qname + '_IOR')) ci.stub.gen(ir.Import(ci.stub._name)) pkg_name = '_'.join(symbol_table.prefix) ci.stub.gen(ir.Import(pkg_name)) ci.stub.write() # IOR ior_template.generate_ior(ci, with_ior_c=self.server, _braid_config=self.config) ci.ior.write() # Skeleton if self.server: self.generate_skeleton(ci, qname) # Convenience header ext_h = CFile(qname) ext_h.genh(ir.Import(qname + '_IOR')) ext_h.genh(ir.Import(qname + '_Stub')) ext_h.write() # Makefile self.classes.append(qname) if not symbol_table: raise Exception() with match(node): if (sidlir.class_, (Name), Extends, Implements, Invariants, Methods, DocComment): expect(data, None) generate_ext_stub( sidlobjects.Class(symbol_table, node, self.class_attrs)) elif (sidlir.struct, (Name), Items, DocComment): # Generate Chapel stub # self.pkg_chpl_stub.gen(ir.Type_decl(lower_ir(symbol_table, node, struct_suffix=''))) # record it for later, when the package is being finished self.pkg_enums_and_structs.append(struct_ior_names(node)) elif (sidlir.interface, (Name), Extends, Invariants, Methods, DocComment): # Interfaces also have an IOR to be generated expect(data, None) generate_ext_stub( sidlobjects.Interface(symbol_table, node, self.class_attrs)) elif (sidlir.enum, Name, Items, DocComment): # Generate Chapel stub # self.pkg_chpl_stub.gen(ir.Type_decl(node)) # record it for later, when the package is being finished self.pkg_enums_and_structs.append(node) elif (sidlir.package, Name, Version, UserTypes, DocComment): # Generate the chapel stub qname = '_'.join(symbol_table.prefix + [Name]) _, pkg_symbol_table = symbol_table[sidlir.Scoped_id([], Name, '')] if self.in_package: # nested modules are generated in-line # self.pkg_chpl_stub.new_def('module %s {'%Name) self.generate_glue_code(UserTypes, data, pkg_symbol_table) # self.pkg_chpl_stub.new_def('}') else: # server-side Chapel implementation template if self.server: self.begin_impl(qname) # new file for the toplevel package # self.pkg_chpl_stub = ChapelFile(relative_indent=0) self.pkg_enums_and_structs = [] self.in_package = True # recursion! self.generate_glue_code(UserTypes, data, pkg_symbol_table) # write_to(qname+'.chpl', str(self.pkg_chpl_stub)) # server-side Chapel implementation template if self.server: self.end_impl(qname) # Makefile self.pkgs.append(qname) pkg_h = CFile(qname) pkg_h = pkg_h pkg_h.genh(ir.Import('sidl_header')) for es in self.pkg_enums_and_structs: es_ior = babel.lower_ir(pkg_symbol_table, es, header=pkg_h, qualify_names=True) pkg_h.gen(ir.Type_decl(es_ior)) for ext in self.exts: pkg_h.genh(ir.Import(ext)) pkg_h.write() elif (sidlir.user_type, Attrs, Cipse): self.class_attrs = Attrs gen(Cipse) elif (sidlir.file, Requires, Imports, UserTypes): self.in_package = False gen(UserTypes) elif A: if (isinstance(A, list)): for defn in A: gen(defn) else: raise Exception("NOT HANDLED:" + repr(A)) else: raise Exception("match error") return data