|
|
1.1 root 1: -IN80
2: -TITLE MINTOK: PHASE 1 TRANSLATION FROM MINIMAL TO TOKENS
3: -STITL INTRODUCTIONS
4: *
5: * This program takes MINIMAL statements and busts them up into
6: * individual pieces.
7: *
8: -STITL Initialization
9: *
10: * Keyword initialization
11: *
12: &ANCHOR = 1; &STLIMIT = -1; &TRIM = 1
13: *
14: * Useful constants
15: *
16: MINLETS = 'ABCDEFGHIJKLMNOPQRSTUVWXY$'
17: NOS = '0123456789'
18: TAB = SUBSTR( &ALPHABET,10,1 )
19: REGNAME = ('X' ANY('LSTR')) | ('W' ANY('ABC')) | 'IA' | 'RA' | 'CP'
20: *
21: * Zero the counts
22: *
23: LABCNT = NOUTLINES = NLINES = NSTMTS = NTARGET = NERRORS = 0
24: *
25: * Get file name
26: *
27: FILENAMI = INPUT
28: TERMINAL = 'Input MINIMAL file: ' FILENAMI
29: TERMINAL =
30: FILENAMO = INPUT
31: TERMINAL = 'Output TOKEN file: ' FILENAMO
32: TERMINAL =
33: FLCFLAG = REPLACE( INPUT,'y','Y' )
34: TERMINAL = 'Full line comments passed to TOKEN file? ' FLCFLAG
35: *
36: * No page ejects without full line comments
37: *
38: TERMINAL = DIFFER(FLCFLAG,'N')
39: EJCFLAG = REPLACE( (DIFFER(FLCFLAG,'N') INPUT, 'N'),'y','Y' )
40: TERMINAL = 'EJCs passed to TOKEN file? ' EJCFLAG
41: -STITL XFER FUNCTIONS
42: * CRACK parses STMT into a STMT data plex and returns it.
43: * It fails if there is a syntax error.
44: *
45: DEFINE('CRACK(LINE)LABEL,OPCODE,OPERANDS,COMMENT,OPERAND,CHAR')
46: *
47: * STMT is the common data plex used to hold the components of
48: * a statement (either Minimal or VAX) during processing.
49: *
50: DATA('STMT(LABEL,OPCODE,OP1,OP2,OP3,COMMENT)')
51: *
52: * MINLABEL is a pattern matching a valid Minimal Source Label.
53: *
54: MINLABEL = ANY(MINLETS) ANY(MINLETS) ANY(MINLETS NOS)
55: + ANY(MINLETS NOS) ANY(MINLETS NOS)
56: *
57: * CSPARSE parses out the components of the input line in STMT,
58: * and puts them into the locals: LABEL, OPCODE, OPERANDS, COMMENT
59: *
60: CSPARSE = (((MINLABEL . LABEL) | (' ' '' . LABEL)) ' '
61: + LEN(3) . OPCODE
62: + ((' ' (BREAK(' ') | RTAB(0)) . OPERANDS
63: + (SPAN(' ') | '') RTAB(0) . COMMENT) |
64: + (RPOS(0) . OPERANDS . COMMENT))) |
65: + ('.' '' . LABEL MINCOND . OPCODE
66: + ((TAB(7) '.' LEN(4) . OPERANDS) | (RPOS(0) . OPERANDS))
67: + '' . COMMENT)
68: *
69: * CSOPERAND breaks out the next operand in the OPERANDS string.
70: *
71: CSOPERAND = (BREAK(',') . OPERAND ',') | ((LEN(1) RTAB(0)) . OPERAND)
72: *
73: * CSDTC is a pattern that handles the special case of the Minimal DTC op
74: *
75: CSDTC = ((MINLABEL . LABEL) | (' ' '' . LABEL))
76: + LEN(7) (LEN(1) $ CHAR BREAK(*CHAR) LEN(1)) . OPERAND
77: + (SPAN(' ') | '') RTAB(0) . COMMENT
78: *
79: * equ.rip is a pattern that parses out the components of an EQU
80: * expression.
81: *
82: equ.rip = ( span(nos) . num1 | minlabel . sym1 )
83: + ( any('+-') . oprtr | '' )
84: + ( span(nos) . num2 | minlabel . sym2 | '' )
85: + rpos(0)
86: -EJECT
87: * DOSTMT is the driver routine that causes processing of the
88: * statement plex in THISSTMT.
89: *
90: DEFINE('DOSTMT()LABEL,OPCODE,OP1,OP2,OP3,COMMENT,T')
91: -SPACE 3
92: *
93: DEFINE('TINIT(STR)POS,CNT,INDEX,VAL,LASTVAL')
94: H_EQU.DEFS = TINIT(
95: + 'CFP$A[256]CFP$B[4]CFP$C[4]CFP$F[8]'
96: + 'CFP$I[1]CFP$M[^X7FFFFFFF]CFP$N[32]'
97: + 'NSTMX[10]CFP$R[1]CFP$S[6]CFP$X[2]'
98: + 'CFP$U[128]'
99: + 'E$SRS[50]E$STS[512]E$CBS[512]E$HNB[253]'
100: + 'E$HNW[3]E$FSP[20]'
101: + 'CH$LA[065]CH$LB[066]CH$LC[067]CH$LD[068]'
102: + 'CH$LE[069]CH$LF[070]CH$LG[071]CH$LH[072]'
103: + 'CH$LI[073]CH$LJ[074]CH$LK[075]CH$LL[076]'
104: + 'CH$LM[077]CH$LN[078]CH$LO[079]CH$LP[080]'
105: + 'CH$LQ[081]CH$LR[082]CH$LS[083]CH$LT[084]'
106: + 'CH$LU[085]CH$LV[086]CH$LW[087]CH$LX[088]'
107: + 'CH$LY[089]CH$L$[090]'
108: + 'CH$D0[048]CH$D1[049]CH$D2[050]CH$D3[051]'
109: + 'CH$D4[052]CH$D5[053]CH$D6[054]CH$D7[055]'
110: + 'CH$D8[056]CH$D9[057]'
111: + 'CH$$A[097]CH$$B[098]CH$$C[099]CH$$D[100]'
112: + 'CH$$E[101]CH$$F[102]CH$$G[103]CH$$H[104]'
113: + 'CH$$I[105]CH$$J[106]CH$$K[107]CH$$L[108]'
114: + 'CH$$M[109]CH$$N[110]CH$$O[111]CH$$P[112]'
115: + 'CH$$Q[113]CH$$R[114]CH$$S[115]CH$$T[116]'
116: + 'CH$$U[117]CH$$V[118]CH$$W[119]CH$$X[120]'
117: + 'CH$$Y[121]CH$$$[122]'
118: + 'CH$AM[038]CH$AS[042]CH$AT[064]CH$BB[060]'
119: + 'CH$BL[032]CH$BR[124]CH$CL[058]CH$CM[044]'
120: + 'CH$DL[036]CH$DT[046]CH$DQ[034]CH$EQ[061]'
121: + 'CH$EX[033]CH$MN[045]CH$NM[035]CH$NT[126]'
122: + 'CH$PC[037]CH$PL[043]CH$PP[040]CH$RB[062]'
123: + 'CH$RP[041]CH$QU[063]CH$SL[047]CH$SM[059]'
124: + 'CH$SQ[039]CH$UN[095]CH$OB[091]CH$CB[093]'
125: + 'CH$HT[009]CH$VT[012]IODEL[000]')
126: *
127: * EQUATES is used by H_EQU and XOP. It contains a directory of
128: * all labels that were defined by EQU instructions. This allows
129: * XOP to properly translate operands of the DLBL(X) category.
130: *
131: EQUATES = TABLE(257)
132: -space 3
133: * BSW is a flag that indicates whether or not a BSW...ESW range
134: * is being processed.
135: *
136: bsw = 0
137: -EJECT
138: * Error is used to report an error for THISSTMT
139: *
140: DEFINE('ERROR(TEXT)')
141: -SPACE 3
142: * OUTSTMT is used to send a target statement to the target code
143: * output file (OUTFILE <=> LU2)
144: *
145: DEFINE('OUTSTMT(LABEL,OPCODE,OP1,OP2,OP3,COMMENT)T,STMTOUT')
146: *
147: * Associate output file
148: *
149: OUTPUT(.OUTFILE,2,(IDENT(FILENAMO) '', FILENAMO))
150: * READLINE is called to return the next non-comment line from
151: * the Minimal input file (INFILE <=> LU1). Note that it will
152: * not fail on EOF, but it will return a Minimal END statement
153: *
154: DEFINE('READLINE()')
155: *
156: * Associate input file to LU1
157: *
158: INPUT(.INFILE,1,(IDENT(FILENAMI) '', FILENAMI))
159: -EJECT
160: * XOP is called to translate a Minimal Operand to a VAX Macro Operand.
161: *
162: DEFINE('XOP(XOP)VAL,PREFIX')
163: *
164: * XOP.REGS is a pattern to match out register names for translation.
165: *
166: XOP.REGS = (*REGNAME . VAL RPOS(0) . PREFIX) |
167: + (BREAK('(') LEN(1)) . PREFIX LEN(2) . VAL
168: *
169: * XOP.XREGS is a table with register translations
170: *
171: XOP.XREGS = TINIT('IA[R5]RA[R2]CP[R3]WA[R6]WB[R7]WC[R8]XR[R9]'
172: + 'XL[R10]XT[R10]XS[SP]')
173: *
174: * XPINTX is a pattern that will match the INT(X) type operand
175: *
176: XPINTX = SPAN(NOS) . VAL '('
177: *
178: * XPDLBLX is a pattern that will match the DLBL(X) type operand
179: *
180: XPDLBLX = MINLABEL . VAL '('
181: -STITL MAIN PROGRAM
182: * Here follows the driver code for the "main" program.
183: -SPACE 3
184: *
185: * Loop until program exits via H_END
186: *
187: MN03 DOSTMT() :(MN03)
188: -STITL CRACK(LINE)
189: * CRACK is called to create a STMT plex containing the various
190: * entrails of the Minimal Source statement in LINE. For
191: * conditional assembly ops, the opcode is the op, and OP1
192: * is the symbol. Note that DTC is handled as a special case to
193: * assure that the decomposition is correct.
194: *
195: * CRACK will print an error and fail if a syntax error occurs.
196: *
197: CRACK NSTMTS = NSTMTS + 1
198: LINE CSPARSE :F(CS03)
199: CRACK = STMT(LABEL,OPCODE,,,,COMMENT)
200: IDENT(OPCODE,'DTC') :S(CS02)
201: *
202: * Now pick out operands until none left
203: *
204: OPERANDS CSOPERAND = :F(CS01)
205: OP1(CRACK) = XOP(OPERAND)
206: OPERANDS CSOPERAND = :F(CS01)
207: OP2(CRACK) = XOP(OPERAND)
208: OPERANDS CSOPERAND :F(CS01)
209: OP3(CRACK) = XOP(OPERAND)
210: *
211: * Operands all parsed out. That's all folks.
212: *
213: CS01 :(RETURN)
214: *
215: * DTC - Special case
216: *
217: CS02 LINE CSDTC :F(CS03)
218: OP1(CRACK) = OPERAND
219: COMMENT(CRACK) = COMMENT :(CS01)
220: *
221: * Here on syntax error
222: *
223: CS03 ERROR('SOURCE LINE SYNTAX ERROR') :(FRETURN)
224: -STITL DOSTMT()
225: * DOSTMT is invoked to initiate processing of the next line from
226: * READLINE. For efficient access
227: * DOSTMT puts name values corresponding to the components in
228: * variables with the same names (LABEL, OPCODE, OP1,OP2,OP3 and
229: * COMMENT) which allows the various handlers to $var to store/fetch
230: * the values of the statment.
231: *
232: * After doing this, DOSTMT branches to the handler routine indicated
233: * for this opcode in the HANDLER table (there must be an entry or
234: * an error results). The handlers all have entry points beginning
235: * with "H_", and can be considered a logical extension of the
236: * DOSTMT routine. The handlers have the choice of branching back
237: * to DSGEN to cause the THISSTMT plex to be sent to OUTSTMT, or
238: * of RETURNing themselves, in which case the handler must output
239: * all needed code itself.
240: *
241: * The handlers are listed in a separate section below.
242: *
243: DOSTMT THISLINE = READLINE()
244: THISSTMT = CRACK(THISLINE) :F(DOSTMT)
245: LABEL = .LABEL(THISSTMT)
246: OPCODE = .OPCODE(THISSTMT)
247: OP1 = .OP1(THISSTMT)
248: OP2 = .OP2(THISSTMT)
249: OP3 = .OP3(THISSTMT)
250: COMMENT = .COMMENT(THISSTMT)
251: *
252: * ONLY NEED TO PROCESS 5 INSTRUCTIONS:
253: *
254: * BSW,END,EQU,ESW,IFF
255: *
256: LEQ( $OPCODE,'EQU' ) :s(h_equ)
257: leq( $opcode,'IFF' ) :s(h_iff)
258: leq( $opcode,'BSW' ) :s(h_bsw)
259: leq( $opcode,'ESW' ) :s(h_esw)
260: leq( $opcode,'END' ) :s(h_end)
261: *
262: * GENERATE TOKENS.
263: *
264: DSGEN OUTSTMT($LABEL,$OPCODE,$OP1,$OP2,$OP3,$COMMENT) :(RETURN)
265: -STITL ERROR(TEXT)
266: * This module handles reporting of errors with the offending
267: * statement text in THISLINE. Comments explaining
268: * the error are written to the listing (including error chain), and
269: * the appropriate counts are updated.
270: *
271: ERROR OUTFILE = '* *???* ' THISLINE
272: OUTFILE = '* ' TEXT
273: + (IDENT(LASTERROR),'. LAST ERROR WAS LINE ' LASTERROR)
274: LASTERROR = NOUTLINES
275: NOUTLINES = NOUTLINES + 2
276: NERRORS = NERRORS + 1
277: + :(RETURN)
278: -STITL OUTSTMT(LABEL,OPCODE,OP1,OP2,OP3,COMMENT)
279: * This module writes the components of the VAX MACRO statement
280: * passed in the argument list to the formatted .MAR file
281: *
282: OUTSTMT
283: *
284: * Send text to OUTFILE
285: *
286: OUTFILE = '{' LABEL '{' OPCODE '{' OP1 '{' OP2 '{' OP3 '{' COMMENT
287: NTARGET = NTARGET + 1
288: NOUTLINES = NOUTLINES + 1
289: + :(RETURN)
290: -STITL READLINE()
291: * This routine returns the next statement line in the input file
292: * to the caller. It never fails. If there is no more input,
293: * then a Minimal END statement is returned.
294: * Comments are passed through to the output file directly.
295: *
296: *
297: READLINE READLINE = INFILE :F(RL02)
298: NLINES = NLINES + 1
299: ident( readline ) :s(readline)
300: LEQ( SUBSTR( READLINE,1,1 ),'*' ) :F(RL01)
301: *
302: * Only print comment if requested.
303: *
304: OUTFILE = IDENT(FLCFLAG,'Y') READLINE :F(READLINE)
305: NOUTLINES = NOUTLINES + 1 :(READLINE)
306: *
307: * Here if not a comment line
308: *
309: RL01 :(RETURN)
310: *
311: * Here on EOF
312: *
313: RL02 READLINE = ' END'
314: :(RL01)
315: -STITL TINIT(STR)
316: * This routine is called to initialize a table from a string of
317: * index/value pairs.
318: *
319: TINIT POS = 0
320: *
321: * Count the number of "[" symbols to get an assessment of the table
322: * size we need.
323: *
324: TIN01 STR (TAB(*POS) '[' BREAK(']') *?(CNT = CNT + 1) @POS)
325: + :S(TIN01)
326: *
327: * Allocate the table, and then fill it. Note that a small memory
328: * optimisation is attempted here by trying to re-use the previous
329: * value string if it is the same as the present one.
330: *
331: TINIT = TABLE(CNT)
332: TIN02 STR (BREAK('[') $ INDEX LEN(1) BREAK(']') $ VAL LEN(1)) =
333: + :F(RETURN)
334: VAL = CONVERT( VAL,'INTEGER' )
335: VAL = IDENT(VAL,LASTVAL) LASTVAL
336: LASTVAL = VAL
337: TINIT[INDEX] = VAL :(TIN02)
338: -STITL XOP(OPERAND)
339: * XOP is called to Translate a Minimal Source Operand into
340: * a semantically equivalent VAX/Macro Operand. Most of the
341: * Minimal Operands are basically OK, the following transformations
342: * must be applied:
343: *
344: * - All operands beginning with "=" have the "=" changed
345: * to a VAX immediate mode beginning with "#"
346: * - Byte immediate "*..." is changed to "#4*..."
347: * - INT(X) is changed to "4*INT(X)"
348: * - DLBL(X) is changed to "4*DLBL(X)"
349: * - CLBL(X) and WLBL(X) are changed to L^XLBL(X)
350: *
351: *
352: * Check for immediate mode
353: *
354: XOP XOP '=' = '#' :S(XP01)
355: *
356: * Else check for byte immediate
357: *
358: XOP ('*' LEN(1) . VAL) = '#4*' VAL :S(XP01)
359: *
360: * Else check for INT(X)
361: *
362: XOP XPINTX = (IDENT(VAL,'0'), '4*' VAL) '(' :S(XP01)
363: *
364: * Else check for DLBL(X), CLBL(X) or WLBL(X)
365: *
366: XOP XPDLBLX = (DIFFER(EQUATES[VAL]) '4*', 'L^') VAL '('
367: *
368: * Merge here with XOP containing syntax fixes. Now map registers
369: *
370: XP01 XOP XOP.REGS = PREFIX XOP.XREGS[VAL] :(RETURN)
371: -stitl Handle instructions
372: *
373: * BSW processing begins by building an array that can hold all
374: * IFF operands and comments.
375: *
376: h_bsw ub = ( integer( $op2 ) $op2, equates[$op2] )
377: iffar = integer( ub )
378: + array( '0:' ub - 1,'{{' ) :f(error)
379: dplbl = $op3
380: bsw = 1 :(dsgen)
381: -space 3
382: *
383: * IFF processing sets the iffar[] element to the current
384: * value, plbl, and comment.
385: *
386: h_iff eq( bsw ) :s(error)
387: iffval = ( integer( $op1 ) $op1, equates[$op1] )
388: iffar[iffval] = integer( iffval )
389: + $op1 '{' $op2 '{' $comment :f(error)s(return)
390: *
391: * In order to support translation of MINIMAL operands and
392: * BSW/IFF/ESW preprocessing, all EQU expressions must be
393: * evaluated and kept in a symbol table.
394: *
395: h_equ equates[$label] = ident($op1,'*')
396: + h_equ.defs[$label] :s(dsgen)
397: *
398: num1 = num2 = sym1 = sym2 = oprtr =
399: $op1 equ.rip :f(error)
400: num1 = differ(sym1) equates[sym1]
401: num2 = differ(sym2) equates[sym2]
402: val = eval( num1 ' ' oprtr ' ' num2 ) :f(error)
403: equates[$label] = val :(dsgen)
404: -space 3
405: *
406: * ESW processing generates an IFF for every value in the
407: * BSW range.
408: *
409: h_esw eq( bsw) :s(error)
410: iffindx = 0
411: h_esw1 iffar[iffindx] break('{') $ val len(1)
412: + break( '{' ) $ plbl len(1)
413: + rem $ cmnt
414: + :f(h_esw2)
415: val = ident( val ) 'DUMMY'
416: plbl = ident( plbl ) dplbl
417: outstmt(,'IFF',val,plbl,,cmnt)
418: iffindx = iffindx + 1 :(h_esw1)
419: h_esw2 iffar = :(dsgen)
420: -SPACE 3
421: * END prints statistics on terminal then exits program
422: *
423: H_END OUTSTMT(,'END',,,,$COMMENT)
424: TERMINAL = '*** TRANSLATION COMPLETE ***'
425: TERMINAL = NLINES ' LINES READ.'
426: TERMINAL = NSTMTS ' STATEMENTS PROCESSED.'
427: TERMINAL = NTARGET ' TARGET CODE LINES PRODUCED.'
428: TERMINAL = NERRORS ' ERRORS OCCURRED.'
429: TERMINAL = DIFFER(LASTERROR) 'THE LAST ERROR WAS IN LINE ' LASTERROR
430: &CODE = NE(NERRORS) 2001
431: terminal = collect() ' free words'
432: :(END)
433: *
434: END
435: spitv35.ppmin
436: spitv35.tok
437: y
438: y
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.