1 /*
2 * Copyright (c) 1982 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 */
6
7 #ifndef lint
8 static char sccsid[] = "@(#)asscan1.c 5.1 (Berkeley) 04/30/85";
9 #endif not lint
10
11 #include "asscanl.h"
12
inittokfile()13 inittokfile()
14 {
15 if (passno == 1){
16 if (useVM){
17 bufstart = &tokbuf[0];
18 buftail = &tokbuf[1];
19 bufstart->tok_next = buftail;
20 buftail->tok_next = 0;
21 }
22 tokbuf[0].tok_count = -1;
23 tokbuf[1].tok_count = -1;
24 }
25 tok_temp = 0;
26 tok_free = 0;
27 bufno = 0;
28 emptybuf = &tokbuf[bufno];
29 tokptr = 0;
30 tokub = 0;
31 }
32
closetokfile()33 closetokfile()
34 {
35 if (passno == 1){
36 if (useVM){
37 emptybuf->toks[emptybuf->tok_count++] = PARSEEOF;
38 } else {
39 /*
40 * Clean up the buffers that haven't been
41 * written out yet
42 */
43 if (tokbuf[bufno ^ 1].tok_count >= 0){
44 if (writeTEST((char *)&tokbuf[bufno ^ 1], sizeof *emptybuf, 1, tokfile)){
45 badwrite:
46 yyerror("Unexpected end of file writing the interpass tmp file");
47 exit(2);
48 }
49 }
50 /*
51 * Ensure that we will read an End of file,
52 * if there are more than one file names
53 * in the argument list
54 */
55 tokbuf[bufno].toks[tokbuf[bufno].tok_count++] = PARSEEOF;
56 if (writeTEST((char *)&tokbuf[bufno], sizeof *emptybuf, 1, tokfile))
57 goto badwrite;
58 }
59 } /*end of being pass 1*/
60 }
61
yylex()62 inttoktype yylex()
63 {
64 register ptrall bufptr;
65 register inttoktype val;
66 register struct exp *locxp;
67 /*
68 * No local variables to be allocated; this saves
69 * one piddling instruction..
70 */
71 static int Lastjxxx;
72
73 bufptr = tokptr; /*copy in the global value*/
74 top:
75 if (bufptr < tokub){
76 gtoken(val, bufptr);
77 switch(yylval = val){
78 case PARSEEOF:
79 yylval = val = PARSEEOF;
80 break;
81 case BFINT:
82 case INT:
83 if (xp >= &explist[NEXP])
84 yyerror("Too many expressions; try simplyfing");
85 else
86 locxp = xp++;
87 locxp->e_number = Znumber;
88 locxp->e_number.num_tag = TYPL;
89 glong(locxp->e_xvalue, bufptr);
90 makevalue:
91 locxp->e_xtype = XABS;
92 locxp->e_xloc = 0;
93 locxp->e_xname = NULL;
94 yylval = (int)locxp;
95 break;
96 case BIGNUM:
97 if (xp >= &explist[NEXP])
98 yyerror("Too many expressions; try simplyfing");
99 else
100 locxp = xp++;
101 gnumber(locxp->e_number, bufptr);
102 goto makevalue;
103 case NAME:
104 gptr(yylval, bufptr);
105 lastnam = (struct symtab *)yylval;
106 break;
107 case SIZESPEC:
108 case REG:
109 gchar(yylval, bufptr);
110 break;
111 case INSTn:
112 case INST0:
113 gopcode(yyopcode, bufptr);
114 break;
115 case IJXXX:
116 gopcode(yyopcode, bufptr);
117 /* We can't cast Lastjxxx into (int *) here.. */
118 gptr(Lastjxxx, bufptr);
119 lastjxxx = (struct symtab *)Lastjxxx;
120 break;
121 case ILINESKIP:
122 gint(yylval, bufptr);
123 lineno += yylval;
124 goto top;
125 case SKIP:
126 eatskiplg(bufptr);
127 goto top;
128 case VOID:
129 goto top;
130 case STRING:
131 case ISTAB:
132 case ISTABSTR:
133 case ISTABNONE:
134 case ISTABDOT:
135 case IALIGN:
136 gptr(yylval, bufptr);
137 break;
138 }
139 #ifdef DEBUG
140 if (toktrace){
141 char *tok_to_name();
142 printf("P: %d T#: %4d, %s ",
143 passno, bufptr - firsttoken, tok_to_name(val));
144 switch(val){
145 case INT: printf("val %d",
146 ((struct exp *)yylval)->e_xvalue);
147 break;
148 case BFINT: printf("val %d",
149 ((struct exp *)yylval)->e_xvalue);
150 break;
151 case BIGNUM: bignumprint(((struct exp*)yylval)->e_number);
152 break;
153 case NAME: printf("\"%.8s\"",
154 FETCHNAME((struct symtab *)yylval));
155 break;
156 case REG: printf(" r%d",
157 yylval);
158 break;
159 case IJXXX:
160 case INST0:
161 case INSTn: if (ITABCHECK(yyopcode))
162 printf("%.8s",
163 FETCHNAME(ITABFETCH(yyopcode)));
164 else
165 printf("IJXXX or INST0 or INSTn can't get into the itab\n");
166 break;
167 case STRING:
168 printf("length %d, seekoffset %d, place 0%o ",
169 ((struct strdesc *)yylval)->sd_strlen,
170 ((struct strdesc *)yylval)->sd_stroff,
171 ((struct strdesc *)yylval)->sd_place
172 );
173 if (((struct strdesc *)yylval)->sd_place & STR_CORE)
174 printf("value\"%*s\"",
175 ((struct strdesc *)yylval)->sd_strlen,
176 ((struct strdesc *)yylval)->sd_string);
177 break;
178 } /*end of the debug switch*/
179 printf("\n");
180 }
181 #endif DEBUG
182
183 } else { /* start a new buffer */
184 if (useVM){
185 if (passno == 2){
186 tok_temp = emptybuf->tok_next;
187 emptybuf->tok_next = tok_free;
188 tok_free = emptybuf;
189 emptybuf = tok_temp;
190 } else {
191 emptybuf = emptybuf->tok_next;
192 }
193 bufno += 1;
194 if (emptybuf == 0){
195 struct tokbufdesc *newdallop;
196 int i;
197 if (passno == 2)
198 goto badread;
199 emptybuf = newdallop = (struct tokbufdesc *)
200 Calloc(TOKDALLOP, sizeof (struct tokbufdesc));
201 for (i=0; i < TOKDALLOP; i++){
202 buftail->tok_next = newdallop;
203 buftail = newdallop;
204 newdallop += 1;
205 }
206 buftail->tok_next = 0;
207 } /*end of need to get more buffers*/
208 (bytetoktype *)bufptr = &(emptybuf->toks[0]);
209 if (passno == 1)
210 scan_dot_s(emptybuf);
211 } else { /*don't use VM*/
212 bufno ^= 1;
213 emptybuf = &tokbuf[bufno];
214 ((bytetoktype *)bufptr) = &(emptybuf->toks[0]);
215 if (passno == 1){
216 /*
217 * First check if there are things to write
218 * out at all
219 */
220 if (emptybuf->tok_count >= 0){
221 if (writeTEST((char *)emptybuf, sizeof *emptybuf, 1, tokfile)){
222 yyerror("Unexpected end of file writing the interpass tmp file");
223 exit(2);
224 }
225 }
226 scan_dot_s(emptybuf);
227 } else { /*pass 2*/
228 if (readTEST((char *)emptybuf, sizeof *emptybuf, 1, tokfile)){
229 badread:
230 yyerror("Unexpected end of file while reading the interpass tmp file");
231 exit(1);
232 }
233 }
234 } /*end of using a real live file*/
235 (char *)tokub = (char *)bufptr + emptybuf->tok_count;
236 #ifdef DEBUG
237 firsttoken = bufptr;
238 if (debug)
239 printf("created buffernumber %d with %d tokens\n",
240 bufno, emptybuf->tok_count);
241 #endif DEBUG
242 goto top;
243 } /*end of reading/creating a new buffer*/
244 tokptr = bufptr; /*copy back the global value*/
245 return(val);
246 } /*end of yylex*/
247
248
buildskip(from,to)249 buildskip(from, to)
250 register ptrall from, to;
251 {
252 int diff;
253 register struct tokbufdesc *middlebuf;
254 /*
255 * check if from and to are in the same buffer
256 * from and to DIFFER BY AT MOST 1 buffer and to is
257 * always ahead of from, with to being in the buffer emptybuf
258 * points to.
259 * The hard part here is accounting for the case where the
260 * skip is to cross a buffer boundary; we must construct
261 * two skips.
262 *
263 * Figure out where the buffer boundary between from and to is
264 * It's easy in VM, as buffers increase to high memory, but
265 * w/o VM, we alternate between two buffers, and want
266 * to look at the exact middle of the contiguous buffer region.
267 */
268 middlebuf = useVM ? emptybuf : &tokbuf[1];
269 if ( ( (bytetoktype *)from > (bytetoktype *)middlebuf)
270 ^ ( (bytetoktype *)to > (bytetoktype *)middlebuf)
271 ){ /*split across a buffer boundary*/
272 ptoken(from, SKIP);
273 /*
274 * Set the skip so it lands someplace beyond
275 * the end of this buffer.
276 * When we pull this skip out in the second pass,
277 * we will temporarily move the current pointer
278 * out beyond the end of the buffer, but immediately
279 * do a compare and fail the compare, and then reset
280 * all the pointers correctly to point into the next buffer.
281 */
282 bskiplg(from, TOKBUFLG + 1);
283 /*
284 * Now, force from to be in the same buffer as to
285 */
286 (bytetoktype *)from = (bytetoktype *)&(emptybuf->toks[0]);
287 }
288 /*
289 * Now, to and from are in the same buffer
290 */
291 if (from > to)
292 yyerror("Internal error: bad skip construction");
293 else {
294 if ( (diff = (bytetoktype *)to - (bytetoktype *)from) >=
295 (sizeof(bytetoktype) + sizeof(lgtype) + 1)) {
296 ptoken(from, SKIP);
297 bskipfromto(from, to);
298 } else {
299 for ( ; diff > 0; --diff)
300 ptoken(from, VOID);
301 }
302 }
303 }
304
movestr(to,from,lg)305 movestr(to, from, lg)
306 char *to; /* 4(ap) */
307 char *from; /* 8(ap) */
308 int lg; /* 12(ap) */
309 {
310 if (lg <= 0)
311 return;
312 ;
313 asm("movc3 12(ap),*8(ap),*4(ap)");
314 ;
315 }
316
new_dot_s(namep)317 new_dot_s(namep)
318 char *namep;
319 {
320 newfflag = 1;
321 newfname = namep;
322 dotsname = namep;
323 lineno = 1;
324 scanlineno = 1;
325 }
326
min(a,b)327 min(a, b)
328 {
329 return(a < b ? a : b);
330 }
331