|
|
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 > 0 ? exp1->e_xvalue >> exp2->e_xvalue : 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: extern struct symtab *exprxname; /*another stab in the back*/
279:
280: exprisname = 0;
281: locxp = xp++;
282: if (val == NAME || val == BFINT){
283: if (val == BFINT) {
284: int off = 0;
285: yylval = ((struct exp *)np)->e_xvalue;
286: if (yylval < 0) {
287: yylval = -yylval;
288: yylval--;
289: off = -1;
290: if (lgensym[yylval] == 1)
291: yyerror("Reference to undefined local label %db", yylval);
292: } else {
293: yylval--;
294: genref[yylval] = 1;
295: }
296: sprintf(yytext, "L%d\001%d", yylval, lgensym[yylval] + off);
297: yylval = np = (int)*lookup(passno == 1);
298: lastnam = (struct symtab *)np;
299: }
300: exprisname++;
301: locxp->e_xtype = ((struct symtab *)np)->s_type;
302: if (( ((struct symtab *)np)->s_type&XTYPE)==XUNDEF) { /*forward*/
303: locxp->e_xname = (struct symtab *)np;
304: locxp->e_xvalue = 0;
305: if (passno==1)
306: ((struct symtab *)np)->s_type |= XFORW;
307: } else { /*otherwise, just get the value*/
308: exprxname = (struct symtab *)np;
309: locxp->e_xvalue = ((struct symtab *)np)->s_value;
310: locxp->e_xname = NULL;
311: }
312: } else { /*INSTn or INST0 or REG*/
313: locxp->e_xtype = XABS;
314: locxp->e_xvalue = ( (int)np) & 0xFF;
315: locxp->e_xloc = 0;
316: locxp->e_xname = NULL;
317: }
318:
319: return(locxp);
320: }
321:
322:
323: #ifdef DEBUG
324: char *tok_name[LASTTOKEN - FIRSTTOKEN + 1];
325: struct Tok_Desc{
326: int tok_which;
327: char *tok_name;
328: } tok_desc[] = {
329: FIRSTTOKEN, "firsttoken", /* 0 */
330: ISPACE, "ispace", /* 1 */
331: IBYTE, "ibyte", /* 2 */
332: IWORD, "iword", /* 3 */
333: IINT, "iint", /* 4 */
334: ILONG, "ilong", /* 5 */
335: IDATA, "idata", /* 6 */
336: IGLOBAL, "iglobal", /* 7 */
337: ISET, "iset", /* 8 */
338: ITEXT, "itext", /* 9 */
339: ICOMM, "icomm", /* 10 */
340: ILCOMM, "ilcomm", /* 11 */
341: IFLOAT, "ifloat", /* 12 */
342: IDOUBLE, "idouble", /* 13 */
343: IORG, "iorg", /* 14 */
344: IASCII, "iascii", /* 15 */
345: IASCIZ, "iasciz", /* 16 */
346: ILSYM, "ilsym", /* 17 */
347: IFILE, "ifile", /* 18 */
348: ILINENO, "ilineno", /* 19 */
349: IABORT, "iabort", /* 20 */
350: ISTAB, "istab", /* 23 */
351: ISTABSTR, "istabstr", /* 24 */
352: ISTABNONE, "istabnone", /* 25 */
353: ISTABDOT, "istabdot", /* 26 */
354: IJXXX, "ijxxx", /* 27 */
355: IALIGN, "ialign", /* 28 */
356: INST0, "inst0", /* 29 */
357: INSTn, "instn", /* 30 */
358: BFINT, "bfint", /* 31 */
359: PARSEEOF, "parseeof", /* 32 */
360: ILINESKIP, "ilineskip", /* 33 */
361: VOID, "void", /* 34 */
362: SKIP, "skip", /* 35 */
363: INT, "int", /* 36 */
364: FLTNUM, "fltnum", /* 37 */
365: NAME, "name", /* 38 */
366: STRING, "string", /* 39 */
367: QUAD, "quad", /* 40 */
368: SIZESPEC, "sizespec", /* 41 */
369: REG, "reg", /* 42 */
370: MUL, "mul", /* 43 */
371: LITOP, "litop", /* 44 */
372: LP, "lp", /* 45 */
373: MP, "mp", /* 46 */
374: NEEDSBUF, "needsbuf", /* 48 */
375: REGOP, "regop", /* 49 */
376: NL, "nl", /* 50 */
377: SCANEOF, "scaneof", /* 51 */
378: BADCHAR, "badchar", /* 52 */
379: SP, "sp", /* 53 */
380: ALPH, "alph", /* 54 */
381: DIG, "dig", /* 55 */
382: SQ, "sq", /* 56 */
383: DQ, "dq", /* 57 */
384: SH, "sh", /* 58 */
385: LSH, "lsh", /* 59 */
386: RSH, "rsh", /* 60 */
387: MINUS, "minus", /* 61 */
388: SIZEQUOTE, "sizequote", /* 62 */
389: XOR, "xor", /* 64 */
390: DIV, "div", /* 65 */
391: SEMI, "semi", /* 66 */
392: COLON, "colon", /* 67 */
393: PLUS, "plus", /* 68 */
394: IOR, "ior", /* 69 */
395: AND, "and", /* 70 */
396: TILDE, "tilde", /* 71 */
397: ORNOT, "ornot", /* 72 */
398: CM, "cm", /* 73 */
399: LB, "lb", /* 74 */
400: RB, "rb", /* 75 */
401: RP, "rp", /* 76 */
402: LASTTOKEN, "lasttoken" /* 80 */
403: };
404: /*
405: * turn a token type into a string
406: */
407: static int fixed = 0;
408: char *tok_to_name(token)
409: {
410: if (!fixed){
411: int i;
412: for (i = FIRSTTOKEN; i <= LASTTOKEN; i++)
413: tok_name[i] = "NOT ASSIGNED";
414: for (i = FIRSTTOKEN; i <= sizeof(tok_desc)/sizeof(struct Tok_Desc); i++){
415: tok_name[tok_desc[i].tok_which] = tok_desc[i].tok_name;
416: }
417: fixed = 1;
418: }
419: if (FIRSTTOKEN <= token && token <= LASTTOKEN)
420: return(tok_name[token]);
421: else
422: panic("Unknown token number, %d\n", token);
423: /*NOTREACHED*/
424: }
425: #endif DEBUG
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.