In large software development projects it is often
necessary to maintain a high level of consistency across different
development teams using different programming languages.
Although this type of consistency is actually one of the main features
of the SoProTech[tm], in some simple cases it is
possible to achieve a good level of consistency by using just
Tefigel.
The next example shows how to effectively and quickly
generate consistent Java[tm] and C declarations by FILTERing
a textual list of instructions. An HTML documentation
file could just as easily be generated.
The starting point of the example is the list of Tefigel instructions.
Purpose of the example is to process this list and generate
the corresponding sets of declarations in both Java[tm] and C.
Instruction set of Tefigel - File "instr_set"
|
1 # Instructions on variables
2 GLOBSET
3 POP
4 PUSH
5 SET
6 UNSET
7
8 # Arithmetic instructions
9 ADD
10 DIV
11 MUL
12 SUB
13 TRUNC
14 NEG
15
16 # Logical instructions
17 AND
18 EVAL
19 NOT
20 OR
21
22 # Control flow
23 IF
24 ELSE
25 ENDIF
26 WHILE
27 ENDWHILE
28 JUMPCOND
29 JUMP
30 LABEL
31
32 # Subroutines and functions
33 CALL
34 FILTER
35 LIBRARY
36 QUIT
37 RETVALUE
38
39 # Input/output
40 APPEND
41 ATTACH
42 ECHO
43 MSG
44 OUTPUT
45 PROCESS
46 PROCESS_IF_READABLE
47
48 # Special characters and operators
49 ARGDELIM
50 CALLKEY
51 DASH
52 ESCAPE
53 LINEBREAK
54 MARK
55
56 # Miscellaneous instructions
57 DUMP
58 REM
59 RESET
60 SWITCH
61 SYSTEM
62 VERSION
|
|
The list filter consists of one main script and two input filters,
one for processing lines containing instructions and blank lines,
one for processing comment lines.
Code Example 41 - List filters
|
This Tefigel filter produces two output files, creating them
via the instruction OUTPUT on lines 9 and 15. It
declares on lines 19 and 20 two filters, one for input
comment lines (instr_comment),
and one for non-comment lines (instr_code).
Then it PROCESSes the instruction set on line 21, and
APPENDs one trailing line to each file at the end.
The filter does not write anything to its standard output,
which is thus empty.
|
|
Source code - File "instr_filter"
|
1 @ mark rem |
2 @ dash $
3 @ switch STRICT_CMDMARK=1
4 |
5 | Initialization: naming and creation of output files
6 |
7 @ globset j_out=Out/InstrSet.java
8 @ globset h_out=Out/instr_set.h
9 @ output j_out
10 //
11 // j_out - generated on ~date at ~time
12 //
13
14 public class InstrSet {
15 @ output h_out
16 /*
17 * h_out - generated on ~date at ~time
18 */
19 @ filter instr_comment ^#
20 @ filter instr_code ^[^#]*$
21 @ process instr_set
22 @ filter instr_code
23 @ filter instr_comment
24 @ append j_out
25 }
26 @ append h_out
27
|
|
Output of
"/opt/somusar/bin/tefigel instr_filter"
|
|
|
Code Example 42 - List filter 1
|
This filter counts the instruction codes (variable instruction_code),
skips blank input lines, and prints proper Java and C definitions
to the corresponding output files. Note use of built-in TABS on lines
22 and 24.
|
|
Source code - File "instr_code"
|
1 @ interface(input_line)
2 |
3 | Skip blank lines on input.
4 |
5 @ eval blank input_line~^[ ]*$
6 @ if blank=1
7 @ quit
8 @ endif
9 |
10 | If instruction_code is not set yet, then we are at the beginning
11 | of the input file: set it to 0. Otherwise increment it.
12 |
13 @ if instruction_code=
14 @ globset instruction_code=0
15 @ else
16 @ add instruction_code 1
17 @ endif
18 |
19 | Append definition to both files. Format lines using built-in tabs
20 |
21 @ append j_out
22 ~tabs(public final int input_line = instruction_code;,40)
23 @ append h_out
24 ~tabs(#define INSTR_$input_line instruction_code,40)
|
|
|
Source code - File "instr_comment"
|
1 @ interface(input_line)
2 @ set comment_length=~length(input_line)
3 @ sub comment_length 1
4 @ set comment=~substr(input_line,1,comment_length)
5 @ append j_out
6
7 //
8 //comment
9 //
10
11 @ append h_out
12
13 /*
14 * comment
15 */
16
|
|
The resulting Java[tm] and C output files are listed below.
The instruction set in Java[tm] - File "Out/InstrSet.java"
|
1 //
2 // Out/InstrSet.java - generated on Thu Sep 27 2012 at 13:05:08.456
3 //
4
5 public class InstrSet {
6
7 //
8 // Instructions on variables
9 //
10
11 public final int GLOBSET = 0;
12 public final int POP = 1;
13 public final int PUSH = 2;
14 public final int SET = 3;
15 public final int UNSET = 4;
16
17 //
18 // Arithmetic instructions
19 //
20
21 public final int ADD = 5;
22 public final int DIV = 6;
23 public final int MUL = 7;
24 public final int SUB = 8;
25 public final int TRUNC = 9;
26 public final int NEG = 10;
27
28 //
29 // Logical instructions
30 //
31
32 public final int AND = 11;
33 public final int EVAL = 12;
34 public final int NOT = 13;
35 public final int OR = 14;
36
37 //
38 // Control flow
39 //
40
41 public final int IF = 15;
42 public final int ELSE = 16;
43 public final int ENDIF = 17;
44 public final int WHILE = 18;
45 public final int ENDWHILE = 19;
46 public final int JUMPCOND = 20;
47 public final int JUMP = 21;
48 public final int LABEL = 22;
49
50 //
51 // Subroutines and functions
52 //
53
54 public final int CALL = 23;
55 public final int FILTER = 24;
56 public final int LIBRARY = 25;
57 public final int QUIT = 26;
58 public final int RETVALUE = 27;
59
60 //
61 // Input/output
62 //
63
64 public final int APPEND = 28;
65 public final int ATTACH = 29;
66 public final int ECHO = 30;
67 public final int MSG = 31;
68 public final int OUTPUT = 32;
69 public final int PROCESS = 33;
70 public final int PROCESS_IF_READABLE = 34;
71
72 //
73 // Special characters and operators
74 //
75
76 public final int ARGDELIM = 35;
77 public final int CALLKEY = 36;
78 public final int DASH = 37;
79 public final int ESCAPE = 38;
80 public final int LINEBREAK = 39;
81 public final int MARK = 40;
82
83 //
84 // Miscellaneous instructions
85 //
86
87 public final int DUMP = 41;
88 public final int REM = 42;
89 public final int RESET = 43;
90 public final int SWITCH = 44;
91 public final int SYSTEM = 45;
92 public final int VERSION = 46;
93 }
|
|
The instruction set in C - File "Out/instr_set.h"
|
1 /*
2 * Out/instr_set.h - generated on Thu Sep 27 2012 at 13:05:08.457
3 */
4
5 /*
6 * Instructions on variables
7 */
8
9 #define INSTR_GLOBSET 0
10 #define INSTR_POP 1
11 #define INSTR_PUSH 2
12 #define INSTR_SET 3
13 #define INSTR_UNSET 4
14
15 /*
16 * Arithmetic instructions
17 */
18
19 #define INSTR_ADD 5
20 #define INSTR_DIV 6
21 #define INSTR_MUL 7
22 #define INSTR_SUB 8
23 #define INSTR_TRUNC 9
24 #define INSTR_NEG 10
25
26 /*
27 * Logical instructions
28 */
29
30 #define INSTR_AND 11
31 #define INSTR_EVAL 12
32 #define INSTR_NOT 13
33 #define INSTR_OR 14
34
35 /*
36 * Control flow
37 */
38
39 #define INSTR_IF 15
40 #define INSTR_ELSE 16
41 #define INSTR_ENDIF 17
42 #define INSTR_WHILE 18
43 #define INSTR_ENDWHILE 19
44 #define INSTR_JUMPCOND 20
45 #define INSTR_JUMP 21
46 #define INSTR_LABEL 22
47
48 /*
49 * Subroutines and functions
50 */
51
52 #define INSTR_CALL 23
53 #define INSTR_FILTER 24
54 #define INSTR_LIBRARY 25
55 #define INSTR_QUIT 26
56 #define INSTR_RETVALUE 27
57
58 /*
59 * Input/output
60 */
61
62 #define INSTR_APPEND 28
63 #define INSTR_ATTACH 29
64 #define INSTR_ECHO 30
65 #define INSTR_MSG 31
66 #define INSTR_OUTPUT 32
67 #define INSTR_PROCESS 33
68 #define INSTR_PROCESS_IF_READABLE 34
69
70 /*
71 * Special characters and operators
72 */
73
74 #define INSTR_ARGDELIM 35
75 #define INSTR_CALLKEY 36
76 #define INSTR_DASH 37
77 #define INSTR_ESCAPE 38
78 #define INSTR_LINEBREAK 39
79 #define INSTR_MARK 40
80
81 /*
82 * Miscellaneous instructions
83 */
84
85 #define INSTR_DUMP 41
86 #define INSTR_REM 42
87 #define INSTR_RESET 43
88 #define INSTR_SWITCH 44
89 #define INSTR_SYSTEM 45
90 #define INSTR_VERSION 46
91
|
|
[Previous chapter]
[Next chapter]
[Back to top]
|