XTRAN Example — Translate HP (Digital, Compaq) VAX MACRO to C
This example uses the following XTRAN rules:
- The standard set of rules for parsing VAX MACRO
- A rule for parsing invocations of the
CALLNZmacro - The standard set of rules for parsing C
- The standard set of rules for translating VAX MACRO to C
- A translation rule for the
CALLNZuser macro that specifies the C code to which it should translate - A standard set of rules for structuring C code
- The standard set of rules for rendering C
- A standard set of rules for styling rendered C code
NOTE that otherwise the translation shown below was done with default conditions. XTRAN provides many options for controlling the way it translates.
Process Flowchart
Here is a flowchart for this process, in which the elements are color coded:
- BLUE for XTRAN versions (runnable programs)
- ORANGE for XTRAN rules (text files)
- RED for
code
Input to XTRAN:
XFLGS = ^X0C ;SOME FLAGS
UPDT = 5 ;UPDATE AMOUNT
SHIFT = 2 ;RIGHT SHIFT TO DO
;
ENTRY: ;ENTRY POINT
MOVAL LWS,R5 ;POINT TO WS
LOOP: MOVL R1,PXADDR[R2] ;SAVE ADDR
BEQL DONE ;IF ZERO, QUIT
MOVL (R5),(R1)+
MOVW R3,(R1)+ ;STORE VALUE..
;..AND BUMP POINTER
BEQL NOINC ;IF NO VALUE
CALLNZ (R1),SUBR,DONE ;CALL IF NONZERO
INCL (R1) ;BUMP VALUE..
INCL A2 ;..AND ENTRY ADDR
NOINC:
BISW2 #XFLGS,WWS ;ADD FLAGS
MOVZWL WWS,LWS ;SHOW OFF OPERAND TYPES
TSTW (R4)[R2] ;END OF UPDATE VALS?
BEQL LOOP ;IF SO, START OVER
MOVL (R1),A2 ;SET ENTRY ADDR
BISL2 #<^C^D<14&24>!- ;ADD SOME FLAGS..
<^XAA@3>!<^XBB@-SHIFT>!- ;..INCLUDING SOME SHIFTS..
<^O25!^XA3>>,R0 ;..TO RETURN VALUE
DONE: RSB ;BACK TO CALLER
;
BARR: .BYTE 1 ;BYTE ARRAY OF VALUES
.BYTE 2,3
.BYTE 4
LARR: ;LONGWORD ARRAY OF VALUES
.LONG 50,600,7000,80000
STR: .ASCII ?String with?<13><10>/embedded/<12>
.ASCIZ +control characters+
WWS: .WORD 0 ;WORD WORKING STORAGE
LWS: .LONG 32768 ;LONGWORD WORKING STORAGE
.END
Output from XTRAN:
extern long a2;
extern long pxaddr[];
extern unsigned short subr();
extern long tmp5;
extern long *tmp1;
extern short tmp2;
extern short *tmp4;
extern unsigned long tmp0;
static char barr[4] =
{ 1, 2, 3, 4 }; /*byte array of values*/
static long larr[4] =
{ 50, 600, 7000, 80000
}; /*longword array of values*/
static char str[41] =
"String with\r\nembedded\fcontrol characters";
short wws = 0; /*word working storage*/
long lws = 32768; /*longword working storage*/
#define XFLGS 0x0c /*some flags*/
#define UPDT 5 /*update amount*/
#define SHIFT 2 /*right shift to do*/
entry: /*entry point*/
tmp5 = &lws; /*point to ws*/
loop:
/*save addr*/
if ((pxaddr[tmp2] = tmp1) != 0) /*(XTR: reversed) if zero, quit*/
{
*(tmp1++) = *tmp5;
/*store value..*/
/*..and bump pointer*/
if ((*(tmp1++) = tmp3) != 0) /*(XTR: reversed) if no value*/
{
if (*tmp1 != 0) /*call if nonzero*/
{
if (!subr())
goto done;
}
++(*tmp1); /*bump value..*/
++a2; /*..and entry addr*/
}
wws |= XFLGS; /*add flags*/
lws = wws; /*show off operand types*/
/*end of update vals?*/
if ((*tmp4)[tmp2] == 0) /*if so, start over*/
goto loop;
a2 = *tmp1; /*set entry addr*/
tmp0 |= ~(14 & 24) | 0xaa << 3 |
0xbb >> SHIFT | (025 | 0xa3); /*add some flags..*/
/*..including some shifts..*/
/*..to return value*/
}
done:
return (tmp0); /*back to caller*/