XTRAN Example — Translate HP (Compaq, Digital) MACRO-11 Assembler to C
This example uses the following XTRAN rules:
- The standard set of rules for parsing MACRO-11
- A rule for parsing invocations of the
CALLNZ
macro - The standard set of rules for parsing C
- The standard set of rules for translating MACRO-11 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
- The 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 = 12 ;SOME FLAGS WARRNE = 4 ;WORD ARRAY NO. OF ELEMENTS ; ENTRY: ;ENTRY POINT MOV #BWS,R4 ;PT TO BYTE WS CLR R5 ;INIT BYTE ARRAY SUBSCRIPT CLR R3 ;INIT WORD ARRAY SUBSCRIPT MOV #WARRNE,R2 ;LENGTH OF WORD ARRAY LOOP: MOV (R0),WWS ;REMEMBER LAST WORD VALUE ADD (R0)+,WARR(R3) ;UPDATE WORD ARRAY ELEMENT BLT DONE ;IF NEG, QUIT BEQ 10$ ;IF ZERO, DON'T CLEAR BYTE CLRB BARR(R5) ;CLEAR BYTE ARRAY ELEMENT BICB #XFLGS,(R4) ;CLEAR SOME FLAGS TOO 10$: ADD #2,R3 ;NEXT WORD ARRAY ELEMENT INC R5 ;NEXT BYTE ARRAY ELEMENT SOB R2,LOOP ;IF MORE TO DO CALLNZ @R1,SUBR,DONE ;CALL IF NONZERO BISB #XFLGS,(R4) ;ADD FLAGS TO BYTE WS MOV R1,@#A2 ;SET ENTRY ADDR CLR R0 ;INIT RETURN VALUE BIS #<^C^D<12&14>!<25!13.>>,R0 ;ADD SOME FLAGS DONE: RTS PC ;BACK TO CALLER WARR: .WORD 9.,8. ;WORD ARRAY OF VALUES .WORD 7 .WORD 6 BARR: .BYTE 1 ;BYTE ARRAY OF VALUES .BYTE 2,3 .BYTE 4 STR: .ASCII ?String with?<15><12>/embedded/<14> .ASCIZ +control characters+ BWS: .BYTE 22. ;BYTE WORKING STORAGE WWS: .WORD 0 ;WORD WORKING STORAGE .END
Output from XTRAN:
extern short a2; extern short *tmp0; extern short *tmp1; extern short tmp2; extern short tmp3; extern char *tmp4; extern short tmp5; extern unsigned short subr(); static short warr[4] = {9, 8, 7, 6}; /*word array of values*/ static char barr[4] = {1, 2, 3, 4}; /*byte array of values*/ static char str[41] = "String with\r\nembedded\fcontrol characters"; char bws = 22; /*byte working storage*/ short wws = 0; /*word working storage*/ #define XFLGS 012 /*some flags*/ #define WARRNE 4 /*word array no. of elements*/ entry: /*entry point*/ tmp4 = &bws; /*pt to byte ws*/ tmp5 = 0; /*init byte array subscript*/ tmp3 = 0; /*init word array subscript*/ tmp2 = WARRNE; /*length of word array*/ loop: wws = *tmp0; /*remember last word value*/ /*update word array element*/ if ((warr[tmp3 / 2] += *(tmp0++)) >= 0) /*(XTR: rvsed) if neg, quit*/ { if (warr[tmp3 / 2] != 0) /*(XTR: rvsed) if zero, don't clear byte*/ { barr[tmp5] = 0; /*clear byte array element*/ *tmp4 &= ~XFLGS; /*clear some flags too*/ } tmp3 += 2; /*next word array element*/ ++tmp5; /*next byte array element*/ if (--tmp2 != 0) /*if more to do*/ goto loop; if (!*tmp1) /*call if nonzero*/ { if (!subr()) goto done; } *tmp4 |= XFLGS; /*add flags to byte ws*/ a2 = tmp1; /*set entry addr*/ tmp0 = 0; /*init return value*/ tmp0 |= ~(12 & 14) | (025 | 13); /*add some flags*/ } done: return; /*back to caller*/