Next: , Previous: , Up: Backend creation   [Contents][Index]


6.2.1 Hook methods

Multiple code generators for the same language but different communication libraries are apt to contain much code in common. Because C is a popular language, coNCePTuaL provides a codegen_c_generic.py module that implements a virtual NCPTL_CodeGen base class. This base class implements all of the methods listed in Method calls. However, rather than support a particular communication library, the codegen_c_generic.py implementation of NCPTL_CodeGen merely provides a number of calls to “hook” methods—placeholders that implement library-specific functionality. See C hooks, for a list of all of the hooks that codegen_c_generic.py defines. For clarity, hooks are named after the method from which they’re called but with an all-uppercase tag appended. Hook methods take a single parameter, a read-only dictionary (the result of invoking Python’s locals() function) of all of the local variables in the caller’s scope. They return C code in the form of a list with one line of C per element. A hook method is invoked only if it exists, which gives the backend developer some flexibility in selecting places at which to insert code. Of course, for coarser-grained control, a backend developer can override complete methods in codegen_c_generic.py if desired. Generally, this will not be necessary as hook invocations are scattered liberally throughout the file.

An example

codegen_c_generic.py defines a method named code_specify_include_files. ( codegen_c_generic.py names all of its code-generating helper methods ‘code_something’.) code_specify_include_files pushes a sequence of #include directives onto a queue of lines of C code. The method is shown below in its entirety:

def code_specify_include_files(self, node):
    "Load all of the C header files the generated code may need."

    # Output a section comment.
    self.pushmany([
        "/*****************",
        " * Include files *",
        " *****************/",
        ""])

    # Enable hooks both before and after the common includes.
    self.pushmany(self.invoke_hook("code_specify_include_files_PRE",
                                   locals(),
                                   before=[
        "/* Header files specific to the %s backend */" %
        self.backend_name],
                                   after=[""]))
    self.pushmany([
        "/* Header files needed by all C-based backends */",
        "#include <stdio.h>",
        "#include <string.h>",
        "#include <ncptl/ncptl.h>"])
    self.pushmany(self.invoke_hook("code_specify_include_files_POST",
                                   locals(),
                                   before=[
        "",
        "/* Header files specific to the %s backend */" %
        self.backend_name]))

code_specify_include_files uses the pushmany method (see Internals) to push each element in a list of lines of C code onto the output queue. It starts by pushing a section comment— codegen_c_generic.py outputs fully commented C code. Next, it invokes the code_specify_include_files_PRE hook if it exists and pushes that method’s return value onto the queue. Then, it pushes all of the #includes needed by the generated C code. Finally, it invokes the code_specify_include_files_POST hook if it exists and pushes that method’s return value onto the queue.

A backend that requires additional header files from those included by code_specify_include_files need only define code_specify_include_files_PRE to add extra header files before the standard ones or code_specify_include_files_POST to add extra header files after them. The following is a sample (hypothetical) hook definition:

def code_specify_include_files_POST(self, localvars):
    "Specify extra header files needed by the c_pthreads backend."
    return [
        "#include <errno.h>",
        "#include <pthread.h>"]

Although the top-level structure of codegen_c_generic.py is described in Internals, a backend developer will normally need to study the codegen_c_generic.py source code to discern the purpose of each hook method and its relation to the surrounding code.


Next: , Previous: , Up: Backend creation   [Contents][Index]

Scott Pakin, pakin@lanl.gov