|
|
1.1 root 1: /* Copyright (c) 1980 Regents of the University of California */
2: static char sccsid[] = "@(#)asexpr.c 4.2 8/15/80";
3: #include <stdio.h>
4: #include "as.h"
5: #include "asexpr.h"
6:
7: /*
8: * Tables for combination of operands.
9: */
10: #define XTXRN 5<<1 /* indexes last row/column when right shifted */
11:
12: /*
13: * table for +
14: */
15: readonly char pltab[6][6] = {
16: /* UND ABS TXT DAT BSS EXT */
17:
18: /*UND*/ XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF,
19: /*ABS*/ XUNDEF, XABS, XTEXT, XDATA, XBSS, XXTRN,
20: /*TXT*/ XUNDEF, XTEXT, ERR, ERR, ERR, ERR,
21: /*DAT*/ XUNDEF, XDATA, ERR, ERR, ERR, ERR,
22: /*BSS*/ XUNDEF, XBSS, ERR, ERR, ERR, ERR,
23: /*EXT*/ XUNDEF, XXTRN, ERR, ERR, ERR, ERR,
24: };
25:
26: /*
27: * table for -
28: */
29: readonly char mintab[6][6] = {
30: /* UND ABS TXT DAT BSS EXT */
31:
32: /*UND*/ XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF,
33: /*ABS*/ XUNDEF, XABS, ERR, ERR, ERR, ERR,
34: /*TXT*/ XUNDEF, XTEXT, XABS, ERR, ERR, ERR,
35: /*DAT*/ XUNDEF, XDATA, ERR, XABS, ERR, ERR,
36: /*BSS*/ XUNDEF, XBSS, ERR, ERR, XABS, ERR,
37: /*EXT*/ XUNDEF, XXTRN, ERR, ERR, ERR, ERR,
38: };
39:
40: /*
41: * table for other operators
42: */
43: readonly char othtab[6][6] = {
44: /* UND ABS TXT DAT BSS EXT */
45:
46: /*UND*/ XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF,
47: /*ABS*/ XUNDEF, XABS, ERR, ERR, ERR, ERR,
48: /*TXT*/ XUNDEF, ERR, ERR, ERR, ERR, ERR,
49: /*DAT*/ XUNDEF, ERR, ERR, ERR, ERR, ERR,
50: /*BSS*/ XUNDEF, ERR, ERR, ERR, ERR, ERR,
51: /*EXT*/ XUNDEF, ERR, ERR, ERR, ERR, ERR,
52: };
53:
54: struct exp *
55: combine(op, exp1, exp2)
56: register struct exp *exp1, *exp2;
57: {
58: register e1_type, e2_type;
59: register back_type;
60:
61: lastnam=0; /* kludge for jxxx instructions */
62:
63: e1_type = exp1->e_xtype&XTYPE;
64: e2_type = exp2->e_xtype&XTYPE;
65:
66: if (exp1->e_xtype==XXTRN+XUNDEF)
67: e1_type = XTXRN;
68: if (exp2->e_xtype==XXTRN+XUNDEF)
69: e2_type = XTXRN;
70: if (passno==1)
71: if (exp1->e_xloc!=exp2->e_xloc && e1_type==e2_type)
72: e1_type = e2_type = XTXRN; /* error on != loc ctrs */
73: e1_type >>= 1; /*dispose of the external (XXTRN) bit*/
74: e2_type >>= 1;
75:
76: switch (op) {
77: case PLUS:
78: exp1->e_xvalue += exp2->e_xvalue;
79: back_type = pltab[e1_type][e2_type];
80: break;
81: case MINUS:
82: exp1->e_xvalue -= exp2->e_xvalue;
83: back_type = mintab[e1_type][e2_type];
84: break;
85: case IOR:
86: exp1->e_xvalue |= exp2->e_xvalue;
87: goto comm;
88: case XOR:
89: exp1->e_xvalue ^= exp2->e_xvalue;
90: goto comm;
91: case AND:
92: exp1->e_xvalue &= exp2->e_xvalue;
93: goto comm;
94: case ORNOT:
95: exp1->e_xvalue |= ~exp2->e_xvalue;
96: goto comm;
97: case LSH:
98: exp1->e_xvalue <<= exp2->e_xvalue;
99: goto comm;
100: case RSH:
101: exp1->e_xvalue >>= exp2->e_xvalue;
102: goto comm;
103: case TILDE:
104: exp1->e_xvalue |= ~ exp2->e_xvalue;
105: goto comm;
106: case MUL:
107: exp1->e_xvalue *= exp2->e_xvalue;
108: goto comm;
109: case DIV:
110: if (exp2->e_xvalue == 0)
111: yyerror("Divide check");
112: else
113: exp1->e_xvalue /= exp2->e_xvalue;
114: goto comm;
115: case REGOP:
116: if (exp2->e_xvalue == 0)
117: yyerror("Divide check (modulo)");
118: else
119: exp1->e_xvalue %= exp2->e_xvalue;
120: goto comm;
121:
122: comm:
123: back_type = othtab[e1_type][e2_type];
124: break;
125: default:
126: yyerror("Internal error: unknown operator");
127: }
128:
129: if (e2_type==(XTXRN>>1))
130: exp1->e_xname = exp2->e_xname;
131: exp1->e_xtype = back_type | (
132: (exp1->e_xtype|exp2->e_xtype) & (XFORW|XXTRN) );
133: if (back_type==ERR)
134: yyerror("Relocation error");
135: return(exp1);
136: }
137:
138: buildtokensets()
139: {
140: #define clobber(val, set) tokensets[(val)] |= (set)
141:
142: clobber(SEMI, LINSTBEGIN);
143: clobber(NL, LINSTBEGIN);
144: clobber(INT, LINSTBEGIN);
145:
146: clobber(NAME, YUKKYEXPRBEG + LINSTBEGIN);
147: clobber(INSTn, YUKKYEXPRBEG);
148: clobber(INST0, YUKKYEXPRBEG);
149: clobber(REG, YUKKYEXPRBEG);
150: clobber(BFINT, YUKKYEXPRBEG);
151:
152: clobber(INT, SAFEEXPRBEG);
153: clobber(FLTNUM, SAFEEXPRBEG);
154:
155: clobber(PLUS, ADDOPS);
156: clobber(MINUS, ADDOPS + EBEGOPS);
157:
158: clobber(LP, EBEGOPS);
159:
160: clobber(IOR, BOOLOPS);
161: clobber(XOR, BOOLOPS);
162: clobber(AND, BOOLOPS);
163: clobber(ORNOT, BOOLOPS);
164:
165: clobber(TILDE, MULOPS + EBEGOPS);
166: clobber(LSH, MULOPS);
167: clobber(RSH, MULOPS);
168: clobber(MUL, MULOPS);
169: clobber(DIV, MULOPS);
170: clobber(REGOP, MULOPS); /* % */
171:
172: }
173:
174: /*
175: * We keep the current token class in this global variable, so
176: * the recursive descent expression analyzers can talk amongst
177: * themselves, and so that we may use the macros shift and shift over
178: */
179:
180: extern int yylval; /*the value of the lexical value*/
181: extern struct exp *xp; /*the next free expression slot*/
182:
183: static int val;
184: int exprparse(inval, backexpr) /*return the value the read head is sitting on*/
185: int inval;
186: struct exp **backexpr;
187: {
188: register struct exp *lexpr;
189: int op;
190:
191: val = inval;
192: lexpr = boolterm();
193: while (INTOKSET(val, ADDOPS)){
194: op = val;
195: shift;
196: lexpr = combine(op, lexpr, boolterm());
197: }
198: *backexpr = lexpr;
199: return(val);
200: }
201:
202: struct exp *boolterm()
203: {
204: register struct exp *lexpr;
205: int op;
206:
207: lexpr = term();
208: while(INTOKSET(val, BOOLOPS)){
209: op = val;
210: shift;
211: lexpr = combine(op, lexpr, term());
212: }
213: return(lexpr);
214: }
215:
216: struct exp *term()
217: {
218: register struct exp *lexpr;
219: int op;
220:
221: lexpr = factor();
222: while(INTOKSET(val, MULOPS)){
223: op = val;
224: shift;
225: lexpr = combine(op, lexpr, factor());
226: }
227: return(lexpr);
228: }
229:
230: struct exp *factor()
231: {
232: struct exp *lexpr;
233: int op;
234: extern int droppedLP; /*called exprparse after consuming an LP*/
235:
236: if (val == LP || droppedLP){
237: if (droppedLP)
238: droppedLP = 0;
239: else
240: shift; /*the LP*/
241: val = exprparse(val, &lexpr);
242: if (val != RP)
243: yyerror("right parenthesis expected");
244: else
245: shift;
246: } else
247: if (INTOKSET(val, YUKKYEXPRBEG)){
248: lexpr = yukkyexpr(val, yylval);
249: shift;
250: }
251: else if (INTOKSET(val, SAFEEXPRBEG)){
252: lexpr = (struct exp *)yylval;
253: shift;
254: }
255: else if ( (val == TILDE) || (val == MINUS) ){
256: op = val;
257: shift;
258: lexpr = xp++;
259: lexpr->e_xtype = XABS;
260: lexpr->e_xvalue = 0;
261: lexpr = combine(op, lexpr, factor());
262: }
263: else {
264: yyerror("Bad expression syntax");
265: lexpr = xp++;
266: lexpr->e_xtype = XABS;
267: lexpr->e_xvalue = 0;
268: }
269: return(lexpr);
270: }
271:
272: struct exp *yukkyexpr(val, np)
273: int val;
274: register np;
275: {
276: register struct exp *locxp;
277: extern int exprisname; /*last factor is a name*/
278:
279: exprisname = 0;
280: locxp = xp++;
281: if (val == NAME || val == BFINT){
282: if (val == BFINT) {
283: int off = 0;
284: yylval = ((struct exp *)np)->e_xvalue;
285: if (yylval < 0) {
286: yylval = -yylval;
287: yylval--;
288: off = -1;
289: if (lgensym[yylval] == 1)
290: yyerror("Reference to undefined local label %db", yylval);
291: } else {
292: yylval--;
293: genref[yylval] = 1;
294: }
295: sprintf(yytext, "L%d\001%d", yylval, lgensym[yylval] + off);
296: yylval = np = (int)*lookup(passno == 1);
297: lastnam = (struct symtab *)np;
298: }
299: exprisname++;
300: locxp->e_xtype = ((struct symtab *)np)->s_type;
301: if (( ((struct symtab *)np)->s_type&XTYPE)==XUNDEF) { /*forward*/
302: locxp->e_xname = (struct symtab *)np;
303: locxp->e_xvalue = 0;
304: if (passno==1)
305: ((struct symtab *)np)->s_type |= XFORW;
306: } else { /*otherwise, just get the value*/
307: locxp->e_xvalue = ((struct symtab *)np)->s_value;
308: locxp->e_xname = NULL;
309: }
310: } else { /*INSTn or INST0 or REG*/
311: locxp->e_xtype = XABS;
312: locxp->e_xvalue = ( (int)np) & 0xFF;
313: locxp->e_xloc = 0;
314: locxp->e_xname = NULL;
315: }
316:
317: return(locxp);
318: }
319:
320:
321: #ifdef DEBUG
322: char *tok_name[LASTTOKEN - FIRSTTOKEN + 1];
323: struct Tok_Desc{
324: int tok_which;
325: char *tok_name;
326: } tok_desc[] = {
327: FIRSTTOKEN, "firsttoken", /* 0 */
328: ISPACE, "ispace", /* 1 */
329: IBYTE, "ibyte", /* 2 */
330: IWORD, "iword", /* 3 */
331: IINT, "iint", /* 4 */
332: ILONG, "ilong", /* 5 */
333: IDATA, "idata", /* 6 */
334: IGLOBAL, "iglobal", /* 7 */
335: ISET, "iset", /* 8 */
336: ITEXT, "itext", /* 9 */
337: ICOMM, "icomm", /* 10 */
338: ILCOMM, "ilcomm", /* 11 */
339: IFLOAT, "ifloat", /* 12 */
340: IDOUBLE, "idouble", /* 13 */
341: IORG, "iorg", /* 14 */
342: IASCII, "iascii", /* 15 */
343: IASCIZ, "iasciz", /* 16 */
344: ILSYM, "ilsym", /* 17 */
345: IFILE, "ifile", /* 18 */
346: ILINENO, "ilineno", /* 19 */
347: IABORT, "iabort", /* 20 */
348: ISTAB, "istab", /* 23 */
349: ISTABSTR, "istabstr", /* 24 */
350: ISTABNONE, "istabnone", /* 25 */
351: ISTABDOT, "istabdot", /* 26 */
352: IJXXX, "ijxxx", /* 27 */
353: IALIGN, "ialign", /* 28 */
354: INST0, "inst0", /* 29 */
355: INSTn, "instn", /* 30 */
356: BFINT, "bfint", /* 31 */
357: PARSEEOF, "parseeof", /* 32 */
358: ILINESKIP, "ilineskip", /* 33 */
359: VOID, "void", /* 34 */
360: SKIP, "skip", /* 35 */
361: INT, "int", /* 36 */
362: FLTNUM, "fltnum", /* 37 */
363: NAME, "name", /* 38 */
364: STRING, "string", /* 39 */
365: QUAD, "quad", /* 40 */
366: SIZESPEC, "sizespec", /* 41 */
367: REG, "reg", /* 42 */
368: MUL, "mul", /* 43 */
369: LITOP, "litop", /* 44 */
370: LP, "lp", /* 45 */
371: MP, "mp", /* 46 */
372: NEEDSBUF, "needsbuf", /* 48 */
373: REGOP, "regop", /* 49 */
374: NL, "nl", /* 50 */
375: SCANEOF, "scaneof", /* 51 */
376: BADCHAR, "badchar", /* 52 */
377: SP, "sp", /* 53 */
378: ALPH, "alph", /* 54 */
379: DIG, "dig", /* 55 */
380: SQ, "sq", /* 56 */
381: DQ, "dq", /* 57 */
382: SH, "sh", /* 58 */
383: LSH, "lsh", /* 59 */
384: RSH, "rsh", /* 60 */
385: MINUS, "minus", /* 61 */
386: SIZEQUOTE, "sizequote", /* 62 */
387: XOR, "xor", /* 64 */
388: DIV, "div", /* 65 */
389: SEMI, "semi", /* 66 */
390: COLON, "colon", /* 67 */
391: PLUS, "plus", /* 68 */
392: IOR, "ior", /* 69 */
393: AND, "and", /* 70 */
394: TILDE, "tilde", /* 71 */
395: ORNOT, "ornot", /* 72 */
396: CM, "cm", /* 73 */
397: LB, "lb", /* 74 */
398: RB, "rb", /* 75 */
399: RP, "rp", /* 76 */
400: LASTTOKEN, "lasttoken" /* 80 */
401: };
402: /*
403: * turn a token type into a string
404: */
405: static int fixed = 0;
406: char *tok_to_name(token)
407: {
408: if (!fixed){
409: int i;
410: for (i = FIRSTTOKEN; i <= LASTTOKEN; i++)
411: tok_name[i] = "NOT ASSIGNED";
412: for (i = FIRSTTOKEN; i <= sizeof(tok_desc)/sizeof(struct Tok_Desc); i++){
413: tok_name[tok_desc[i].tok_which] = tok_desc[i].tok_name;
414: }
415: fixed = 1;
416: }
417: if (FIRSTTOKEN <= token && token <= LASTTOKEN)
418: return(tok_name[token]);
419: else
420: panic("Unknown token number, %d\n", token);
421: /*NOTREACHED*/
422: }
423: #endif DEBUG
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.