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
CALLNZ
macro - The standard set of rules for parsing C
- The standard set of rules for translating VAX MACRO to C
- A translation rule for the
CALLNZ
user 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*/