XTRAN example — Translate PL/M to C

The following example used the standard set of XTRAN rules for parsing PL/M 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.


Input to XTRAN:

func1:  PROCEDURE EXTERNAL;             /*func1: PROCEDURE EXTERNAL;*/
        END func1;
func2:  PROCEDURE EXTERNAL;             /*func2: PROCEDURE EXTERNAL;*/
        END func2;
func3:  PROCEDURE EXTERNAL;             /*func3: PROCEDURE EXTERNAL;*/
        END func3;

        DECLARE outidx WORD;            /*DECLARE outidx WORD;*/

proc1:  PROCEDURE(arg);                 /*proc1: PROCEDURE(arg);*/
        DECLARE arg WORD;               /*DECLARE arg WORD;*/
        DECLARE (byt1, byt2) BYTE;      /*DECLARE (byt1, byt2) BYTE;*/
        DECLARE (wrd1, wrd2, wrd3) WORD; /*DECLARE (wrd1, wrd2, wrd3) WORD;*/
        DECLARE (int1, int2) INTEGER;   /*DECLARE (int1, int2) INTEGER;*/

lbl3:   DO CASE arg;                    /*lbl3: DO CASE arg;*/
            wrd2 = 1;                   /*wrd2 = 1;*/
            DO;                         /*DO;*/
                IF wrd1 < wrd2 THEN     /*IF wrd1 < wrd2 THEN*/
                    wrd2 = 1;           /*wrd2 = 1;*/
                ELSE                    /*ELSE*/
                    DO WHILE wrd1 < 1;  /*DO WHILE wrd1 < 1;*/
                        wrd2 = 2;       /*wrd2 = 2;*/
                        wrd3 = 1 + wrd3; /*wrd3 = 1 + wrd3;*/
                    END;
                wrd1 = wrd2;            /*wrd1 = wrd2;*/
            END;
            wrd2 = wrd2 + 3;            /*wrd2 = wrd2 + 3;*/
            IF wrd2 < 3 THEN            /*IF wrd2 < 3 THEN*/
                wrd2 = 4 + wrd2;        /*wrd2 = 4 + wrd2;*/
            ELSE                        /*ELSE*/
                DO;                     /*DO;*/
                wrd2 = 5 * wrd2;        /*wrd2 = 5 * wrd2;*/
                wrd3 = wrd3 / 6;        /*wrd3 = wrd3 / 6;*/
                END;
        END lbl3;                       /*END lbl3;*/
        DO byt1 = 1 to byt2 BY 2;       /*DO byt1 = 1 to byt2 BY 2;*/
            wrd3 = wrd1 + 2;            /*wrd3 = wrd1 + 2;*/
        END;
        DO WHILE wrd2 < 3;              /*DO WHILE wrd2 < 3;*/
            wrd1 = 1;                   /*wrd1 = 1;*/
            wrd1 = wrd1 - 1;            /*wrd1 = wrd1 - 1;*/
            DO wrd1 = 1 to wrd2 by 2;   /*DO wrd1 = 1 to wrd2 by 2;*/
                wrd3 = 2 - wrd3;        /*wrd3 = 2 - wrd3;*/
            END;
            DO int1 = int2 to 1 by -1;  /*DO int1 = int2 to 1 by -1;*/
                wrd3 = wrd1;            /*wrd3 = wrd1;*/
            END;
        END;
        RETURN (wrd1);                  /*RETURN (wrd1);*/
        END proc1;

proc2:  PROCEDURE(arg);                 /*proc2: PROCEDURE(arg);*/
        DECLARE arg WORD;               /*DECLARE arg WORD;*/
        DECLARE (byt1, byt2) BYTE;      /*DECLARE (byt1, byt2) BYTE;*/
        DECLARE (wrd1, wrd2, wrd3) WORD; /*DECLARE (wrd1, wrd2, wrd3) WORD;*/
        DECLARE fnam POINTER;           /*DECLARE fnam POINTER;*/
        DECLARE fnarr (3) POINTER       /*DECLARE fnarr (3) POINTER..*/
          DATA(.func1, .func2, .func3); /*..DATA(.func1, .func2, .func3);*/
        DECLARE str1 STRUCTURE          /*DECLARE str1 STRUCTURE..*/
          (m1 WORD, m2 BYTE)            /*..(m1 WORD, m2 BYTE)..*/
          DATA (1, 2);                  /*..DATA (1, 2);*/

        DO byt2 = 1 to byt1;            /*DO byt2 = 1 to byt1;*/
            wrd3 = wrd1;                /*wrd3 = wrd1;*/
        END;
        DO outidx = 1 to 3;             /*DO outidx = 1 to 3;*/
            wrd1 = wrd3;                /*wrd1 = wrd3;*/
        END;
        wrd1 = (wrd2 := wrd3 + 1) + 2;  /*wrd1 = (wrd2 := wrd3 + 1) + 2;*/
        fnam = @func1;                  /*fnam = @func1;*/
        CALL fnam;                      /*CALL fnam;*/
        CALL func1;                     /*CALL func1;*/ 
        fnam = fnarr(1);                /*fnam = fnarr(1);*/
        CALL fnam;                      /*CALL fnam;*/
        END proc2;

