In order to develop a fully functional C++ or Java program, it is sometimes desirable to expand Flavor-defined classes with additional functionality. This can be easily done by deriving new classes from the ones defined in the Flavor source code. When only trivial modifications are needed, however, this may require more effort that necessary.
More importantly, it is sometimes desirable to intervene to the code generated by the translator.
A trivial example is to ensure that member variables are declared private
or
protected
, rather than the default of public
used by the translator.
Other examples include constructors and destructors, in-line methods, etc. More sophisticated
cases involve intervention to the get()
or put()
code produced by the
translator.
In order to facilitate the highest possible level of integration between Flavor and the base language (C++ or Java), the translator supports verbatim code segments. In other words, segments that contain user code which will be ignored by the Flavor translator, but copied verbatim to the output file.
There are four different types of verbatim code segments, reflecting the different program areas
where such code should be copied: class declaration or global scope, put()
method,
get()
method, or both put()
and get()
methods. Regardless
of the type, verbatim code can appear wherever a regular Flavor statement or declaration can
appear. Also, it is copied to the output file at the exact position where it appears.
The verbatim code segments are enclosed with the verbatim delimeters. For example the
delimeters for verbatim code which goes to the global scope of the generated code are:
%{
and %}
. In order to differentiate the verbatim code segments for
Java and C++ more decorated version of verbatim delimeters are provided. For example the verbatim
code segment enclosed with %.j{
and %.j}
goes to the global scope of
the generated Java code but not in C++ code.
In the following, in addition to describing the various types of verbatim code and its use, we also describe how to facilitate compilation and debugging of such code. The delimeters used in the examples are both for Java and C++. So all the verbatim code between in the delimeters appeared in the sample codes would be copied into both Java and C++ code. The complete list of verbatim delimeters are provided below.
Declarative verbatim code is introduced with the delimiter %{
and ends with the
delimiter %}
. Here are a few examples.
|
The declaration of the pointer p
in file scope will be placed before the
Example
class is declared. Similarly, the private
keyword will be
inserted before a
is declared. The translator outputs a public
directive right at the beginning of the class; as a result, any other directive inserted will
override it. The dosomething()
method will be declared as protected
since this is the directive that is active when its declaration is encountered (it is the
directive preceding the declaration of b
).
This verbatim code segment is enclosed in the delimiters %g{
and %g}
.
All text contained between these two will be output at the exact same place in the
get()
method only. Let's see an example.
|
The printf()
statement will be inserted in the get()
method after the
code for outputting a
(including any required code for tracing, if requested), but
before the code for outputting b
.
Similarly to the previous case, this verbatim code segment is enclosed in the delimiters
%p{
and %p}
. All text contained between these two will be output at
the exact same place in the put()
method only. Using our previous example:
|
Here the printf()
statement will be inserted in the put()
method after
the code for outputting a
, but before the code for outputting b
. This
allows the programmer very fine control, even inside the put()
method. For
example, you could place at the top of the definition of a Flavor class a call to a function that
will transform its data and prepare them for output. This way, a single call to the
put()
method will perform both the transformation (encoding) and outputing the
resulting bits (creating the bitstream representation).
For cases where the same code should be inserted in both the get()
and the
put()
method, the delimiters %*{
and %*}
can be used.
Verbatim Delimeters | Destination of Verbatim code |
%{ and %} |
Global scope of C++ and Java |
%g{ and %g} |
Get method of C++ and Java |
%p{ and %p} |
Put method of C++ and Java |
%*{ and %*} |
Both Get and Put methods of C++ and Java |
%.c{ and %.c} |
Global scope of C++ |
%g.c{ and %g.c} |
Get method of C++ |
%p.c{ and %p.c} |
Put method of C++ |
%*.c{ and %*.c} |
Both Get and Put methods of C++ |
%.j{ and %.j} |
Global scope of Java |
%g.j{ and %g.j} |
Get method of Java |
%p.j{ and %p.j} |
Put method of Java |
%*.j{ and %*.j} |
Both Get and Put methods of Java |
When verbatim code is used, the translator generates C++ preprocessor statements to indicate its position in the Flavor source code. This helps development environments that automatically position the programmer's editor to the source position where the error was detected. This information is also used by source code debuggers to position their source window to the right file and line.
In the case where you want compiler error messages to refer to the
flavorc
-generated C++ file, or your debugger to use the
flavorc
-generated C++ file, you can switch output of such line information off
using the -l
command line option or the line
pragma directive.