A first example of the code generated by tjpp is
provided by the translation of "SimpleClass.tj" into "SimpleClass.java".
The most relevant code fragments are described below.
Directive include is similar to the well-known #include
of C and C++:
$include(header.tjh)
By convention, tjpp requires header files to bear the
extension ".tjh". Path names are relative to "tjpp_include".
Tjpp issues a warning message when it detects
multiple inclusions of the same file.
Preprocessing variables are defined and set as follows:
: MY_TIME_MACRO_ENABLED=1
Tjpp's preferred file for these variables
is "tjpp_include/tjpp.defs", but users can freely
define additional variables as needed.
Conditional code generation directly uses Tefigel's
instructions IF, ELSE, and ENDIF:
@ IF MY_TIME_MACRO_ENABLED=1
// DATE of preprocessing: $my_macros/timestamp(date)
// TIME of preprocessing: $my_macros/timestamp(time)
@ ELSE
// Oops, my time macro is not enabled!
@ ENDIF
User-defined macros are used as the my_macros/timestamp
macro in the following fragment:
// DATE of preprocessing: $my_macros/timestamp(date)
The dollar sign "$" instructs tjpp to call macro "my_macros/timestamp"
with parameter "date", and replace the macro call in input with
its string result in output. The macro file "my_macros/timestamp"
is to be found under "tjpp_lib".
Note that the macro can be used even within Java comments,
as tjpp is unaware of Java syntax and semantics.
The source code of the timestamp
macro is commented at the end of this chapter.
Another example of user macro is provided by "ComplexClass.tj",
a file presented in detail later in this booklet:
double d = $my_macros/perc(anInt,1000);
The above line translates to
double d = ((anInt) * 100.0 / (1000));
The source code of this macro
is commented at the end of this chapter.
Tjpp allows to define more powerful macros, generating
whole blocks of code. An example is presented later in
paragraph "Exercise: Improving Multitier Code Consistency".
Variable tracing is used as follows:
public void setAThing( Object aThing ) {
$ trace(aThing)
this.aThing = aThing;
}
and generates the following code:
public void setAThing( Object aThing ) {
System.err.println("[T] File subpackage/SimpleClass.java, line 68
(src: subpackage/SimpleClass.tj, 56)");
System.err.println("[T] [aThing = '" + aThing + "']");
this.aThing = aThing;
}
Note that, for debugging convenience, the trace message reports
file name and line number of both ".tj" and ".java" files.
Several variables can be traced in one trace, as shown
by the following fragment from "ComplexClass.tj":
$ trace(aRange,aColor)
Code Example 1 - Input code to generate SimpleClass.java
|
Line 1 shows an example of use of a tjpp variable,
namely PACKAGE_ROOT, which is set in
"tjpp_include/tjpp.defs".
Lines 9-10 use directive $include, referring to
files available under "tjpp_include".
Line 12 sets a tjpp variable, which is then used for
the conditional code block of lines 13-18.
Lines 14-15 call a user-defined macro from "tjpp_lib",
namely tjpp_lib/my_macros/timestamp.
Directive $trace is used on lines 39 and 56.
|
|
Source code - File "input_code/subpackage/SimpleClass.tj"
|
1 package PACKAGE_ROOT.subpackage;
2
3 /**
4 * Class SimpleClass:
5 *
6 * A simple software entity.
7 */
8
9 $include(header.tjh)
10 $include(subinc/subhdr.tjh)
11
12 : MY_TIME_MACRO_ENABLED=1
13 @ IF MY_TIME_MACRO_ENABLED=1
14 // DATE of preprocessing: $my_macros/timestamp(date)
15 // TIME of preprocessing: $my_macros/timestamp(time)
16 @ ELSE
17 // Oops, my time macro is not enabled!
18 @ ENDIF
19
20 public class SimpleClass {
21
22 private String aStringOfChar;
23 private int anInt;
24 private Object aThing;
25
26 /*
27 * Get methods
28 */
29
30 public String getAStringOfChar() {
31 return aStringOfChar;
32 }
33
34 public int getAnInt() {
35 return anInt;
36 }
37
38 public Object getAThing() {
39 $ trace(aThing)
40 return aThing;
41 }
42
43 /*
44 * Set methods
45 */
46
47 public void setAStringOfChar( String aStringOfChar ) {
48 this.aStringOfChar = aStringOfChar;
49 }
50
51 public void setAnInt( int anInt ) {
52 this.anInt = anInt;
53 }
54
55 public void setAThing( Object aThing ) {
56 $ trace(aThing)
57 this.aThing = aThing;
58 }
59
60 }
|
|
Code Example 2 - Code generated from SimpleClass.tj
|
Lines 1-3 and 70-72 contain a warning message automatically
generated by tjpp.
Line 4 shows that PACKAGE_ROOT has been replaced by
com.somusar.tjpptest, as expected.
The $include directives have produced code lines 12-22.
Lines 24 and 25 contain the results returned by macro
my_macros/timestamp.
Lines 46-47 and 64-65 correspond to the two $traces
of "subpackage/SimpleClass.tj".
|
|
Source code - File "generated_code/subpackage/SimpleClass.java"
|
1 // WARNING: file "subpackage/SimpleClass.java" generated from "subpackage/SimpleClass.tj"
2 // Changes should be applied on the source file.
3
4 package com.somusar.tjpptest.subpackage;
5
6 /**
7 * Class SimpleClass:
8 *
9 * A simple software entity.
10 */
11
12 // begin include "header.tjh"
13 //
14 // Sample header file for Java preprocessor
15 //
16 // end include "header.tjh"
17 // begin include "subinc/subhdr.tjh"
18 //
19 // Sample header file for Java preprocessor from a subdirectory
20 // of include root directory "tjpp_inst/tjpp_include"
21 //
22 // end include "subinc/subhdr.tjh"
23
24 // DATE of preprocessing: timestamp for "date": Wed Dec 03 2003
25 // TIME of preprocessing: timestamp for "time": 17:35:16.844
26
27 public class SimpleClass {
28
29 private String aStringOfChar;
30 private int anInt;
31 private Object aThing;
32
33 /*
34 * Get methods
35 */
36
37 public String getAStringOfChar() {
38 return aStringOfChar;
39 }
40
41 public int getAnInt() {
42 return anInt;
43 }
44
45 public Object getAThing() {
46 System.err.println("[T] File subpackage/SimpleClass.java, line 46 (src: subpackage/SimpleClass.tj, 39)");
47 System.err.println("[T] [aThing = '" + aThing + "']");
48 return aThing;
49 }
50
51 /*
52 * Set methods
53 */
54
55 public void setAStringOfChar( String aStringOfChar ) {
56 this.aStringOfChar = aStringOfChar;
57 }
58
59 public void setAnInt( int anInt ) {
60 this.anInt = anInt;
61 }
62
63 public void setAThing( Object aThing ) {
64 System.err.println("[T] File subpackage/SimpleClass.java, line 64 (src: subpackage/SimpleClass.tj, 56)");
65 System.err.println("[T] [aThing = '" + aThing + "']");
66 this.aThing = aThing;
67 }
68
69 }
70
71 // WARNING: file "subpackage/SimpleClass.java" generated from "subpackage/SimpleClass.tj"
72 // Changes should be applied on the source file.
|
|
Code Example 3 - A user-defined macro: timestamp
|
Line 1 defines the interface of this macro, which expects
one parameter called "what".
Lines 7 and 9 call Tefigel's built-in functions DATE
and TIME.
Line 11 sets the return value of this macro to the string
on the right side of the assignment.
|
|
Source code - File "input_code/tjpp_lib/my_macros/timestamp"
|
1 @ INTERFACE(what)
2 |
3 | Sample user-defined macro, returning a string
4 | with a time stamp, as requested via parameter "what"
5 |
6 @ IF what=date
7 @ SET TS=$DATE
8 @ ELSE
9 @ SET TS=$TIME
10 @ ENDIF
11 @ RETVALUE=timestamp for "what": TS
|
|
Code Example 4 - Another user-defined macro: perc
|
This tjpp macro is equivalent to the following
C #define:
#define perc(a,b) ((a) * 100.0 / (b))
A major advantage of tjpp macros is that
they reside in individual files and are called by means
of their file-system path name, relative to "tjpp_lib".
Moreover, they can accept a variable number of
arguments. This particular macro expects two arguments,
referred to by means of local variables a and b,
as specified on line 1.
|
|
Source code - File "input_code/tjpp_lib/my_macros/perc"
|
1 @ INTERFACE(a,b)
2 |
3 | Sample user-defined macro, returning a code string
4 | to compute the percentage on given arguments.
5 |
6 @ RETVALUE=((a) * 100.0 / (b))
|
|
[Previous chapter]
[Next chapter]
[Back to top]
|