|
|
1.1 root 1: /* Copyright (c) 1979 Regents of the University of California */
2: #include <stdio.h>
3: #include "as.h"
4: #include "asexpr.h"
5:
6: /*
7: * Tables for combination of operands.
8: */
9:
10: /*
11: * table for +
12: */
13: readonly char pltab[6][6] = {
14: /* UND ABS TXT DAT BSS EXT */
15:
16: /*UND*/ XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF,
17: /*ABS*/ XUNDEF, XABS, XTEXT, XDATA, XBSS, XXTRN,
18: /*TXT*/ XUNDEF, XTEXT, ERR, ERR, ERR, ERR,
19: /*DAT*/ XUNDEF, XDATA, ERR, ERR, ERR, ERR,
20: /*BSS*/ XUNDEF, XBSS, ERR, ERR, ERR, ERR,
21: /*EXT*/ XUNDEF, XXTRN, ERR, ERR, ERR, ERR,
22: };
23:
24: /*
25: * table for -
26: */
27: readonly char mintab[6][6] = {
28: /* UND ABS TXT DAT BSS EXT */
29:
30: /*UND*/ XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF,
31: /*ABS*/ XUNDEF, XABS, ERR, ERR, ERR, ERR,
32: /*TXT*/ XUNDEF, XTEXT, XABS, ERR, ERR, ERR,
33: /*DAT*/ XUNDEF, XDATA, ERR, XABS, ERR, ERR,
34: /*BSS*/ XUNDEF, XBSS, ERR, ERR, XABS, ERR,
35: /*EXT*/ XUNDEF, XXTRN, ERR, ERR, ERR, ERR,
36: };
37:
38: /*
39: * table for other operators
40: */
41: readonly char othtab[6][6] = {
42: /* UND ABS TXT DAT BSS EXT */
43:
44: /*UND*/ XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF,
45: /*ABS*/ XUNDEF, XABS, ERR, ERR, ERR, ERR,
46: /*TXT*/ XUNDEF, ERR, ERR, ERR, ERR, ERR,
47: /*DAT*/ XUNDEF, ERR, ERR, ERR, ERR, ERR,
48: /*BSS*/ XUNDEF, ERR, ERR, ERR, ERR, ERR,
49: /*EXT*/ XUNDEF, ERR, ERR, ERR, ERR, ERR,
50: };
51:
52: struct exp *
53: combine(op, exp1, exp2)
54: register struct exp *exp1, *exp2;
55: {
56: register e1_type, e2_type;
57: register type;
58:
59: lastnam=0; /* kludge for jxxx instructions */
60:
61: e1_type = exp1->xtype&XTYPE;
62: e2_type = exp2->xtype&XTYPE;
63:
64: if (exp1->xtype==XXTRN+XUNDEF)
65: e1_type = XTXRN;
66: if (exp2->xtype==XXTRN+XUNDEF)
67: e2_type = XTXRN;
68: if (passno==1)
69: if (exp1->xloc!=exp2->xloc && e1_type==e2_type)
70: e1_type = e2_type = XTXRN; /* error on != loc ctrs */
71: e1_type >>= 1; /*dispost of the external (XXTRN) bit*/
72: e2_type >>= 1;
73:
74: switch (op) {
75: case PLUS:
76: exp1->xvalue += exp2->xvalue;
77: type = pltab[e1_type][e2_type];
78: break;
79: case MINUS:
80: exp1->xvalue -= exp2->xvalue;
81: type = mintab[e1_type][e2_type];
82: break;
83: case IOR:
84: exp1->xvalue |= exp2->xvalue;
85: goto comm;
86: case XOR:
87: exp1->xvalue ^= exp2->xvalue;
88: goto comm;
89: case AND:
90: exp1->xvalue &= exp2->xvalue;
91: goto comm;
92: case ORNOT:
93: exp1->xvalue |= ~exp2->xvalue;
94: goto comm;
95: case LSH:
96: exp1->xvalue <<= exp2->xvalue;
97: goto comm;
98: case RSH:
99: exp1->xvalue >>= exp2->xvalue;
100: goto comm;
101: case TILDE:
102: exp1->xvalue |= ~ exp2->xvalue;
103: goto comm;
104: case MUL:
105: exp1->xvalue *= exp2->xvalue;
106: goto comm;
107: case DIV:
108: if (exp2->xvalue == 0)
109: yyerror("Divide check");
110: else
111: exp1->xvalue /= exp2->xvalue;
112: goto comm;
113: case REGOP:
114: if (exp2->xvalue == 0)
115: yyerror("Divide check (modulo)");
116: else
117: exp1->xvalue %= exp2->xvalue;
118: goto comm;
119:
120: comm:
121: type = othtab[e1_type][e2_type];
122: break;
123: default:
124: yyerror("Internal error: unknown operator");
125: }
126:
127: if (e2_type==(XTXRN>>1))
128: exp1->xname = exp2->xname;
129: exp1->xtype = type | (
130: (exp1->xtype|exp2->xtype) & (XFORW|XXTRN) );
131: if (type==ERR)
132: yyerror("Relocation error");
133: return(exp1);
134: }
135:
136: buildtokensets()
137: {
138: #define clobber(val, set) tokensets[(val)] |= (set)
139:
140: clobber(SEMI, LINSTBEGIN);
141: clobber(NL, LINSTBEGIN);
142:
143: clobber(NAME, YUKKYEXPRBEG + LINSTBEGIN);
144: clobber(INSTn, YUKKYEXPRBEG);
145: clobber(INST0, YUKKYEXPRBEG);
146: clobber(REG, YUKKYEXPRBEG);
147:
148: clobber(INT, SAFEEXPRBEG);
149: clobber(FLTNUM, SAFEEXPRBEG);
150:
151: clobber(PLUS, ADDOPS);
152: clobber(MINUS, ADDOPS + EBEGOPS);
153:
154: clobber(LP, EBEGOPS);
155:
156: clobber(IOR, BOOLOPS);
157: clobber(XOR, BOOLOPS);
158: clobber(AND, BOOLOPS);
159: clobber(ORNOT, BOOLOPS);
160:
161: clobber(TILDE, MULOPS + EBEGOPS);
162: clobber(LSH, MULOPS);
163: clobber(RSH, MULOPS);
164: clobber(MUL, MULOPS);
165: clobber(DIV, MULOPS);
166: clobber(REGOP, MULOPS); /* % */
167: }
168:
169: /*
170: * We keep the current token class in this global variable, so
171: * the recursive descent expression analyzers can talk amongst
172: * themselves, and so that we may use the macros shift and shift over
173: */
174:
175: extern int yylval; /*the value of the lexical value*/
176: extern struct exp *xp; /*the next free expression slot*/
177:
178: static int val;
179: int exprparse(inval, backexpr) /*return the value the read head is sitting on*/
180: int inval;
181: struct exp **backexpr;
182: {
183: register struct exp *lexpr;
184: int op;
185:
186: val = inval;
187: lexpr = boolterm();
188: while (INTOKSET(val, ADDOPS)){
189: op = val;
190: shift;
191: lexpr = combine(op, lexpr, boolterm());
192: }
193: *backexpr = lexpr;
194: return(val);
195: }
196:
197: struct exp *boolterm()
198: {
199: register struct exp *lexpr;
200: int op;
201:
202: lexpr = term();
203: while(INTOKSET(val, BOOLOPS)){
204: op = val;
205: shift;
206: lexpr = combine(op, lexpr, term());
207: }
208: return(lexpr);
209: }
210:
211: struct exp *term()
212: {
213: register struct exp *lexpr;
214: int op;
215:
216: lexpr = factor();
217: while(INTOKSET(val, MULOPS)){
218: op = val;
219: shift;
220: lexpr = combine(op, lexpr, factor());
221: }
222: return(lexpr);
223: }
224:
225: struct exp *factor()
226: {
227: struct exp *lexpr;
228: int op;
229: extern int droppedLP; /*called exprparse after consuming an LP*/
230:
231: if (val == LP || droppedLP){
232: if (droppedLP)
233: droppedLP = 0;
234: else
235: shift; /*the LP*/
236: val = exprparse(val, &lexpr);
237: if (val != RP)
238: yyerror("right parenthesis expected");
239: else
240: shift;
241: } else
242: if (INTOKSET(val, YUKKYEXPRBEG)){
243: lexpr = yukkyexpr(val, yylval);
244: shift;
245: }
246: else if (INTOKSET(val, SAFEEXPRBEG)){
247: lexpr = (struct exp *)yylval;
248: shift;
249: }
250: else if ( (val == TILDE) || (val == MINUS) ){
251: op = val;
252: shift;
253: lexpr = xp++;
254: lexpr->xtype = XABS;
255: lexpr->xvalue = 0;
256: lexpr = combine(op, lexpr, factor());
257: }
258: else {
259: yyerror("Bad expression syntax");
260: lexpr = xp++;
261: lexpr->xtype = XABS;
262: lexpr->xvalue = 0;
263: }
264: return(lexpr);
265: }
266:
267: struct exp *yukkyexpr(val, np)
268: int val;
269: register np;
270: {
271: register struct exp *locxp;
272: extern int exprisname; /*last factor is a name*/
273:
274: exprisname = 0;
275: locxp = xp++;
276: if (val == NAME){
277: exprisname++;
278: locxp->xtype = ((struct symtab *)np)->type;
279: if (( ((struct symtab *)np)->type&XTYPE)==XUNDEF) { /*forward*/
280: locxp->xname = (struct symtab *)np;
281: locxp->xvalue = 0;
282: if (passno==1)
283: ((struct symtab *)np)->type |= XFORW;
284: } else { /*otherwise, just get the value*/
285: locxp->xvalue = ((struct symtab *)np)->value;
286: locxp->xname = NULL;
287: }
288: } else { /*INSTn or INST0 or REG*/
289: locxp->xtype = XABS;
290: locxp->xvalue = ( (int)np) & 0xFF;
291: locxp->xloc = 0;
292: locxp->xname = NULL;
293: }
294:
295: return(locxp);
296: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.