XTRAN Example — Translate IBM Series/1 EDL to C

The following example uses the standard set of XTRAN rules ("meta-code") for parsing EDL and translating it to C.

NOTE that the translation shown below was done with default conditions.  XTRAN provides many options for controlling the way it translates.

We have declared to XTRAN the following C structures prior to translation:

    struct str1
        {
        short strmem1;
        };

    typedef struct
        {
        char strmem2;
        }
        Str2;

We have also told XTRAN, via meta-code, that a struct str1 allocation exists named str.



Process Flowchart

Here is a flowchart for this process, in which the elements are color coded:

process flowchart

Input to XTRAN:

* Expression conversion to symbols:  on
* Register "unioning":  on
* Address arithmetic:  off
* Pointer variables:  off
A1   EQU  5                   A1    EQU  5
B1   EQU  6                   B1    EQU  6
C1   EQU  7                   C1    EQU  7
D1   EQU  8                   D1    EQU  8
E1   EQU  9                   E1    EQU  9
FOO1 EQU  A1+1                FOO1  EQU  A1+1
     MOVE (STRMEM2,#1),BVAR1,BYTE   MOVE (STRMEM2,#1),BVAR1,BYTE
     MOVE (STRMEM1,#2),#1           MOVE (STRMEM1,#2),#1
     MOVE (D1,#1),(WARR1,#1)        MOVE (D1,#1),(WARR1,#1)
     MOVE (E1,#1),(BARR2,#1),BYTE   MOVE (E1,#1),(BARR2,#1),BYTE
     MOVE STR+STRMEM1,#1            MOVE STR+STRMEM1,#1
     MOVE (B1+C1-1,#1),#1           MOVE (B1+C1-1,#1),#1
* Expression conversion to symbols:  on (ignored)
* Register "unioning":  on
* Address arithmetic:  on
* Pointer variables:  off
A2   EQU  5                   A2    EQU  5
B2   EQU  6                   B2    EQU  6
C2   EQU  7                   C2    EQU  7
D2   EQU  8                   D2    EQU  8
E2   EQU  9                   E2    EQU  9
FOO2 EQU  A2+1                FOO2  EQU  A2+1
     MOVE (STRMEM2,#1),BVAR1,BYTE   MOVE (STRMEM2,#1),BVAR1,BYTE
     MOVE (STRMEM1,#2),#1           MOVE (STRMEM1,#2),#1
     MOVE (D2,#1),(WARR1,#1)        MOVE (D2,#1),(WARR1,#1)
     MOVE (E2,#1),(BARR2,#1),BYTE   MOVE (E2,#1),(BARR2,#1),BYTE
     MOVE STR+STRMEM1,#1            MOVE STR+STRMEM1,#1
     MOVE (B2+C2-1,#1),#1           MOVE (B2+C2-1,#1),#1
* Finally, at this point we told XTRAN to use pointer variables
* in address arithmetic generation.
*
* Expression conversion to symbols:  on (ignored)
* Register "unioning":  on
* Address arithmetic:  on
* Pointer variables:  on
A3   EQU  5                   A3    EQU  5
B3   EQU  6                   B3    EQU  6
C3   EQU  7                   C3    EQU  7
D3   EQU  8                   D3    EQU  8
E3   EQU  9                   E3    EQU  9
FOO3 EQU  A3+1                FOO3  EQU  A3+1
     MOVE (STRMEM2,#1),BVAR1,BYTE   MOVE (STRMEM2,#1),BVAR1,BYTE
     MOVE (STRMEM1,#2),#1           MOVE (STRMEM1,#2),#1
     MOVE (D3,#1),(WARR1,#1)        MOVE (D3,#1),(WARR1,#1)
     MOVE (E3,#1),(BARR2,#1),BYTE   MOVE (E3,#1),(BARR2,#1),BYTE
     MOVE STR+STRMEM1,#1            MOVE STR+STRMEM1,#1
     MOVE (B3+C3-1,#1),#1           MOVE (B3+C3-1,#1),#1


Output from XTRAN:

   extern struct str1 str;
   extern union                             /*unionize reg1*/
       {
       Str2 *p__Str2;
       short s;
       struct unkn_str *p__unkn_str;
       char *p_c;
       }
       reg1;
   extern struct str1 *reg2;

   static short warr1[] = {1, 2, 3, 4};     /*warr1 data  f'1',f'2',f'3',f'4'*/
   static short warr2[4] = { 0 };           /*warr2 data  4f*/
   short wvar1 = 0;                         /*wvar1 data  f*/
   static char barr1[] = {4, 3, 2, 1};      /*barr1 data  h'4',h'3',h'2',h'1'*/
   static char barr2[3] = { 0 };            /*barr2 data  3h*/
   char bvar1 = 0;                          /*bvar1 data  h*/
   struct unkn_str
       {
       short d1;
       char e1;
       short b1_pl_c1_mi_1;
       };

   short *p_opnd_a;
   short *p_opnd_b;
/*
 * Expression conversion to symbols:  on
 * Register "unioning":  on
 * Address arithmetic:  off
 * Pointer variables:  off
 */
#define A1 5                                /*a1    equ  5*/
#define B1 6                                /*b1    equ  6*/
#define C1 7                                /*c1    equ  7*/
                                            /*d1    equ  8*/
                                            /*e1    equ  9*/
#define FOO1 (A1 + 1)                       /*foo1  equ  a1+1*/
   reg1.p__Str2->strmem2 = bvar1;           /*move (strmem2,#1),bvar1,byte*/
   reg2->strmem1 = reg1.s;
   reg1.p__unkn_str->d1 = warr1[reg1.s /
     2];                                    /*move (d1,#1),(warr1,#1)*/
   reg1.p__unkn_str->e1 = barr2[reg1.s];    /*move (e1,#1),(barr2,#1),byte*/
   str.strmem1 = reg1.s;                    /*move str+strmem1,#1*/
   reg1.p__unkn_str->b1_pl_c1_mi_1 =
     reg1.s;                                /*move (b1+c1-1,#1),#1*/
/*
 * Expression conversion to symbols:  on (ignored)
 * Register "unioning":  on
 * Address arithmetic:  on
 * Pointer variables:  off
 */
#define A2 5                                /*a2    equ  5*/
#define B2 6                                /*b2    equ  6*/
#define C2 7                                /*c2    equ  7*/
#define D2 8                                /*d2    equ  8*/
#define E2 9                                /*e2    equ  9*/
#define FOO2 (A2 + 1)                       /*foo2  equ  a2+1*/
   reg1.p__Str2->strmem2 = bvar1;           /*move (strmem2,#1),bvar1,byte*/
   reg2->strmem1 = reg1.s;                  /*move (strmem1,#2),#1*/
   *(short *) (reg1.p_c + D2) = *(short *)
     ((char *) warr1 + reg1.s);             /*move (d2,#1),(warr1,#1)*/
   *(reg1.p_c + E2) = *(barr2 + reg1.s);    /*move (e2,#1),(barr2,#1),byte*/
   str.strmem1 = reg1.s;                    /*move str+strmem1,#1*/
   *(short *) (reg1.p_c + (B2 + C2 - 1)) =
     reg1.s;                                /*move (b2+c2-1,#1),#1*/
/*
 * Finally, at this point we told XTRAN to use pointer variables
 * in address arithmetic generation.
 *
 * Expression conversion to symbols:  on (ignored)
 * Register "unioning":  on
 * Address arithmetic:  on
 * Pointer variables:  on
 */
#define A3 5                                /*a3    equ  5*/
#define B3 6                                /*b3    equ  6*/
#define C3 7                                /*c3    equ  7*/
#define D3 8                                /*d3    equ  8*/
#define E3 9                                /*e3    equ  9*/
#define FOO3 (A3 + 1)                       /*foo3  equ  a3+1*/
   reg1.p__Str2->strmem2 = bvar1;           /*move (strmem2,#1),bvar1,byte*/
   reg2->strmem1 = reg1.s;                  /*move (strmem1,#2),#1*/
   p_opnd_a = (short *) (reg1.p_c + D3);    /*set up operand pointer*/
   p_opnd_b = (short *) ((char *) warr1 +
     reg1.s);                               /*set up operand pointer*/
   *p_opnd_a = *p_opnd_b;                   /*move (d3,#1),(warr1,#1)*/
   p_opnd_a = (short *) (reg1.p_c + E3);    /*set up operand pointer*/
   p_opnd_b = (short *) (barr2 + reg1.s);   /*set up operand pointer*/
   *(char *) p_opnd_a = *(char *) p_opnd_b; /*move (e3,#1),(barr2,#1),byte*/
   str.strmem1 = reg1.s;                    /*move str+strmem1,#1*/
   p_opnd_a = (short *) (reg1.p_c + (B3 +
     C3 - 1));                              /*set up operand pointer*/
   *p_opnd_a = reg1.s;                      /*move (b3+c3-1,#1),#1*/