Next: A minimal C-based backend, Previous: Backend creation, Up: Backend creation [Contents][Index]
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.
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 #include
s
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: A minimal C-based backend, Previous: Backend creation, Up: Backend creation [Contents][Index]