4. Verbatim Code

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.

4.1 Declarative Verbatim Code

Declarative verbatim code is introduced with the delimiter %{ and ends with the delimiter %}. Here are a few examples.

Declarative Verbatim Code Examples
// Declare a global pointer
%{ char *p; %}

// Customize declaration of class member variables
class Example {
    %{ private: %}
    int(5) a;

    %{ protected: %}
    unsigned char(6) b;

    // Declare a method (will be protected)
    %{ int dosomething(void); %}
    
    // Declare an inline method
    %{ inline int geta(void) { return a; } %}
}

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).

4.2 Get() Verbatim Code

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.

Get() Verbatim Code Example
class Example {
    int(5) a;

    %g{ printf("after 'a' (=%d), but before 'b'\n", a); %g}

    unsigned char(6) b;
}

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.

4.3 Put() Verbatim Code

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:

Put() Verbatim Code Example
class Example {
    int(5) a;

    %p{ printf("after 'a', but before 'b'\n"); %p}

    unsigned char(6) b;
}

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).

4.4 Get()/Put() Verbatim Code

For cases where the same code should be inserted in both the get() and the put() method, the delimiters %*{ and %*} can be used.

4.5 Verbatim delimeters

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

4.6 Debugging Verbatim Code

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.

 

Copyright Notice