Output from XTRAN:

        extern void func1(void);        /*func1: PROCEDURE EXTERNAL;*/
        extern void func2(void);        /*func2: PROCEDURE EXTERNAL;*/
        extern void func3(void);        /*func3: PROCEDURE EXTERNAL;*/

        static unsigned short outidx;   /*DECLARE outidx WORD;*/

static void proc1(unsigned short arg)   /*proc1: PROCEDURE(arg);*/
{
        static unsigned char byt1, byt2; /*DECLARE (byt1, byt2) BYTE;*/
                                        /*DECLARE arg WORD;*/
        static unsigned short wrd1,
          wrd2, wrd3;                   /*DECLARE (wrd1, wrd2, wrd3) WORD;*/
        static short int1, int2;        /*DECLARE (int1, int2) INTEGER;*/

        static unsigned char prev_byt1;
        static unsigned short prev_wrd1;
        switch (arg)                    /*lbl3: DO CASE arg;*/
            {
            case 0 :
                wrd2 = 1;               /*wrd2 = 1;*/
                break;

            case 1 :
                                        /*do;*/
                if (wrd1 < wrd2)        /*IF wrd1 < wrd2 THEN*/
                    wrd2 = 1;           /*wrd2 = 1;*/
                else                    /*else*/
                    {
                    while (wrd1 < 1)    /*DO WHILE wrd1 < 1;*/
                        {
                        wrd2 = 2;       /*wrd2 = 2;*/
                        ++wrd3;         /*wrd3 = 1 + wrd3;*/
                        }
                    }
                wrd1 = wrd2;            /*wrd1 = wrd2;*/
                break;

            case 2 :
                wrd2 += 3;              /*wrd2 = wrd2 + 3;*/
                break;

            case 3 :
                if (wrd2 < 3)           /*IF wrd2 < 3 THEN*/
                    wrd2 += 4;          /*wrd2 = 4 + wrd2;*/
                else                    /*else*/
                                        /*do;*/
                                        /*END lbl3;*/
                    {
                    wrd2 *= 5;          /*wrd2 = 5 * wrd2;*/
                    wrd3 /= 6;          /*wrd3 = wrd3 / 6;*/
                    }
                break;
            }
        for (byt1 = prev_byt1 = 1; byt1
          <= byt2 && prev_byt1 <= byt1;
          prev_byt1 = byt1, byt1 += 2)  /*DO byt1 = 1 to byt2 BY 2;*/
            wrd3 = (unsigned short)
              (wrd1 + 2);               /*wrd3 = wrd1 + 2;*/
        while (wrd2 < 3)                /*DO WHILE wrd2 < 3;*/
            {
            wrd1 = 1;                   /*wrd1 = 1;*/
            --wrd1;                     /*wrd1 = wrd1 - 1;*/
            for (wrd1 = prev_wrd1 = 1;
              wrd1 <= wrd2 && prev_wrd1
              <= wrd1; prev_wrd1 = wrd1,
              wrd1 += 2)                /*DO wrd1 = 1 to wrd2 by 2;*/
                wrd3 = (unsigned short)
                  (2 - wrd3);           /*wrd3 = 2 - wrd3;*/
            for (int1 = int2; int1 >= 1;
              --int1)                   /*DO int1 = int2 to 1 by -1;*/
                wrd3 = wrd1;            /*wrd3 = wrd1;*/
            }
        return (wrd1);                  /*RETURN (wrd1);*/
}

static void proc2(unsigned short arg)   /*proc2: PROCEDURE(arg);*/
{
        static unsigned char byt1, byt2; /*DECLARE (byt1, byt2) BYTE;*/
                                        /*DECLARE arg WORD;*/
        static unsigned short wrd1,
          wrd2, wrd3;                   /*DECLARE (wrd1, wrd2, wrd3) WORD;*/
        static void (*fnam)(void);      /*DECLARE fnam POINTER;*/
        static const void *fnarr[3] = 
            { func1, func2, func3
            };                          /*DECLARE fnarr (3) POINTER..*/
                                        /*..DATA(.func1, .func2, .func3);*/
        static unsigned char prev_byt2;
        static const struct             /*DECLARE str1 STRUCTURE..*/
                                        /*..data (1, 2);*/
            {
            unsigned short m1;
            unsigned char m2;           /*..(m1 WORD, m2 BYTE)..*/
            }
            str1 = 
                { 1, 2
                };

        static unsigned short prev_outidx;
        for (byt2 = prev_byt2 = 1; byt2
          <= byt1 && prev_byt2 <= byt2;
          prev_byt2 = byt2++)           /*DO byt2 = 1 to byt1;*/
            wrd3 = wrd1;                /*wrd3 = wrd1;*/
        for (outidx = prev_outidx = 1;
          outidx <= 3 && prev_outidx <=
          outidx; prev_outidx = outidx++) /*DO outidx = 1 to 3;*/
            wrd1 = wrd3;                /*wrd1 = wrd3;*/
        wrd1 = (wrd2 = (unsigned short)
          (wrd3 + 1)) + 2;              /*wrd1 = (wrd2 := wrd3 + 1) + 2;*/
        fnam = func1;                   /*fnam = @func1;*/
        (*fnam)();                      /*CALL fnam;*/
        func1();                        /*CALL func1;*/
        fnam = fnarr[1];                /*fnam = fnarr(1);*/
        (*fnam)();                      /*CALL fnam;*/
}