1
|
1 /* Micro-C Parser Part */
|
|
2 /* $Id$ */
|
|
3
|
0
|
4 #define EXTERN /**/
|
|
5 #include "mc.h"
|
|
6
|
|
7 void ntable_consistency();
|
|
8 static void adecl(NMTBL *n);
|
13
|
9 static int decl_data(int t, NMTBL *n,int offset);
|
0
|
10 static int alpha(char c);
|
|
11 static int binop(int op, int e1, int e2, int t1, int t2);
|
|
12 int caddr(int e);
|
|
13 int cadr(int e);
|
|
14 int car(int e);
|
|
15 static void compatible(int t1, int t2);
|
|
16 static void decl(void);
|
|
17 static void def(NMTBL *n);
|
|
18 static int digit(char c);
|
|
19 static void docase(void);
|
|
20 static void docomp(void);
|
|
21 static void dodefault(void);
|
|
22 static void dodo(void);
|
|
23 static void dofor(void);
|
|
24 static void dogoto(void);
|
|
25 static void doif(void);
|
|
26 static void dolabel(void);
|
|
27 static void doswitch(void);
|
|
28 static void doreturn(void);
|
|
29 static void dowhile(void);
|
|
30 static void errmsg(void);
|
18
|
31 static void macro_processing();
|
0
|
32 static void copy(NMTBL *nptr, char *s);
|
|
33 void error(int n);
|
|
34 static int expr(void);
|
|
35 static int expr0(void);
|
|
36 static int expr1(void);
|
|
37 static int expr2(void);
|
|
38 static int expr3(void);
|
|
39 static int expr4(void);
|
|
40 static int expr5(void);
|
|
41 static int expr6(void);
|
|
42 static int expr7(void);
|
|
43 static int expr8(void);
|
|
44 static int expr9(void);
|
|
45 static int expr10(void);
|
|
46 static int expr11(void);
|
|
47 static int expr12(void);
|
|
48 static int expr13(void);
|
|
49 static int expr14(void);
|
|
50 static int expr15(int e1);
|
|
51 static int expr16(int e1);
|
|
52 static void fcheck(NMTBL *n);
|
|
53 static void fdecl(NMTBL *n);
|
|
54 static int getch(void);
|
|
55 static int getfree(int n);
|
|
56 static void getline(void);
|
|
57 static void getstring(void);
|
|
58 static int getsym(void);
|
|
59 static int indop(int e);
|
|
60 static void init(void);
|
|
61 static int integral(int t);
|
|
62 static void lcheck(int e);
|
18
|
63 extern int glist2(int e1,int e2);
|
|
64 extern int list2(int e1, int e2);
|
|
65 extern int list3(int e1, int e2, int e3);
|
|
66 extern int list4(int e1, int e2, int e3, int e4);
|
0
|
67 static void reserve(char *s, int d);
|
|
68 static int macroeq(char *s);
|
|
69 static int ndecl0(void);
|
|
70 static int ndecl1(void);
|
|
71 static int neqname(char *p);
|
|
72 static void newfile(void);
|
|
73 static int postequ(int s1, int s2);
|
|
74 static void reverse(int t1);
|
2
|
75 int reverse0(int t1);
|
0
|
76 static int rplacad(int e, int n);
|
|
77 static int rvalue(int e);
|
2
|
78 int scalar(int t);
|
0
|
79 static int sdecl(int s);
|
|
80 static int skipspc(void);
|
|
81 static void statement(void);
|
|
82 static int strop(int e);
|
|
83 static int typeid(int s);
|
|
84 static int typename(void);
|
|
85 static int typespec(void);
|
|
86 static int cexpr(int e);
|
|
87 static void code_decl(NMTBL *n);
|
|
88
|
18
|
89 extern void display_ntable(NMTBL *n, char *s);
|
0
|
90 extern void closing(void);
|
|
91 extern void opening(char *filename);
|
|
92 extern void gen_gdecl(char *n, int gpc);
|
18
|
93 extern void emit_init(void);
|
0
|
94 extern void enter(char *name);
|
|
95 extern void enter1(int disp);
|
|
96 extern void leave(int control, char *name);
|
|
97 extern void ret(void);
|
|
98 extern void jmp(int l);
|
|
99 extern void gexpr(int e1);
|
18
|
100 extern void g_expr(int e1);
|
0
|
101 extern int get_register_var(void);
|
|
102 extern void bexpr(int e1, char cond, int l1);
|
|
103 extern int fwdlabel(void);
|
|
104 extern void fwddef(int l);
|
|
105 extern int backdef(void);
|
|
106 extern int def_label(int cslabel, int dlabel);
|
|
107 extern void jmp_label(int l);
|
|
108 extern void cmpdimm(int e, int csreg);
|
|
109 extern void jcond(int l, char cond);
|
|
110 extern void jmp_eq_label(int l);
|
|
111 extern void gen_comment(char *s);
|
|
112 extern void gen_source(char *s);
|
|
113 extern void code_init(void);
|
18
|
114 extern void code_enter(char *name) ;
|
|
115 extern void code_leave(char *name) ;
|
|
116 extern void code_enter1(int disp0,int args);
|
|
117
|
0
|
118 extern void emit_data_closing(NMTBL *n);
|
|
119 extern void emit_data(int e, int t, NMTBL *n);
|
|
120
|
18
|
121 extern void exit(int l);
|
|
122
|
0
|
123 int
|
|
124 main(int argc, char **argv)
|
|
125 {
|
|
126 NMTBL *nptr;
|
|
127 int i;
|
|
128 char *ccout;
|
|
129
|
|
130 if(argc==1) exit(1);
|
|
131 lsrc = chk = asmf = 0;
|
|
132 ccout = OUTPUT_FILE_NAME;
|
|
133 ac=argc;
|
|
134 av=argv;
|
|
135 for (ac2=1; (ac2 < ac) && (*av[ac2] == '-'); ++ac2) {
|
|
136 switch (*(av[ac2]+1)) {
|
|
137 case 'S': case 's':
|
|
138 lsrc = 1;
|
|
139 break;
|
|
140 case 'O': case 'o':
|
|
141 ccout = av[ac2]+2;
|
|
142 break;
|
|
143 case 'C': case 'c':
|
|
144 chk = 1;
|
|
145 break;
|
|
146 case 'D': case 'd':
|
|
147 debug = 1;
|
|
148 break;
|
|
149 default:
|
|
150 error(OPTION);
|
|
151 exit(1);
|
|
152 }
|
|
153 }
|
|
154 if (!chk)
|
18
|
155 if ( (freopen(ccout,"w",stdout)) == NULL ) error(FILERR);
|
0
|
156 init();
|
|
157 while(1) {
|
2
|
158 for (nptr = &ntable[GSYMS],i=LSYMS; i--;) {
|
0
|
159 (nptr++)->sc = 0;
|
2
|
160 }
|
|
161 emit_init();
|
0
|
162 mode=TOP;
|
|
163 lfree= HEAPSIZE;
|
|
164 while(getsym()==SM);
|
|
165 mode=GDECL;
|
|
166 stmode=0;
|
|
167 args=0;
|
|
168 decl();
|
|
169 }
|
|
170 /*NOTREACHED*/
|
|
171 }
|
|
172
|
|
173 void
|
|
174 error(int n)
|
|
175 {
|
|
176 if(n == EOFERR) {
|
|
177 if(filep!=filestack) {
|
|
178 fclose(filep->fcb);
|
|
179 lineno=filep->ln;
|
|
180 --filep;
|
|
181 return;
|
|
182 } else if(ac2!=ac) {
|
|
183 fclose(filep->fcb);
|
|
184 newfile();
|
|
185 return;
|
|
186 } else if(mode == TOP) {
|
18
|
187 /*
|
|
188 if (!chk) fprintf(stderr,
|
|
189 "Total internal labels : %u.\n",labelno-1);
|
|
190 fprintf(stderr,
|
|
191 "Total global variables : %u bytes.\n\n",gpc);
|
|
192 */
|
0
|
193 closing();
|
|
194 exit(0);
|
|
195 }
|
|
196 }
|
25
|
197 fprintf(stderr,"%s:%d:%s\n",filep->name0,lineno,
|
0
|
198 (n==FILERR) ? "Can't open specified file" :
|
|
199 (n==DCERR) ? "Declaration syntax" :
|
|
200 (n==STERR) ? "Statement syntax" :
|
|
201 (n==EXERR) ? "Expression syntax" :
|
|
202 (n==CNERR) ? "Constant required" :
|
|
203 (n==CHERR) ? "Illegal character" :
|
|
204 (n==GSERR) ? "Too many global symbols" :
|
|
205 (n==LSERR) ? "Too many local symbols" :
|
|
206 (n==STRERR) ? "Too many strings or macros" :
|
|
207 (n==LNERR) ? "Line too long" :
|
|
208 (n==EOFERR) ? "Unexpected end of file" :
|
|
209 (n==MCERR) ? "Macro syntax" :
|
|
210 (n==INCERR) ? "Include syntax" :
|
|
211 (n==HPERR) ? "Too long expression" :
|
|
212 (n==TYERR) ? "Type mismatch" :
|
|
213 (n==LVERR) ? "Lvalue required" :
|
|
214 (n==UDERR) ? "Undeclared identifier" :
|
|
215 (n==OPTION) ? "Illegal option" :
|
|
216 (n==REG_ERR) ? "illegal register var" :
|
|
217 (n==CODE_ERR) ? "goto code is necessary" :
|
|
218 "Bug of compiler");
|
|
219 errmsg();
|
|
220 exit(1);
|
|
221 }
|
|
222
|
|
223 void
|
|
224 errmsg(void)
|
|
225 {
|
|
226 char *p,*lim;
|
|
227
|
|
228 if(lineno==0) return;
|
|
229 fprintf(stderr,"%s",linebuf);
|
|
230 lim=(mflag?chptrsave:chptr);
|
|
231 for (p=linebuf; p < lim;)
|
|
232 fprintf(stderr,(*p++ == '\t') ? "\t" : " ");
|
|
233 fprintf (stderr,"^\n");
|
|
234 }
|
|
235
|
|
236 void
|
|
237 checksym(int s)
|
|
238 {
|
|
239 char *p;
|
|
240
|
|
241 if (sym != s) {
|
|
242 p=(s==RPAR) ? "')'": (s==RBRA) ? "']'": (s==SM) ? "';'":
|
|
243 (s==LPAR) ? "'('": (s==WHILE) ? "'while'":
|
|
244 (s==COLON) ? "':'": "Identifier";
|
|
245 fprintf(stderr,"%d:%s expected.\n",lineno,p);
|
|
246 errmsg();
|
|
247 } else
|
|
248 getsym();
|
|
249 }
|
|
250
|
|
251 void
|
|
252 init(void)
|
|
253 {
|
|
254 NMTBL *nptr;
|
|
255 int i;
|
|
256
|
|
257 cheapp=cheap;
|
|
258 for(nptr = ntable,i = GSYMS; i--;) (nptr++)->sc = 0;
|
|
259 reserve("int",INT);
|
|
260 reserve("void",VOID);
|
|
261 reserve("char",CHAR);
|
20
|
262 reserve("const",KONST);
|
0
|
263 reserve("struct",STRUCT);
|
|
264 reserve("union",UNION);
|
|
265 reserve("unsigned",UNSIGNED);
|
|
266 reserve("static",STATIC);
|
|
267 reserve("goto",GOTO);
|
|
268 reserve("return",RETURN);
|
|
269 reserve("break",BREAK);
|
|
270 reserve("continue",CONTINUE);
|
|
271 reserve("if",IF);
|
|
272 reserve("else",ELSE);
|
|
273 reserve("for",FOR);
|
|
274 reserve("do",DO);
|
|
275 reserve("while",WHILE);
|
|
276 reserve("switch",SWITCH);
|
|
277 reserve("case",CASE);
|
|
278 reserve("default",DEFAULT);
|
|
279 reserve("typedef",TYPEDEF);
|
|
280 reserve("sizeof",SIZEOF);
|
|
281 reserve("long",LONG);
|
|
282 reserve("short",SHORT);
|
|
283 reserve("extern",EXTRN);
|
18
|
284 reserve("defined",DEFINED);
|
0
|
285 reserve("register",REGISTER);
|
|
286 reserve("code",CODE);
|
|
287 reserve("environment",ENVIRONMENT);
|
19
|
288
|
|
289 reserve("__micro_c__",0);
|
|
290
|
0
|
291 gpc=glineno=mflag=0;
|
|
292 gfree=ilabel=1;
|
|
293 labelno=2;
|
|
294 lfree=HEAPSIZE;
|
|
295 filep=filestack;
|
|
296 code_init();
|
|
297 newfile();
|
|
298 getline();
|
|
299 getch();
|
|
300 }
|
|
301
|
|
302 void
|
|
303 newfile(void)
|
|
304 {
|
25
|
305 char *s;
|
0
|
306 lineno=0;
|
18
|
307 /* fprintf(stderr,"%s:\n",av[ac2]); */
|
0
|
308 opening(av[ac2]);
|
|
309 if ( (filep->fcb = fopen(av[ac2++],"r")) == NULL ) error(FILERR);
|
25
|
310 s = av[ac2-1];
|
|
311 filep->name0 = cheapp;
|
|
312 while((*cheapp++ = *s++));
|
0
|
313 }
|
|
314
|
|
315 void
|
|
316 reserve(char *s, int d)
|
|
317 {
|
|
318 NMTBL *nptr;
|
|
319 int i;
|
|
320
|
|
321 hash=0; name=namebuf; i=0;
|
|
322 while((name[i++] = *s)) {
|
|
323 hash=((7*hash) ^ *s++);
|
|
324 }
|
|
325 if (cheapp+i >= cheap+CHEAPSIZE) error(STRERR);
|
|
326 name[i++] = 0;
|
|
327 (nptr = gsearch())->sc = RESERVE;
|
19
|
328 if (d==0) {
|
|
329 nptr->sc = MACRO;
|
|
330 nptr->dsp = (int)"1";
|
|
331 } else {
|
|
332 nptr->dsp = d;
|
|
333 }
|
0
|
334 }
|
|
335
|
|
336 static
|
|
337 NMTBL null_nptr;
|
|
338
|
|
339 void
|
|
340 decl(void)
|
|
341 {
|
|
342 NMTBL *n;
|
|
343 int t;
|
|
344
|
|
345 if(sym==STATIC) {
|
|
346 if(mode==LDECL) {
|
|
347 getsym();
|
|
348 mode=STADECL;
|
|
349 stmode=LDECL;
|
|
350 } else if(mode==GDECL) {
|
|
351 getsym();
|
|
352 stmode=STATIC;
|
|
353 } else
|
|
354 error(DCERR);
|
|
355 } else if(sym==REGISTER) {
|
|
356 if(mode!=LDECL)
|
|
357 error(DCERR);
|
|
358 stmode=REGISTER;
|
|
359 getsym();
|
|
360 } else if(sym==EXTRN) {
|
|
361 getsym();
|
|
362 stmode=EXTRN;
|
|
363 } else if(sym==TYPEDEF) {
|
|
364 if(mode==GDECL) {
|
|
365 getsym();
|
|
366 mode=GTDECL;
|
|
367 } else if(mode==LDECL) {
|
|
368 getsym();
|
|
369 mode=LTDECL;
|
|
370 } else
|
|
371 error(DCERR);
|
|
372 }
|
|
373 if((t=typespec())==0) return;
|
|
374 if(sym==SM) return;
|
|
375 type=t;
|
|
376 n=decl0();
|
|
377 reverse(t);
|
|
378 if (n == &null_nptr) {
|
|
379 error(DCERR);
|
|
380 return;
|
|
381 }
|
|
382 if(sym==LC || ( sym!=SM && sym!=COMMA && sym!=ASS )) {
|
|
383 if (car(type)==CODE) {
|
|
384 code_decl(n); return;
|
|
385 } else if (car(type)==FUNCTION) {
|
|
386 fdecl(n); return;
|
|
387 }
|
|
388 }
|
|
389 def(n);
|
|
390 while(sym==COMMA) {
|
|
391 getsym();
|
|
392 type=t;
|
|
393 n=decl0();
|
|
394 reverse(t);
|
|
395 if(n == &null_nptr) error(DCERR);
|
|
396 /* if(args) error(DCERR); */
|
|
397 def(n);
|
|
398 }
|
|
399 if(sym!=SM) error(DCERR);
|
|
400 if(mode==GTDECL)
|
|
401 mode=GDECL;
|
|
402 if(mode==STADECL||mode==LTDECL)
|
|
403 mode=LDECL;
|
|
404 }
|
|
405
|
|
406 int
|
|
407 typespec(void)
|
|
408 {
|
|
409 int t;
|
|
410
|
20
|
411 while (sym==KONST) {
|
|
412 getsym();
|
|
413 }
|
0
|
414 switch(sym) {
|
|
415 case VOID:
|
|
416 case INT:
|
|
417 case CHAR:
|
|
418 case CODE:
|
|
419 t= sym;
|
|
420 getsym();
|
|
421 break;
|
|
422 case STRUCT:
|
|
423 case UNION:
|
|
424 t=sdecl(sym);
|
|
425 break;
|
|
426 case UNSIGNED:
|
|
427 t = UNSIGNED;
|
|
428 if(getsym()==INT) getsym();
|
|
429 break;
|
|
430 case SHORT:
|
|
431 t=CHAR;
|
|
432 if(getsym()==INT) getsym();
|
|
433 break;
|
|
434 case LONG:
|
|
435 t=INT;
|
|
436 if(getsym()==INT) getsym();
|
|
437 break;
|
|
438 default:
|
|
439 if(sym==IDENT) {
|
|
440 if(nptr->sc==TYPE) {
|
|
441 t=nptr->ty;
|
|
442 getsym();
|
|
443 break;
|
|
444 } else if(nptr->sc==EMPTY && gnptr->sc==TYPE) {
|
|
445 t=gnptr->ty;
|
|
446 getsym();
|
|
447 break;
|
|
448 }
|
|
449 }
|
20
|
450 while (sym==KONST) {
|
|
451 getsym();
|
|
452 }
|
0
|
453 if(mode==LDECL) return 0;
|
|
454 t= INT;
|
|
455 }
|
20
|
456 while (sym==KONST) {
|
|
457 getsym();
|
|
458 }
|
0
|
459 return t;
|
|
460 }
|
|
461
|
|
462 struct nametable *
|
|
463 decl0(void)
|
|
464 {
|
|
465 NMTBL *n;
|
|
466 if(sym==MUL) {
|
|
467 getsym();
|
|
468 n=decl0();
|
|
469 type=list2(POINTER,type);
|
|
470 return n;
|
|
471 }
|
|
472 return decl1();
|
|
473 }
|
|
474
|
|
475
|
|
476 NMTBL *
|
|
477 decl1(void)
|
|
478 {
|
|
479 NMTBL *n;
|
|
480 int i,t;
|
|
481
|
|
482 if(sym==LPAR) {
|
|
483 getsym();
|
|
484 n=decl0();
|
|
485 checksym(RPAR);
|
|
486 } else if (sym == IDENT) {
|
|
487 n=nptr;
|
|
488 getsym();
|
|
489 } else {
|
|
490 /* error(DCERR); */
|
|
491 n= &null_nptr;
|
|
492 }
|
|
493 while(1) {
|
|
494 if(sym==LBRA) {
|
|
495 if(getsym()==RBRA) {
|
|
496 getsym();
|
|
497 if(mode==ADECL) {
|
|
498 t=type;
|
|
499 type=list2(POINTER,type);
|
|
500 } else if (mode==GDECL) {
|
|
501 t=type;
|
|
502 type=list3(ARRAY,t,0);
|
|
503 } else {
|
|
504 error(DCERR);
|
|
505 }
|
|
506 } else {
|
|
507 t=type;
|
|
508 i=cexpr(expr());
|
|
509 checksym(RBRA);
|
|
510 type=list3(ARRAY,t,i);
|
|
511 }
|
|
512 } else if(sym==LPAR) {
|
|
513 if(mode==GDECL) {
|
|
514 mode=ADECL;getsym();mode=GDECL; /* ??? */
|
|
515 } else
|
|
516 getsym();
|
|
517 if(sym==RPAR)
|
|
518 getsym();
|
|
519 else {
|
|
520 if (type==CODE) {
|
|
521 n->sc=CODE;
|
|
522 n->dsp=0;
|
|
523 stmode=REGISTER;
|
|
524 adecl(n);
|
|
525 stmode=0;
|
|
526 n->sc=EMPTY;
|
|
527 type=list3(CODE,type,cadr(n->ty));
|
|
528 return n;
|
|
529 } else {
|
|
530 n->sc=FUNCTION;
|
|
531 n->dsp=0;
|
|
532 adecl(n);
|
|
533 n->sc=EMPTY;
|
|
534 }
|
|
535 }
|
|
536 type=list3(FUNCTION,type,cadr(n->ty));
|
|
537 } else
|
|
538 return n;
|
|
539 }
|
|
540 }
|
|
541
|
|
542
|
|
543 void
|
|
544 adecl(NMTBL *n)
|
|
545 {
|
|
546 NMTBL *arg,*sfnptr;
|
|
547 int sreg_var,t;
|
16
|
548 int stype,smode;
|
0
|
549
|
|
550 stype=type;
|
|
551 sfnptr=fnptr;
|
|
552 fnptr=n;
|
|
553 sreg_var=reg_var;
|
|
554 reg_var=0;
|
|
555 n->dsp=0;
|
16
|
556 smode = mode;
|
|
557 /* if(mode!=GDECL && mode!=ADECL)
|
|
558 error(DCERR); */
|
0
|
559 mode=ADECL;
|
|
560 args= 0;
|
|
561 for(;;) {
|
|
562 if(sym==IDENT && nptr->sc!=TYPE) {
|
16
|
563 rplacad(n->ty,glist2(INT,cadr(n->ty)));
|
0
|
564 if (stmode==REGISTER && reg_var < MAX_REGISTER_VAR) {
|
|
565 nptr->ty = INT;
|
|
566 nptr->sc = REGISTER;
|
|
567 if ((nptr->dsp = get_register_var())<0)
|
|
568 error(-1);
|
|
569 reg_var++;
|
|
570 } else {
|
|
571 nptr->ty = INT;
|
|
572 nptr->sc = LVAR;
|
|
573 nptr->dsp = args ;
|
3
|
574 args += size_of_int;
|
0
|
575 }
|
|
576 getsym();
|
|
577 if(sym==RPAR) break;
|
|
578 } else {
|
|
579 if(sym==DOTS) {
|
7
|
580 rplacad(n->ty,glist2(INT,cadr(n->ty)));
|
0
|
581 getsym();
|
|
582 break;
|
|
583 }
|
|
584 if((t=typespec())==0) {
|
|
585 error(DCERR);
|
|
586 break;
|
|
587 }
|
|
588 if(sym!=COMMA && sym!=RPAR) {
|
|
589 if(sym==RPAR) break;
|
|
590 type=t;
|
|
591 arg=decl0();
|
|
592 reverse(t);
|
|
593 if (arg != &null_nptr) { /* no varname typespec only */
|
|
594 def(arg);
|
|
595 }
|
|
596 }
|
16
|
597 rplacad(n->ty,glist2(t,cadr(n->ty)));
|
0
|
598 if(sym==RPAR) break;
|
|
599 }
|
|
600 if (sym!=COMMA) error(DCERR);
|
|
601 getsym();
|
|
602 }
|
|
603 checksym(RPAR);
|
16
|
604 mode=smode;
|
0
|
605 reg_var=sreg_var;
|
|
606 fnptr=sfnptr;
|
|
607 type=stype;
|
|
608 return;
|
|
609 }
|
|
610
|
|
611 void
|
|
612 reverse(int t1)
|
|
613 {
|
|
614 int t2,t3;
|
|
615 t2=t1;
|
|
616
|
|
617 while(type!=t1) {
|
|
618 t3=cadr(type);
|
|
619 rplacad(type,t2);
|
|
620 t2=type;
|
|
621 type=t3;
|
|
622 }
|
|
623 type = t2;
|
|
624 }
|
|
625
|
|
626 int
|
|
627 reverse0(int t1)
|
|
628 {
|
|
629 int t2,t3;
|
|
630
|
|
631 t2=0;
|
|
632 while(t1) {
|
|
633 t3=cadr(t1);
|
|
634 rplacad(t1,t2);
|
|
635 t2=t1;
|
|
636 t1=t3;
|
|
637 }
|
|
638 return t2;
|
|
639 }
|
|
640
|
|
641 int
|
|
642 size(int t)
|
|
643 {
|
|
644 if(t==CHAR) return 1;
|
|
645 if(t==VOID) return 0;
|
3
|
646 if(scalar(t)) return size_of_int;
|
0
|
647 if(car(t)==STRUCT||car(t)==UNION) {
|
|
648 if(cadr(t)==-1) error(DCERR);
|
|
649 return(cadr(t));
|
|
650 }
|
|
651 if(car(t)==ARRAY)
|
|
652 return(size(cadr(t))*caddr(t));
|
|
653 else
|
|
654 error(DCERR);
|
|
655 return 0;
|
|
656 }
|
|
657
|
|
658 void
|
|
659 def(NMTBL *n)
|
|
660 {
|
18
|
661 int sz,nsc,ndsp,t;
|
0
|
662
|
|
663 nsc=ndsp=0;
|
|
664 if(car(type)==FUNCTION) {
|
|
665 fcheck(n);
|
|
666 return;
|
|
667 }
|
|
668 if (n->sc!=EMPTY &&
|
|
669 !(n->sc==GVAR&&n->dsp==EXTRN) &&
|
|
670 !(n->sc==FUNCTION&&n->dsp==EXTRN) &&
|
|
671 (mode!=ADECL || n->sc!=LVAR || n->ty!=INT) &&
|
|
672 (mode!=ADECL || n->sc!=REGISTER || n->ty!=INT) &&
|
|
673 ((mode!=GSDECL&&mode!=LSDECL) || n->sc!=FIELD || n->dsp!=disp) &&
|
|
674 ((mode!=GUDECL&&mode!=LUDECL) || n->sc!=FIELD || n->dsp!=0) )
|
|
675 error(DCERR);
|
|
676 sz = size(n->ty = type);
|
|
677 switch(mode) {
|
|
678 case GDECL:
|
|
679 gen_gdecl(n->nm,gpc);
|
|
680 case STADECL:
|
|
681 nsc = GVAR;
|
|
682 ndsp = gpc;
|
|
683 if (stmode==EXTRN)
|
|
684 n->dsp = EXTRN;
|
|
685 else
|
|
686 n->dsp = ndsp; /* emit_data will override this */
|
|
687 n->sc = nsc;
|
|
688 if (stmode==LDECL) {
|
|
689 copy(n,n->nm);
|
|
690 cheapp[-1] = '.';
|
|
691 ndsp = ++stat_no;
|
|
692 while(ndsp>0) {
|
|
693 *cheapp++ = ndsp%10+'0';
|
|
694 ndsp /= 10;
|
|
695 }
|
|
696 *cheapp++ = 0;
|
|
697 }
|
|
698 if(sym==ASS) {
|
13
|
699 decl_data(type,n,0);
|
0
|
700 emit_data_closing(n);
|
|
701 /* gpc is incremented by emit_data */
|
|
702 } else
|
|
703 gpc +=sz;
|
|
704 return;
|
|
705 case GSDECL:
|
|
706 nsc = FIELD;
|
|
707 ndsp = disp;
|
|
708 disp += sz;
|
|
709 break;
|
|
710 case GUDECL:
|
|
711 nsc = FIELD;
|
|
712 ndsp = 0;
|
|
713 if (disp < sz) disp = sz;
|
|
714 break;
|
|
715 case GTDECL:
|
|
716 nsc = TYPE;
|
|
717 break;
|
|
718 case ADECL:
|
|
719 if (stmode==REGISTER && reg_var <MAX_REGISTER_VAR) {
|
|
720 if (type!=CHAR && !scalar(type))
|
|
721 error(TYERR);
|
2
|
722 nptr->sc = REGISTER;
|
0
|
723 reg_var++;
|
2
|
724 if (nptr->dsp==0) {
|
|
725 if ((nptr->dsp = get_register_var())<0) {
|
|
726 error(-1);
|
|
727 }
|
|
728 }
|
|
729 return;
|
0
|
730 }
|
|
731 nptr->sc = LVAR;
|
|
732 if(type==CHAR) {
|
|
733 /* nptr->ty=INT; */
|
|
734 if (nptr->dsp==0) {
|
|
735 nptr->dsp = args;
|
|
736 if (endian)
|
3
|
737 n->dsp += size_of_int-1;
|
0
|
738 }
|
3
|
739 args += size_of_int;
|
0
|
740 } else {
|
|
741 if (nptr->dsp==0)
|
|
742 nptr->dsp = args;
|
|
743 args += sz;
|
|
744 }
|
|
745 if(type==VOID) {
|
|
746 } else if (!scalar(type)) {
|
|
747 if((t=car(type))==STRUCT || t==UNION) {
|
|
748 nptr->ty = type;
|
|
749 } else
|
|
750 error(TYERR);
|
|
751 }
|
|
752 return;
|
|
753 case LDECL:
|
|
754 if (stmode==REGISTER && reg_var <=MAX_REGISTER_VAR) {
|
|
755 if(!scalar(type)) /* non integer register type ... */
|
|
756 error(DCERR);
|
|
757 nsc = REGISTER;
|
|
758 reg_var++;
|
2
|
759 if ((ndsp = get_register_var())<0)
|
|
760 error(-1);
|
0
|
761 } else {
|
|
762 nsc = LVAR;
|
|
763 ndsp = (disp -= sz);
|
|
764 }
|
14
|
765 n->sc = nsc;
|
|
766 n->dsp = ndsp;
|
0
|
767 if(sym==ASS) {
|
13
|
768 decl_data(type,n,0);
|
0
|
769 }
|
13
|
770 return;
|
0
|
771 case LSDECL:
|
|
772 nsc = FIELD;
|
|
773 ndsp = disp;
|
|
774 disp += sz;
|
|
775 break;
|
|
776 case LUDECL:
|
|
777 nsc = FIELD;
|
|
778 ndsp = 0;
|
|
779 if (disp < sz) disp = sz;
|
|
780 break;
|
|
781 case LTDECL:
|
|
782 nsc = TYPE;
|
|
783 break;
|
|
784 default:
|
|
785 error(DCERR);
|
|
786 }
|
|
787 n->sc = nsc;
|
|
788 if (stmode==EXTRN)
|
|
789 n->dsp = EXTRN;
|
|
790 else
|
|
791 n->dsp = ndsp;
|
|
792 }
|
|
793
|
|
794 void
|
|
795 emit_init_vars(void)
|
|
796 {
|
13
|
797 if (!init_vars) return;
|
|
798 init_vars = reverse0(init_vars);
|
0
|
799 while(init_vars) {
|
|
800 g_expr(car(init_vars));
|
|
801 init_vars = cadr(init_vars);
|
|
802 }
|
|
803 }
|
|
804
|
13
|
805 int
|
|
806 assign_data(int e, int t, NMTBL *n,int offset)
|
0
|
807 {
|
|
808 int ass;
|
|
809
|
|
810 if(mode==GDECL) {
|
13
|
811 emit_data(e,t,n);
|
|
812 return offset+size(t);
|
0
|
813 } else if(mode==LDECL) {
|
13
|
814 if(t==CHAR) {
|
|
815 ass =list3(CASS,list2(LVAR,n->dsp+offset),e);
|
|
816 } else if (scalar(t)) {
|
|
817 ass = list3(ASS,list2(LVAR,n->dsp+offset),e);
|
|
818 } else if (car(t)==STRUCT || car(t)==UNION || car(t)==STRING) {
|
14
|
819 ass = list4(SASS,list2(LVAR,n->dsp+offset),e,size(t));
|
0
|
820 } else {
|
13
|
821 error(DCERR);
|
0
|
822 }
|
|
823 init_vars = list2(ass,init_vars);
|
13
|
824 return offset+size(t);
|
0
|
825 } else {
|
|
826 error(DCERR);
|
|
827 }
|
18
|
828 return 0; /* not reached */
|
0
|
829 }
|
|
830
|
13
|
831 int
|
|
832 decl_data(int t, NMTBL *n,int offset)
|
0
|
833 {
|
13
|
834 int t1,e,i;
|
0
|
835
|
|
836 getsym();
|
|
837 if (scalar(t)) {
|
|
838 e=expr1();
|
|
839 if(car(e)!=CONST && t==CHAR)
|
|
840 error(TYERR);
|
13
|
841 offset = assign_data(e,t,n,offset);
|
0
|
842 type=t;
|
13
|
843 return offset;
|
0
|
844 }
|
|
845 t1 = car(t);
|
|
846 if (t1==ARRAY) {
|
|
847 if (sym==LC) {
|
|
848 t1 = cadr(t);
|
|
849 for(i=0;;i++) {
|
|
850 if (sym!=RC)
|
13
|
851 offset=decl_data(t1,n,offset);
|
0
|
852 if (sym==COMMA) { continue;
|
|
853 } else if (sym==RC) {
|
13
|
854 if (caddr(t)==0) { /* size not defined */
|
|
855 heap[t+2]=i+1; /* define array size */
|
|
856 } else if (caddr(t)!=i+1) { /* size match? */
|
0
|
857 error(TYERR);
|
|
858 }
|
|
859 getsym();
|
13
|
860 return offset;
|
0
|
861 } else {
|
|
862 error(TYERR);
|
|
863 }
|
|
864 }
|
|
865 } else if (cadr(t)==CHAR) {
|
|
866 e=expr1();
|
|
867 if(car(e)!=STRING)
|
|
868 error(TYERR);
|
13
|
869 offset=assign_data(e,list3(ARRAY,CHAR,size(type)),n,offset);
|
|
870 if (caddr(t)==0) { /* size not defined */
|
|
871 heap[t+2]=size(type); /* define array size */
|
|
872 } else if (caddr(t)!=size(type)) { /* size match? */
|
|
873 error(TYERR);
|
|
874 }
|
0
|
875 } else
|
|
876 error(DCERR);
|
|
877 } else if (t1==STRUCT) {
|
|
878 if(cadr(t)==-1) error(DCERR);
|
|
879 t1 = caddr(t); /* list of fields */
|
|
880 while(t1) {
|
13
|
881 offset = decl_data(car(t1),n,offset); /* alignment? */
|
0
|
882 t1 = cadr(t1);
|
|
883 if ( t1 && sym==COMMA) continue;
|
|
884 if (!t1 && sym!=RC) error(DCERR);
|
|
885 }
|
|
886 getsym();
|
18
|
887 return offset;
|
0
|
888 } else {
|
|
889 error(TYERR); /* should be initialization error */
|
|
890 }
|
18
|
891 return offset; /* not reached */
|
0
|
892 }
|
|
893
|
|
894 int
|
|
895 sdecl(int s)
|
|
896 {
|
18
|
897 int smode,sdisp,type0;
|
0
|
898 NMTBL *nptr0,*gnptr0;
|
|
899 int tags;
|
|
900
|
|
901 smode=mode;
|
|
902 if (mode==GDECL || mode==GSDECL || mode==GUDECL || mode==GTDECL)
|
|
903 mode=(s==STRUCT?GSDECL:GUDECL);
|
|
904 else
|
|
905 mode=(s==STRUCT?LSDECL:LUDECL);
|
|
906 sdisp=disp;
|
|
907 disp=0;
|
|
908 if (getsym() == IDENT) {
|
|
909 nptr0 = nptr;
|
|
910 gnptr0 = gnptr;
|
|
911 if (getsym() == LC) {
|
|
912 if (nptr0->sc != EMPTY) error(DCERR);
|
|
913 nptr0->sc = TAG;
|
|
914 tags = 0;
|
|
915 nptr0->ty = list3(s,-1,tags);
|
|
916 while (getsym() != RC) {
|
|
917 decl();
|
|
918 tags = list2(type,tags);
|
|
919 }
|
|
920 getsym();
|
|
921 tags=reverse0(tags);
|
|
922 heap[nptr0->ty+2]=tags;
|
|
923 rplacad(type0 = nptr0->ty,disp);
|
|
924 } else {
|
13
|
925 /* struct tag name */
|
0
|
926 if(nptr0->sc == EMPTY) nptr0=gnptr0;
|
|
927 if(nptr0->sc == EMPTY) error(UDERR);
|
|
928 if(nptr0->sc != TAG) error(TYERR);
|
13
|
929 tags = caddr(nptr0->ty);
|
|
930 disp = cadr(nptr0->ty);
|
0
|
931 }
|
13
|
932 type0 = list3(s,disp,tags);
|
0
|
933 } else if(sym==LC) {
|
|
934 tags = 0;
|
|
935 while(getsym() != RC) {
|
|
936 decl();
|
|
937 tags = list2(type,tags);
|
|
938 }
|
|
939 getsym();
|
|
940 tags=reverse0(tags);
|
|
941 type0 = list3(s,disp,tags);
|
|
942 }
|
|
943 else error(DCERR);
|
|
944 disp=sdisp;
|
|
945 mode=smode;
|
|
946 return type0;
|
|
947 }
|
|
948
|
|
949 void
|
|
950 code_decl(NMTBL *n)
|
|
951 {
|
3
|
952 int odisp;
|
|
953
|
0
|
954 if (n->sc==EMPTY) n->sc = CODE;
|
|
955 code_enter(n->nm);
|
|
956 fnptr=n;
|
3
|
957 disp = -args;
|
|
958 args = 0;
|
0
|
959 reg_var=0;
|
|
960 mode=ADECL;
|
|
961 stmode=REGISTER;
|
|
962 while (sym!=LC) { /* argument declaration !ANSI */
|
|
963 decl(); getsym();
|
|
964 }
|
3
|
965 if (args) disp = -args;
|
|
966 else args = -disp;
|
0
|
967 init_vars=0;
|
|
968 /* local variable declaration */
|
|
969 stmode=0;
|
|
970 mode=STAT;
|
|
971 init_vars=0;
|
3
|
972 odisp=disp;
|
0
|
973 while (typeid(getsym()) || sym==STATIC || sym==EXTRN || sym==TYPEDEF) {
|
|
974 mode=LDECL;
|
|
975 decl();
|
|
976 mode=STAT;
|
|
977 }
|
|
978 control=1;
|
3
|
979 code_enter1(disp-odisp,args);
|
0
|
980 emit_init_vars();
|
|
981 while(sym!=RC) statement();
|
|
982 if(control)
|
|
983 error(STERR);
|
|
984 control=0;
|
|
985 code_leave(n->nm);
|
|
986 }
|
|
987
|
|
988 void
|
|
989 fdecl(NMTBL *n)
|
|
990 {
|
|
991 enter(n->nm);
|
|
992 fnptr=n;
|
|
993 retlabel=fwdlabel();
|
|
994 retcont = 0;
|
|
995
|
|
996 args=0;
|
|
997 reg_var=0;
|
|
998 fcheck(n);
|
|
999 mode=ADECL;
|
|
1000 while (sym!=LC) { /* argument declaration !ANSI */
|
|
1001 stmode=0;
|
|
1002 decl(); getsym();
|
|
1003 }
|
|
1004 disp=0;
|
|
1005 init_vars=0;
|
|
1006 /* local variable declaration */
|
|
1007 mode=STAT;
|
|
1008 while (typeid(getsym()) || sym==STATIC || sym==EXTRN
|
|
1009 || sym==REGISTER || sym==TYPEDEF) {
|
|
1010 mode=LDECL;
|
|
1011 stmode=0;
|
|
1012 decl();
|
|
1013 mode=STAT;
|
|
1014 }
|
|
1015 control=1;
|
|
1016 enter1(disp);
|
|
1017 emit_init_vars();
|
|
1018 while(sym!=RC) statement();
|
|
1019
|
|
1020 leave(control,n->nm);
|
|
1021 retpending = 0;
|
|
1022 control=0;
|
|
1023 }
|
|
1024
|
|
1025 void
|
|
1026 fcheck(NMTBL *n)
|
|
1027 {
|
|
1028 if(mode!=GDECL||car(type)!=FUNCTION) error(DCERR);
|
|
1029 if(n->sc==FUNCTION) compatible(car(n->ty),cadr(type));
|
|
1030 else {
|
|
1031 if(n->sc!=EMPTY)
|
|
1032 error(DCERR);
|
|
1033 else {
|
|
1034 n->sc=FUNCTION;
|
7
|
1035 n->ty=glist2(cadr(type),0);
|
0
|
1036 }
|
|
1037 }
|
|
1038 }
|
|
1039
|
|
1040 void
|
|
1041 compatible(int t1, int t2)
|
|
1042 {
|
|
1043 if(integral(t1)) {
|
|
1044 if(t1!=t2) error(TYERR);
|
|
1045 }
|
|
1046 else if(car(t1)!=car(t2))
|
|
1047 error(TYERR);
|
|
1048 else if((car(t1)==STRUCT || car(t1)==UNION) && cadr(t1)!=cadr(t2))
|
|
1049 error(TYERR);
|
|
1050 else if(car(t1)==POINTER || car(t1)==ARRAY ||car(t1)==FUNCTION)
|
|
1051 compatible(cadr(t1),cadr(t2));
|
|
1052 }
|
|
1053
|
|
1054 int
|
|
1055 scalar(int t)
|
|
1056 {
|
|
1057 return(integral(t)||car(t)==POINTER);
|
|
1058 }
|
|
1059
|
|
1060 int
|
|
1061 integral(int t)
|
|
1062 {
|
|
1063 return(t==INT||t==CHAR||t==UNSIGNED);
|
|
1064 }
|
|
1065
|
|
1066 void
|
|
1067 checkret(void)
|
|
1068 {
|
|
1069 if (retpending) {
|
|
1070 ret();
|
|
1071 control=0;
|
|
1072 retpending=0;
|
|
1073 }
|
|
1074 }
|
|
1075
|
|
1076 void
|
|
1077 statement(void)
|
|
1078 {
|
|
1079 int slfree;
|
|
1080
|
|
1081 if(sym==SM) {
|
|
1082 getsym(); return;
|
|
1083 }
|
|
1084 checkret();
|
|
1085 switch(sym) {
|
|
1086 case IF:
|
|
1087 doif();
|
|
1088 return;
|
|
1089 case WHILE:
|
|
1090 dowhile();
|
|
1091 return;
|
|
1092 case DO:
|
|
1093 dodo();
|
|
1094 return;
|
|
1095 case FOR:
|
|
1096 dofor();
|
|
1097 return;
|
|
1098 case SWITCH:
|
|
1099 doswitch();
|
|
1100 return;
|
|
1101 case LC:
|
|
1102 docomp();
|
|
1103 return;
|
|
1104 case BREAK:
|
|
1105 jmp(blabel);
|
|
1106 getsym();
|
|
1107 checksym(SM);
|
|
1108 return;
|
|
1109 case CONTINUE:
|
|
1110 jmp(clabel);
|
|
1111 getsym();
|
|
1112 checksym(SM);
|
|
1113 return;
|
|
1114 case CASE:
|
|
1115 docase();
|
|
1116 statement();
|
|
1117 return;
|
|
1118 case DEFAULT:
|
|
1119 dodefault();
|
|
1120 statement();
|
|
1121 return;
|
|
1122 case RETURN:
|
|
1123 doreturn();
|
|
1124 return;
|
|
1125 case GOTO:
|
|
1126 dogoto();
|
|
1127 return;
|
|
1128 default:
|
|
1129 if(sym==IDENT&&skipspc()==':') {
|
|
1130 dolabel();
|
|
1131 statement();
|
|
1132 } else {
|
|
1133 slfree=lfree;
|
|
1134 gexpr(expr());
|
|
1135 lfree=slfree;
|
|
1136 checksym(SM);
|
|
1137 }
|
|
1138 }
|
|
1139 }
|
|
1140
|
|
1141 void
|
|
1142 doif(void)
|
|
1143 {
|
|
1144 int l1,l2,slfree;
|
|
1145 getsym();
|
|
1146 checksym(LPAR);
|
|
1147 slfree=lfree;
|
|
1148 bexpr(expr(),0,l1=fwdlabel());
|
|
1149 lfree=slfree;
|
|
1150 checksym(RPAR);
|
|
1151 statement();
|
|
1152 checkret();
|
|
1153 if(sym==ELSE) {
|
|
1154 if ((l2 = control))
|
|
1155 jmp(l2=fwdlabel());
|
|
1156 fwddef(l1);
|
|
1157 getsym();
|
|
1158 statement();
|
|
1159 checkret();
|
|
1160 if (l2) fwddef(l2);
|
|
1161 }
|
|
1162 else fwddef(l1);
|
|
1163 }
|
|
1164
|
|
1165 void
|
|
1166 dowhile(void)
|
|
1167 {
|
|
1168 int sbreak,scontinue,slfree,e;
|
|
1169
|
|
1170 sbreak=blabel;
|
|
1171 scontinue=clabel;
|
|
1172 blabel=fwdlabel();
|
|
1173 clabel=backdef();
|
|
1174 getsym();
|
|
1175 checksym(LPAR);
|
|
1176 slfree=lfree;
|
|
1177 e=expr();
|
|
1178 checksym(RPAR);
|
|
1179 if(sym==SM) {
|
|
1180 bexpr(e,1,clabel);
|
|
1181 lfree=slfree;
|
|
1182 getsym();
|
|
1183 } else {
|
|
1184 bexpr(e,0,blabel);
|
|
1185 lfree=slfree;
|
|
1186 statement();
|
|
1187 checkret();
|
|
1188 if(control)
|
|
1189 jmp(clabel);
|
|
1190 }
|
|
1191 fwddef(blabel);
|
|
1192 clabel=scontinue;
|
|
1193 blabel=sbreak;
|
|
1194 }
|
|
1195
|
|
1196 void
|
|
1197 dodo(void)
|
|
1198 {
|
|
1199 int sbreak,scontinue,l,slfree;
|
|
1200
|
|
1201 sbreak=blabel;
|
|
1202 scontinue=clabel;
|
|
1203 blabel=fwdlabel();
|
|
1204 clabel=fwdlabel();
|
|
1205 l=backdef();
|
|
1206 getsym();
|
|
1207 statement();
|
|
1208 checkret();
|
|
1209 fwddef(clabel);
|
|
1210 checksym(WHILE);
|
|
1211 checksym(LPAR);
|
|
1212 slfree=lfree;
|
|
1213 bexpr(expr(),1,l);
|
|
1214 lfree=slfree;
|
|
1215 checksym(RPAR);
|
|
1216 checksym(SM);
|
|
1217 fwddef(blabel);
|
|
1218 clabel=scontinue;
|
|
1219 blabel=sbreak;
|
|
1220 }
|
|
1221
|
|
1222 void
|
|
1223 dofor(void)
|
|
1224 {
|
|
1225 int sbreak,scontinue,l,e,slfree;
|
|
1226
|
|
1227 sbreak=blabel;
|
|
1228 scontinue=clabel;
|
|
1229 blabel=fwdlabel();
|
|
1230 getsym();
|
|
1231 checksym(LPAR);
|
|
1232 slfree=lfree;
|
|
1233 if(sym!=SM) {
|
|
1234 gexpr(expr());
|
|
1235 checksym(SM);
|
|
1236 }
|
|
1237 else getsym();
|
|
1238 lfree=slfree;
|
|
1239 l=backdef();
|
|
1240 if(sym!=SM) {
|
|
1241 bexpr(expr(),0,blabel);
|
|
1242 checksym(SM);
|
|
1243 }
|
|
1244 else getsym();
|
|
1245 lfree=slfree;
|
|
1246 if(sym==RPAR) {
|
|
1247 clabel=l;
|
|
1248 getsym();
|
|
1249 statement();
|
|
1250 checkret();
|
|
1251 } else {
|
|
1252 clabel=fwdlabel();
|
|
1253 e=expr();
|
|
1254 checksym(RPAR);
|
|
1255 statement();
|
|
1256 checkret();
|
|
1257 fwddef(clabel);
|
|
1258 gexpr(e);
|
|
1259 lfree=slfree;
|
|
1260 }
|
|
1261 jmp(l);
|
|
1262 fwddef(blabel);
|
|
1263 clabel=scontinue;
|
|
1264 blabel=sbreak;
|
|
1265 }
|
|
1266
|
|
1267 void
|
|
1268 doswitch(void)
|
|
1269 {
|
|
1270 int sbreak,scase,sdefault,slfree,svalue;
|
|
1271
|
|
1272 sbreak=blabel; /* save parents break label */
|
|
1273 blabel=fwdlabel();
|
|
1274 sdefault=dlabel; /* save parents default label */
|
|
1275 dlabel=0;
|
|
1276 scase=cslabel; /* save parents next case label */
|
|
1277 getsym();
|
|
1278 checksym(LPAR);
|
|
1279 slfree=lfree;
|
|
1280 svalue=csvalue1; /* save parents switch value */
|
|
1281 gexpr(expr());
|
|
1282 csvalue1=csvalue ;
|
|
1283 lfree=slfree;
|
|
1284 checksym(RPAR);
|
|
1285 cslabel = control = 0;
|
|
1286 /* should be case statement but... */
|
|
1287 statement();
|
|
1288 checkret();
|
|
1289 if(dlabel) def_label(cslabel,dlabel);
|
|
1290 else fwddef(cslabel);
|
|
1291 csvalue1=svalue;
|
|
1292 cslabel=scase;
|
|
1293 dlabel=sdefault;
|
|
1294 fwddef(blabel);
|
|
1295 blabel=sbreak;
|
|
1296 }
|
|
1297
|
|
1298 void
|
|
1299 docomp(void)
|
|
1300 {
|
|
1301 getsym();
|
|
1302 while(sym!=RC) { statement(); checkret();}
|
|
1303 getsym();
|
|
1304 }
|
|
1305
|
|
1306 void
|
|
1307 docase(void)
|
|
1308 {
|
|
1309 int c,l,slfree;
|
|
1310
|
|
1311 c=0;
|
|
1312 slfree=lfree;
|
|
1313 while(sym==CASE) {
|
|
1314 getsym();
|
|
1315 c=list2(cexpr(expr()),c);
|
|
1316 checksym(COLON);
|
|
1317 }
|
|
1318 l=fwdlabel();
|
|
1319 if (control) {
|
|
1320 control=0;
|
|
1321 jmp(l);
|
|
1322 }
|
|
1323 if (cslabel) fwddef(cslabel);
|
|
1324 while(cadr(c)) {
|
|
1325 cmpdimm(car(c),csvalue1);
|
|
1326 jcond(l,0);
|
|
1327 c=cadr(c);
|
|
1328 }
|
|
1329 lfree=slfree;
|
|
1330 cmpdimm(car(c),csvalue1);
|
|
1331 jcond(cslabel=fwdlabel(),1);
|
|
1332 fwddef(l);
|
|
1333 }
|
|
1334
|
|
1335 void
|
|
1336 dodefault(void)
|
|
1337 {
|
|
1338 getsym();
|
|
1339 checksym(COLON);
|
|
1340 if (dlabel) error(STERR);
|
|
1341 if (!cslabel) jmp(cslabel = fwdlabel());
|
|
1342 dlabel = backdef();
|
|
1343 }
|
|
1344
|
|
1345 void
|
|
1346 doreturn(void)
|
|
1347 {
|
|
1348 int slfree;
|
|
1349
|
|
1350 if(getsym()==SM) {
|
|
1351 getsym();
|
|
1352 retpending = 1;
|
|
1353 return;
|
|
1354 }
|
|
1355 slfree=lfree;
|
|
1356 gexpr(expr());
|
|
1357 lfree=slfree;
|
|
1358 checksym(SM);
|
|
1359 retpending = 1;
|
|
1360 }
|
|
1361
|
|
1362
|
|
1363 void
|
|
1364 dogoto(void)
|
|
1365 {
|
|
1366 NMTBL *nptr0;
|
|
1367 int t,e1,e2,env;
|
|
1368
|
|
1369 getsym();
|
|
1370 e1 = expr();
|
|
1371 t=car(e1);
|
|
1372 if (t==FNAME) {
|
|
1373 nptr0 = (NMTBL *)cadr(e1);
|
|
1374 t = nptr0->sc;
|
|
1375 if (t==EMPTY) {
|
|
1376 nptr0->sc = FLABEL;
|
|
1377 jmp(nptr0->dsp = fwdlabel());
|
|
1378 } else if (t==FLABEL||t==BLABEL) {
|
|
1379 jmp(nptr0->dsp);
|
|
1380 }
|
|
1381 control=0;
|
|
1382 checksym(SM);
|
|
1383 return;
|
|
1384 }
|
|
1385 if (t==COMMA) {
|
|
1386 env = caddr(e1);
|
|
1387 e1 = cadr(e1);
|
|
1388 t = car(e1);
|
|
1389 } else {
|
|
1390 env = 0;
|
|
1391 }
|
|
1392 if (t==FUNCTION) {
|
|
1393 e2 = cadr(e1);
|
|
1394 if (car(e2) == FNAME) {
|
|
1395 nptr0=(NMTBL *)cadr(e2);
|
|
1396 nptr0->sc = CODE;
|
|
1397 }
|
|
1398 gexpr(list3(CODE,e1,env));
|
|
1399 control=0;
|
|
1400 checksym(SM);
|
|
1401 return;
|
|
1402 }
|
|
1403 error(STERR);
|
|
1404 return;
|
|
1405 }
|
|
1406
|
|
1407 void
|
|
1408 dolabel(void)
|
|
1409 {
|
|
1410 if(nptr->sc == FLABEL)
|
|
1411 fwddef(nptr->dsp);
|
|
1412 else if(nptr->sc != EMPTY)
|
|
1413 error(TYERR);
|
|
1414 nptr->sc = BLABEL;
|
|
1415 nptr->dsp = backdef();
|
|
1416 getsym();
|
|
1417 checksym(COLON);
|
|
1418 }
|
|
1419
|
|
1420 int
|
|
1421 expr(void)
|
|
1422 {
|
|
1423 return(rvalue(expr0()));
|
|
1424 }
|
|
1425
|
|
1426 int
|
|
1427 expr0(void)
|
|
1428 {
|
|
1429 int e;
|
|
1430
|
|
1431 e=expr1();
|
|
1432 while(sym==COMMA) {
|
|
1433 getsym();e=list3(COMMA,e,rvalue(expr1()));
|
|
1434 }
|
|
1435 return e;
|
|
1436 }
|
|
1437
|
|
1438 int
|
|
1439 expr1(void)
|
|
1440 {
|
|
1441 int e1,e2,t,op;
|
|
1442 e1=expr2();
|
|
1443 switch (sym) {
|
|
1444 case ASS:
|
|
1445 lcheck(e1);
|
|
1446 t=type;
|
|
1447 getsym();
|
|
1448 e2=rvalue(expr1());
|
|
1449 if(t==VOID)
|
|
1450 error(TYERR);
|
|
1451 if(t==CHAR) {
|
|
1452 type= INT;return(list3(CASS,e1,e2));
|
14
|
1453 } else if(!scalar(t)&&(car(t)==STRUCT||car(t)==UNION)) {
|
|
1454 type= t;return(list4(SASS,e1,e2,size(t)));
|
0
|
1455 }
|
|
1456 type=t;
|
|
1457 return(list3(ASS,e1,e2));
|
|
1458 case ADD+AS: case SUB+AS: case MUL+AS: case DIV+AS: case MOD+AS:
|
|
1459 case RSHIFT+AS: case LSHIFT+AS: case BAND+AS: case EOR+AS: case BOR+AS:
|
|
1460 op = sym-AS;
|
|
1461 lcheck(e1);
|
|
1462 t=type;
|
|
1463 getsym();
|
|
1464 e2=rvalue(expr1());
|
|
1465 if(!integral(type)) error(TYERR);
|
|
1466 if((t==UNSIGNED||type==UNSIGNED)&&
|
|
1467 (op==MUL||op==DIV||op==MOD||op==RSHIFT||op==LSHIFT))
|
|
1468 op=op+US;
|
|
1469 if(t==CHAR) {
|
|
1470 type= INT;
|
|
1471 return(list4(CASSOP,e1,e2,op));
|
|
1472 }
|
|
1473 type=t;
|
|
1474 if(integral(t)) return(list4(ASSOP,e1,e2,op));
|
|
1475 if((op!=ADD&&op!=SUB)||car(t)!=POINTER) error(TYERR);
|
|
1476 e2=binop(MUL,e2,list2(CONST,size(cadr(t))),INT,UNSIGNED);
|
|
1477 type=t;
|
|
1478 return list4(ASSOP,e1,e2,op);
|
|
1479 default:
|
|
1480 return(e1);
|
|
1481 }
|
|
1482 }
|
|
1483
|
|
1484 int
|
|
1485 expr2(void)
|
|
1486 {
|
|
1487 int e1,e2,e3,t;
|
|
1488
|
|
1489 e1=expr3();
|
|
1490 if(sym==COND) {
|
|
1491 e1=rvalue(e1);
|
|
1492 getsym();
|
|
1493 e2=rvalue(expr2());
|
|
1494 t=type;
|
|
1495 checksym(COLON);
|
|
1496 e3=rvalue(expr2());
|
|
1497 if(car(e1)==CONST) {
|
|
1498 if(cadr(e1)) {
|
|
1499 type=t;return e2;
|
|
1500 } else
|
|
1501 return e3;
|
|
1502 }
|
|
1503 if(type==INT||(t!=INT&&type==UNSIGNED))
|
|
1504 type=t;
|
|
1505 return(list4(COND,e1,e2,e3));
|
|
1506 }
|
|
1507 return(e1);
|
|
1508 }
|
|
1509
|
|
1510 int
|
|
1511 expr3(void)
|
|
1512 {
|
|
1513 int e;
|
|
1514
|
|
1515 e=expr4();
|
|
1516 while(sym==LOR) {
|
|
1517 e=rvalue(e);
|
|
1518 getsym();
|
|
1519 e=list3(LOR,e,rvalue(expr4()));
|
|
1520 type= INT;
|
|
1521 }
|
|
1522 return(e);
|
|
1523 }
|
|
1524
|
|
1525 int
|
|
1526 expr4(void)
|
|
1527 {
|
|
1528 int e;
|
|
1529
|
|
1530 e=expr5();
|
|
1531 while(sym==LAND) {
|
|
1532 e=rvalue(e);
|
|
1533 getsym();
|
|
1534 e=list3(LAND,e,rvalue(expr5()));
|
|
1535 type= INT;
|
|
1536 }
|
|
1537 return(e);
|
|
1538 }
|
|
1539
|
|
1540 int
|
|
1541 expr5(void)
|
|
1542 {
|
|
1543 int e1,e2,t;
|
|
1544
|
|
1545 e1=expr6();
|
|
1546 while(sym==BOR) {
|
|
1547 e1=rvalue(e1);
|
|
1548 t=type;
|
|
1549 getsym();
|
|
1550 e2=rvalue(expr6());
|
|
1551 e1=binop(BOR,e1,e2,t,type);
|
|
1552 }
|
|
1553 return(e1);
|
|
1554 }
|
|
1555
|
|
1556 int
|
|
1557 expr6(void)
|
|
1558 {
|
|
1559 int e1,e2,t;
|
|
1560
|
|
1561 e1=expr7();
|
|
1562 while(sym==EOR) {
|
|
1563 e1=rvalue(e1);
|
|
1564 t=type;
|
|
1565 getsym();
|
|
1566 e2=rvalue(expr7());
|
|
1567 e1=binop(EOR,e1,e2,t,type);
|
|
1568 }
|
|
1569 return(e1);
|
|
1570 }
|
|
1571
|
|
1572 int
|
|
1573 expr7(void)
|
|
1574 {
|
|
1575 int e1,e2,t;
|
|
1576
|
|
1577 e1=expr8();
|
|
1578 while(sym==BAND) {
|
|
1579 e1=rvalue(e1);
|
|
1580 t=type;
|
|
1581 getsym();
|
|
1582 e2=rvalue(expr8());
|
|
1583 e1=binop(BAND,e1,e2,t,type);
|
|
1584 }
|
|
1585 return(e1);
|
|
1586 }
|
|
1587
|
|
1588 int
|
|
1589 expr8(void)
|
|
1590 {
|
|
1591 int e,op;
|
|
1592
|
|
1593 e=expr9();
|
|
1594 while((op=sym)==EQ||op==NEQ) {
|
|
1595 e=rvalue(e);
|
|
1596 getsym();
|
|
1597 e=list3(op,e,rvalue(expr9()));
|
|
1598 type= INT;
|
|
1599 }
|
|
1600 return e;
|
|
1601 }
|
|
1602
|
|
1603 int
|
|
1604 expr9(void)
|
|
1605 {
|
|
1606 int e1,e2,t,op;
|
|
1607
|
|
1608 e1=expr10();
|
|
1609 while((op=sym)==GT||op==GE||op==LT||op==LE) {
|
|
1610 e1=rvalue(e1);
|
|
1611 t=type;
|
|
1612 getsym();
|
|
1613 e2=rvalue(expr10());
|
|
1614 if(t==INT&&type==INT)
|
|
1615 e1=list3(op,e1,e2);
|
|
1616 else
|
|
1617 e1=list3(op+US,e1,e2);
|
|
1618 type= INT;
|
|
1619 }
|
|
1620 return e1;
|
|
1621 }
|
|
1622
|
|
1623 int
|
|
1624 expr10(void)
|
|
1625 {
|
|
1626 int e1,e2,t,op;
|
|
1627
|
|
1628 e1=expr11();
|
|
1629 while((op=sym)==RSHIFT||op==LSHIFT) {
|
|
1630 e1=rvalue(e1);
|
|
1631 t=type;
|
|
1632 getsym();
|
|
1633 e2=rvalue(expr11());
|
|
1634 e1=binop(op,e1,e2,t,type);
|
|
1635 }
|
|
1636 return e1;
|
|
1637 }
|
|
1638
|
|
1639 int
|
|
1640 expr11(void)
|
|
1641 {
|
|
1642 int e1,e2,t,op;
|
|
1643
|
|
1644 e1=expr12();
|
|
1645 while((op=sym)==ADD||op==SUB) {
|
|
1646 e1=rvalue(e1);
|
|
1647 t=type;
|
|
1648 getsym();
|
|
1649 e2=rvalue(expr12());
|
|
1650 e1=binop(op,e1,e2,t,type);
|
|
1651 }
|
|
1652 return e1;
|
|
1653 }
|
|
1654
|
|
1655 int
|
|
1656 expr12(void)
|
|
1657 {
|
|
1658 int e1,e2,t,op;
|
|
1659
|
|
1660 e1=expr13();
|
|
1661 while((op=sym)==MUL||op==DIV||op==MOD) {
|
|
1662 e1=rvalue(e1);
|
|
1663 t=type;
|
|
1664 getsym();
|
|
1665 e2=rvalue(expr13());
|
|
1666 e1=binop(op,e1,e2,t,type);
|
|
1667 }
|
|
1668 return e1;
|
|
1669 }
|
|
1670
|
|
1671 int
|
|
1672 expr13(void)
|
|
1673 {
|
|
1674 int e,op;
|
|
1675
|
|
1676 switch (op = sym) {
|
|
1677 case INC: case DEC:
|
|
1678 getsym();
|
|
1679 lcheck(e=expr13());
|
|
1680 if(type==CHAR) {
|
|
1681 type= INT;
|
|
1682 return(list2(op==INC?CPREINC:CPREDEC,e));
|
|
1683 }
|
|
1684 if(integral(type))
|
|
1685 return(list3(PREINC,e,op==INC?1:-1));
|
|
1686 if(car(type)!=POINTER)
|
|
1687 error(TYERR);
|
|
1688 return(list3(PREINC,e,
|
|
1689 op==INC?size(cadr(type)):-size(cadr(type)) ));
|
|
1690 case MUL:
|
|
1691 getsym();
|
|
1692 e=rvalue(expr13());
|
|
1693 return(indop(e));
|
|
1694 case BAND:
|
|
1695 getsym();
|
|
1696 switch(car(e=expr13())) {
|
|
1697 case INDIRECT:
|
|
1698 e=cadr(e);
|
|
1699 break;
|
|
1700 case GVAR:
|
|
1701 case LVAR:
|
|
1702 e=list2(ADDRESS,e);
|
|
1703 break;
|
|
1704 case FNAME:
|
|
1705 return e;
|
|
1706 default:error(LVERR);
|
|
1707 }
|
|
1708 type=list2(POINTER,type);
|
|
1709 return e;
|
|
1710 case SUB:
|
|
1711 getsym();
|
|
1712 e=rvalue(expr13());
|
|
1713 if(!integral(type))
|
|
1714 error(TYERR);
|
|
1715 return(car(e)==CONST?list2(CONST,-cadr(e)):list2(MINUS,e));
|
|
1716 case BNOT:
|
|
1717 getsym();
|
|
1718 e=rvalue(expr13());
|
|
1719 if(!integral(type))
|
|
1720 error(TYERR);
|
|
1721 return(car(e)==CONST?list2(CONST,~cadr(e)):list2(BNOT,e));
|
|
1722 case LNOT:
|
|
1723 getsym();
|
19
|
1724 e=rvalue(expr13());
|
20
|
1725 if(!scalar(type))
|
19
|
1726 error(TYERR);
|
|
1727 return(car(e)==CONST?list2(CONST,!cadr(e)):list2(LNOT,e));
|
0
|
1728 case SIZEOF:
|
|
1729 if(getsym()==LPAR) {
|
|
1730 if(typeid(getsym())) {
|
|
1731 e=list2(CONST,size(typename()));
|
|
1732 type=INT;
|
|
1733 checksym(RPAR);
|
|
1734 return e;
|
|
1735 } else {
|
|
1736 e=expr0();
|
|
1737 checksym(RPAR);
|
|
1738 expr16(e);
|
|
1739 if(sym==INC||sym==DEC) {
|
|
1740 getsym();
|
|
1741 if(type==CHAR) type=INT;
|
|
1742 else if(!scalar(type))
|
|
1743 error(TYERR);
|
|
1744 }
|
|
1745 }
|
|
1746 } else
|
|
1747 expr13();
|
|
1748 e=list2(CONST,size(type));
|
|
1749 type=INT;
|
|
1750 return e;
|
|
1751 }
|
|
1752 e=expr14();
|
|
1753 if((op=sym)==INC||op==DEC) {
|
|
1754 lcheck(e);
|
|
1755 getsym();
|
|
1756 if(type==CHAR) {
|
|
1757 type= INT;
|
|
1758 return(list2(op==INC?CPOSTINC:CPOSTDEC,e));
|
|
1759 }
|
|
1760 if(integral(type))
|
|
1761 return(list3(POSTINC,e,op==INC?1:-1));
|
|
1762 if(car(type)!=POINTER)
|
|
1763 error(TYERR);
|
|
1764 return (list3(POSTINC,e,
|
|
1765 op == INC ? size(cadr(type)): -size(cadr(type)) ));
|
|
1766 }
|
|
1767 return e;
|
|
1768 }
|
|
1769
|
|
1770 int
|
|
1771 expr14(void)
|
|
1772 {
|
|
1773 int e1,t;
|
|
1774
|
|
1775 switch(sym) {
|
|
1776 case IDENT:
|
|
1777 switch(nptr->sc) {
|
|
1778 case GVAR:
|
|
1779 e1=list3(GVAR,nptr->dsp,(int)nptr->nm);
|
|
1780 type=nptr->ty;
|
|
1781 getsym();
|
|
1782 break;
|
|
1783 case LVAR:
|
|
1784 e1=list2(LVAR,nptr->dsp);
|
|
1785 type=nptr->ty;
|
|
1786 getsym();
|
|
1787 break;
|
|
1788 case REGISTER:
|
|
1789 e1=list2(REGISTER,nptr->dsp);
|
|
1790 type=nptr->ty;
|
|
1791 getsym();
|
|
1792 break;
|
|
1793 case FLABEL: case BLABEL:
|
|
1794 case FUNCTION: case CODE:
|
|
1795 e1=list2(FNAME,(int)nptr);
|
|
1796 type=list3(nptr->sc,car(nptr->ty),cadr(nptr->ty));
|
|
1797 getsym();
|
|
1798 break;
|
|
1799 case EMPTY:
|
|
1800 if(getsym()==LPAR) {
|
|
1801 nptr->sc = FUNCTION;
|
7
|
1802 nptr->ty= glist2(INT,0);
|
0
|
1803 type= list3(FUNCTION,INT,0);
|
|
1804 e1=expr15(list2(FNAME,(int)nptr));
|
|
1805 break;
|
|
1806 } else {
|
|
1807 e1=list2(FNAME,(int)nptr);
|
|
1808 type=list3(nptr->sc,nptr->ty,0);
|
|
1809 break;
|
|
1810 }
|
|
1811 default:error(UDERR);
|
|
1812 }
|
|
1813 break;
|
|
1814 case STRING:
|
|
1815 e1=list3(STRING,(int)sptr,symval);
|
|
1816 type=list3(ARRAY,CHAR,symval);
|
|
1817 getsym();
|
|
1818 break;
|
|
1819 case CONST:
|
|
1820 type= INT;
|
|
1821 e1=list2(CONST,symval);
|
|
1822 getsym();
|
|
1823 break;
|
|
1824 case RETURN:
|
|
1825 if (fnptr->sc != FUNCTION) {
|
|
1826 error(STERR);
|
|
1827 }
|
|
1828 type=list2(POINTER,CODE);
|
|
1829 e1=list2(RETURN,(int)fnptr);
|
|
1830 getsym();
|
|
1831 break;
|
18
|
1832 case DEFINED:
|
|
1833 getsym();
|
|
1834 t = mode; mode = IFDEF;
|
|
1835 checksym(LPAR);
|
|
1836 mode = t;
|
|
1837 type= INT;
|
|
1838 e1=list2(CONST,symval);
|
|
1839 getsym();
|
|
1840 checksym(RPAR);
|
|
1841 break;
|
0
|
1842 case ENVIRONMENT:
|
2
|
1843 type=list2(POINTER,VOID);
|
0
|
1844 e1=list2(ENVIRONMENT,0);
|
|
1845 getsym();
|
|
1846 break;
|
|
1847 case LPAR:
|
|
1848 if(typeid(getsym())) {
|
|
1849 t=typename();
|
|
1850 checksym(RPAR);
|
|
1851 e1=expr13();
|
|
1852 type=t;
|
|
1853 return e1;
|
|
1854 }
|
|
1855 e1=expr0();
|
|
1856 checksym(RPAR);
|
|
1857 break;
|
|
1858 default:error(EXERR);
|
|
1859 }
|
|
1860 return expr16(e1);
|
|
1861 }
|
|
1862
|
|
1863 int
|
|
1864 expr16(int e1)
|
|
1865 {
|
|
1866 int e2,t;
|
|
1867
|
|
1868 while(1) {
|
|
1869 if(sym==LBRA) {
|
|
1870 e1=rvalue(e1);
|
|
1871 t=type;
|
|
1872 getsym();
|
|
1873 e2=rvalue(expr0());
|
|
1874 checksym(RBRA);
|
|
1875 e1=binop(ADD,e1,e2,t,type);
|
|
1876 e1=indop(e1);
|
|
1877 } else if(sym==LPAR) e1=expr15(e1);
|
|
1878 else if(sym==PERIOD) e1=strop(e1);
|
|
1879 else if(sym==ARROW) e1=strop(indop(rvalue(e1)));
|
|
1880 else break;
|
|
1881 }
|
|
1882 if(car(e1)==FNAME) type=list2(POINTER,type);
|
|
1883 return e1;
|
|
1884 }
|
|
1885
|
|
1886 int
|
|
1887 rvalue(int e)
|
|
1888 {
|
|
1889 int t;
|
|
1890 if(type==CHAR) {
|
|
1891 type= INT;
|
|
1892 switch(car(e)) {
|
|
1893 case GVAR:
|
|
1894 return(list3(CRGVAR,cadr(e),caddr(e)));
|
|
1895 case LVAR:
|
|
1896 return(list2(CRLVAR,cadr(e)));
|
|
1897 case INDIRECT:
|
|
1898 return(list2(CRINDIRECT,cadr(e)));
|
|
1899 default:return(e);
|
|
1900 }
|
|
1901 }
|
|
1902 if(!integral(type)&&type!=VOID) {
|
|
1903 if(type==CODE) { return(e);
|
|
1904 } else if((t=car(type))==ARRAY) {
|
|
1905 type=list2(POINTER,cadr(type));
|
|
1906 if(car(e)==INDIRECT) return cadr(e);
|
|
1907 return list2(ADDRESS,e);
|
|
1908 } else if(t==STRUCT || t==UNION) { return e;
|
|
1909 } else if(t!=POINTER) error(TYERR);
|
|
1910 }
|
|
1911 switch(car(e)) {
|
|
1912 case GVAR:
|
|
1913 return(list3(RGVAR,cadr(e),caddr(e)));
|
|
1914 case LVAR:
|
|
1915 return(list2(RLVAR,cadr(e)));
|
|
1916 case INDIRECT:
|
|
1917 return(list2(RINDIRECT,cadr(e)));
|
|
1918 default:return(e);
|
|
1919 }
|
|
1920 }
|
|
1921
|
|
1922 void
|
|
1923 lcheck(int e)
|
|
1924 {
|
|
1925 int t;
|
|
1926 if(!scalar(type)||
|
|
1927 (car(e)!=GVAR&&car(e)!=LVAR&&car(e)!=INDIRECT&&car(e)!=REGISTER))
|
|
1928 if ((t=car(type))<0 && t!=STRUCT && t!=UNION)
|
|
1929 error(LVERR);
|
|
1930 }
|
|
1931
|
|
1932 int
|
|
1933 indop(int e)
|
|
1934 {
|
|
1935 if(type!=INT&&type!=UNSIGNED) {
|
|
1936 if(car(type)==POINTER)
|
|
1937 type=cadr(type);
|
|
1938 else error(TYERR);
|
|
1939 } else
|
|
1940 type= CHAR;
|
|
1941 if(car(e)==ADDRESS)
|
|
1942 return(cadr(e));
|
|
1943 return(list2(INDIRECT,e));
|
|
1944 }
|
|
1945
|
|
1946 int
|
|
1947 strop(int e)
|
|
1948 {
|
|
1949 getsym();
|
|
1950 if (sym!=IDENT||nptr->sc!=FIELD) error(TYERR);
|
|
1951 if (integral(type)||(car(type)!=STRUCT && car(type)!=UNION))
|
|
1952 e=rvalue(e);
|
|
1953 type = nptr->ty;
|
|
1954 switch(car(e)) {
|
|
1955 case GVAR:
|
|
1956 e=list2(INDIRECT,list3(ADD,e,list2(CONST,nptr->dsp)));
|
|
1957 break;
|
|
1958 case LVAR:
|
|
1959 e=list2(car(e),cadr(e) + nptr->dsp);
|
|
1960 break;
|
|
1961 case INDIRECT:
|
|
1962 if(!nptr->dsp) break;
|
|
1963 e=list2(INDIRECT,list3(ADD,cadr(e),list2(CONST,nptr->dsp)));
|
|
1964 break;
|
|
1965 default:
|
|
1966 e=list2(INDIRECT,list3(ADD,e,list2(CONST,nptr->dsp)));
|
|
1967 }
|
|
1968 getsym();
|
|
1969 return e;
|
|
1970 }
|
|
1971
|
|
1972 int
|
|
1973 binop(int op, int e1, int e2, int t1, int t2)
|
|
1974 {
|
|
1975 int e;
|
|
1976
|
|
1977 if(car(e1)==CONST&&car(e2)==CONST) {
|
|
1978 e1=cadr(e1);
|
|
1979 e2=cadr(e2);
|
|
1980 type= INT;
|
|
1981 switch(op) {
|
|
1982 case BOR:
|
|
1983 e=e1|e2;break;
|
|
1984 case EOR:
|
|
1985 e=e1^e2;break;
|
|
1986 case BAND:
|
|
1987 e=e1&e2;break;
|
|
1988 case ADD:
|
|
1989 if(integral(t1)) {
|
|
1990 if(integral(t2)) {
|
|
1991 e=e1+e2;
|
|
1992 } else {
|
|
1993 if(car(t2)!=POINTER) error(TYERR);
|
|
1994 e=size(cadr(t2))*e1+e2;
|
|
1995 type=t2;
|
|
1996 }
|
|
1997 } else {
|
|
1998 if(car(t1)!=POINTER) error(TYERR);
|
|
1999 e=e1+size(cadr(t1))*e2;
|
|
2000 type=t1;
|
|
2001 }
|
|
2002 break;
|
|
2003 case SUB:
|
|
2004 if(integral(t1)) {
|
|
2005 e=e1-e2;
|
|
2006 } else {
|
|
2007 if(car(t1)!=POINTER) error(TYERR);
|
|
2008 e=e1-size(cadr(t1))*e2;
|
|
2009 type=t1;
|
|
2010 }
|
|
2011 break;
|
|
2012 case MUL:
|
|
2013 e=e1*e2;break;
|
|
2014 case DIV:
|
|
2015 if(!e2) error(EXERR);e=e1/e2;break;
|
|
2016 case MOD:
|
|
2017 if(!e2) error(EXERR);e=e1%e2;break;
|
|
2018 case RSHIFT:
|
|
2019 e=e1>>e2;break;
|
|
2020 case LSHIFT:
|
|
2021 e=e1<<e2;
|
|
2022 }
|
|
2023 return list2(CONST,e);
|
|
2024 }
|
|
2025 if((op==ADD||op==MUL||op==BOR||op==EOR||op==BAND)&&
|
|
2026 (car(e1)==CONST||(car(e2)!=CONST&&
|
|
2027 (car(e1)==RGVAR||car(e1)==RLVAR)))) {
|
|
2028 e=e1;e1=e2;e2=e;e=t1;t1=t2;t2=e;
|
|
2029 }
|
|
2030 if(op==ADD) {
|
|
2031 if(integral(t1)) {
|
|
2032 if(integral(t2)) {
|
|
2033 if(t1==INT) type=t2;else type=t1;
|
|
2034 return(list3(ADD,e1,e2));
|
|
2035 }
|
|
2036 if(car(t2)!=POINTER) error(TYERR);
|
|
2037 e=binop(MUL,e1,list2(CONST,size(cadr(t2))),t1,INT);
|
|
2038 type=t2;
|
|
2039 return(list3(ADD,e,e2));
|
|
2040 }
|
|
2041 if(car(t1)!=POINTER||!integral(t2)) error(TYERR);
|
|
2042 e=binop(MUL,e2,list2(CONST,size(cadr(t1))),t2,INT);
|
|
2043 type=t1;
|
|
2044 if(car(e1)==ADDRESS&&car(e)==CONST&&car(cadr(e1))!=GVAR)
|
|
2045 return(list2(ADDRESS,list2(car(cadr(e1)),
|
|
2046 cadr(cadr(e1))+cadr(e))));
|
|
2047 return(list3(ADD,e1,e));
|
|
2048 }
|
|
2049 if(op==SUB) {
|
|
2050 if(integral(t1)) {
|
|
2051 if(!integral(t2)) error(TYERR);
|
|
2052 if(t1==INT) type=t2;else type=t1;
|
|
2053 return(list3(SUB,e1,e2));
|
|
2054 }
|
|
2055 if(car(t1)!=POINTER) error(TYERR);
|
|
2056 if(integral(t2)) {
|
|
2057 e=binop(MUL,e2,list2(CONST,size(cadr(t1))),t2,INT);
|
|
2058 type=t1;
|
|
2059 return(list3(SUB,e1,e));
|
|
2060 }
|
|
2061 if(car(t2)!=POINTER)
|
|
2062 error(TYERR);
|
|
2063 compatible(t1,t2);
|
|
2064 e=list3(SUB,e1,e2);
|
|
2065 e=binop(DIV,e,list2(CONST,size(cadr(t1))),UNSIGNED,INT);
|
|
2066 type= INT;
|
|
2067 return e;
|
|
2068 }
|
|
2069 if(!integral(t1)||!integral(t2)) error(TYERR);
|
|
2070 if(t1==INT) type=t2;else type=t1;
|
|
2071 if((op==MUL||op==DIV)&&car(e2)==CONST&&cadr(e2)==1) return e1;
|
|
2072 if(op==BOR||op==EOR||op==BAND) return(list3(op,e1,e2));
|
|
2073 return(list3(type==UNSIGNED?op+US:op,e1,e2));
|
|
2074 }
|
|
2075
|
|
2076 int
|
|
2077 expr15(int e1)
|
|
2078 {
|
3
|
2079 int t,arglist,e;
|
0
|
2080
|
|
2081 t=type;
|
|
2082 if(integral(t)|| (car(t)!=FUNCTION && car(t)!=CODE))
|
|
2083 error(TYERR);
|
|
2084 getsym();
|
|
2085 arglist=0;
|
|
2086 while(sym!=RPAR) {
|
3
|
2087 e=rvalue(expr1());
|
|
2088 arglist=list3(e,arglist,type);
|
0
|
2089 if(sym!=COMMA) break;
|
|
2090 getsym();
|
|
2091 }
|
|
2092 checksym(RPAR);
|
|
2093 if(car(t)!=CODE) {
|
|
2094 t=cadr(t);
|
|
2095 if(t==CHAR) type= INT;else type=t;
|
|
2096 }
|
|
2097 return list3(FUNCTION,e1,arglist);
|
|
2098 }
|
|
2099
|
|
2100 int
|
|
2101 typeid(int s)
|
|
2102 {
|
|
2103 return (integral(s) || s==CODE || s==SHORT || s==LONG || s==STRUCT || s==UNION ||
|
|
2104 (s==IDENT && nptr->sc==TYPE));
|
|
2105 }
|
|
2106
|
|
2107 int
|
|
2108 typename(void)
|
|
2109 {
|
|
2110 int t;
|
|
2111
|
|
2112 type=t=typespec();
|
|
2113 ndecl0();
|
|
2114 reverse(t);
|
|
2115 return type;
|
|
2116 }
|
|
2117
|
|
2118 int
|
|
2119 ndecl0(void)
|
|
2120 {
|
|
2121 if(sym==MUL) {
|
|
2122 getsym();
|
|
2123 return type=list2(POINTER,ndecl0());
|
|
2124 }
|
|
2125 return ndecl1();
|
|
2126 }
|
|
2127
|
|
2128 int
|
|
2129 ndecl1(void)
|
|
2130 {
|
|
2131 int i,t,arglist;
|
|
2132
|
|
2133 if(sym==LPAR) {
|
|
2134 if(getsym()==RPAR) {
|
|
2135 type=list3(FUNCTION,type,0); getsym();
|
|
2136 } else {
|
|
2137 ndecl0();
|
|
2138 checksym(RPAR);
|
|
2139 }
|
|
2140 }
|
|
2141 while(1) {
|
|
2142 if(sym==LBRA) {
|
|
2143 getsym();
|
|
2144 t=type;
|
|
2145 i=cexpr(expr());
|
|
2146 checksym(RBRA);
|
|
2147 type=list3(ARRAY,t,i);
|
|
2148 } else if(sym==LPAR) {
|
|
2149 t = type;
|
|
2150 getsym();
|
|
2151 arglist=0;
|
|
2152 while(sym!=RPAR) {
|
|
2153 ndecl0();
|
|
2154 arglist=list2(type,arglist);
|
|
2155 if(sym!=COMMA) break;
|
|
2156 getsym();
|
|
2157 }
|
|
2158 checksym(RPAR);
|
|
2159 type=list3(FUNCTION,t,arglist);
|
|
2160 }
|
|
2161 else return type;
|
|
2162 }
|
|
2163 }
|
|
2164
|
|
2165 int
|
|
2166 cexpr(int e)
|
|
2167 {
|
|
2168 if (car(e) != CONST) error(CNERR);
|
|
2169 return (cadr(e));
|
|
2170 }
|
|
2171
|
20
|
2172 int in_comment = 0;
|
|
2173
|
0
|
2174 int
|
|
2175 getsym(void)
|
|
2176 {
|
|
2177 NMTBL *nptr0,*nptr1;
|
|
2178 int i;
|
|
2179 char c;
|
|
2180
|
|
2181 if (alpha(skipspc())) {
|
|
2182 i = hash = 0;
|
|
2183 name = namebuf;
|
|
2184 while (alpha(ch) || digit(ch)) {
|
|
2185 if (i < LBUFSIZE-1)
|
|
2186 hash=(7*hash ^ (name[i++]=ch));
|
|
2187 getch();
|
|
2188 }
|
|
2189 name[i++] = '\0';
|
|
2190 nptr0 = gsearch();
|
|
2191 if (nptr0->sc == MACRO && !mflag) {
|
18
|
2192 if (mode==IFDEF) {
|
|
2193 return (symval=1);
|
|
2194 }
|
0
|
2195 mflag++;
|
|
2196 chsave = ch;
|
|
2197 chptrsave = chptr;
|
|
2198 chptr = (char *)nptr0->dsp;
|
|
2199 getch();
|
|
2200 return getsym();
|
|
2201 }
|
18
|
2202 if (mode==IFDEF) {
|
|
2203 return (symval=0);
|
|
2204 }
|
|
2205 if (nptr0->sc == RESERVE) return sym = nptr0->dsp;
|
|
2206
|
0
|
2207 sym = IDENT;
|
|
2208 gnptr=nptr=nptr0;
|
|
2209 if (mode==ADECL && nptr0->sc ==TYPE) return sym;
|
|
2210 if (mode==GDECL || mode==GSDECL || mode==GUDECL ||
|
|
2211 mode==GTDECL || mode==TOP) {
|
|
2212 return sym;
|
|
2213 }
|
|
2214 nptr1=lsearch(nptr0->nm);
|
18
|
2215 if (mode==STAT) {
|
0
|
2216 if (nptr1->sc == EMPTY) return sym;
|
|
2217 else { nptr=nptr1; return sym;}
|
18
|
2218 }
|
0
|
2219 nptr=nptr1;
|
|
2220 return sym;
|
|
2221 } else if (digit(ch)) {
|
|
2222 symval=0;
|
|
2223 if (ch == '0') {
|
|
2224 if (getch() == 'x' || ch == 'X') {
|
|
2225 while(1) {
|
|
2226 if(digit(getch()))
|
|
2227 symval=symval*16+ch-'0';
|
|
2228 else if('a'<=ch&&ch<='f')
|
|
2229 symval=symval*16+ch-'a'+10;
|
|
2230 else if('A'<=ch&&ch<='F')
|
|
2231 symval=symval*16+ch-'A'+10;
|
|
2232 else break;
|
|
2233 }
|
|
2234 } else {
|
|
2235 while (digit(ch)) {
|
|
2236 symval=symval*8+ch-'0';getch();
|
|
2237 }
|
|
2238 }
|
|
2239 } else {
|
|
2240 while(digit(ch)) {
|
|
2241 symval=symval*10+ch-'0';getch();
|
|
2242 }
|
|
2243 }
|
|
2244 return sym=CONST;
|
|
2245 } else if(ch=='\'') {
|
|
2246 getch();
|
|
2247 symval=escape();
|
|
2248 if(ch!='\'') error(CHERR);
|
|
2249 getch();
|
|
2250 return sym=CONST;
|
|
2251 } else if(ch=='"') {
|
|
2252 getstring();
|
|
2253 return sym= STRING;
|
|
2254 }
|
|
2255 c=ch;
|
|
2256 getch();
|
|
2257 switch(c) {
|
|
2258 case '*':
|
|
2259 return postequ(MUL,MUL+AS);
|
|
2260 case '&':
|
|
2261 if(ch=='&') {getch();return sym=LAND;}
|
|
2262 return postequ(BAND,BAND+AS);
|
|
2263 case '-':
|
|
2264 if(ch=='>') {getch();return sym=ARROW;}
|
|
2265 if(ch=='-') {getch();return sym=DEC;}
|
|
2266 return postequ(SUB,SUB+AS);
|
|
2267 case '!':
|
|
2268 return postequ(LNOT,NEQ);
|
|
2269 case '~':
|
|
2270 return sym=BNOT;
|
|
2271 case '+':
|
|
2272 if(ch=='+') {getch();return sym=INC;}
|
|
2273 return postequ(ADD,ADD+AS);
|
|
2274 case '%':
|
|
2275 return postequ(MOD,MOD+AS);
|
|
2276 case '^':
|
|
2277 return postequ(EOR,EOR+AS);
|
|
2278 case '|':
|
|
2279 if(ch=='|') {getch();return sym=LOR;}
|
|
2280 return postequ(BOR,BOR+AS);
|
|
2281 case '=':
|
|
2282 return postequ(ASS,EQ);
|
|
2283 case '>':
|
|
2284 if(ch=='>') {getch();return postequ(RSHIFT,RSHIFT+AS);}
|
|
2285 return postequ(GT,GE);
|
|
2286 case '<':
|
|
2287 if(ch=='<') {getch();return postequ(LSHIFT,LSHIFT+AS);}
|
|
2288 return postequ(LT,LE);
|
|
2289 case '(':
|
|
2290 return sym=LPAR;
|
|
2291 case ')':
|
|
2292 return sym=RPAR;
|
|
2293 case '[':
|
|
2294 return sym=LBRA;
|
|
2295 case ']':
|
|
2296 return sym=RBRA;
|
|
2297 case '{':
|
|
2298 return sym=LC;
|
|
2299 case '}':
|
|
2300 return sym=RC;
|
|
2301 case ',':
|
|
2302 return sym=COMMA;
|
|
2303 case ';':
|
|
2304 return sym=SM;
|
|
2305 case ':':
|
|
2306 return sym=COLON;
|
|
2307 case '?':
|
|
2308 return sym=COND;
|
|
2309 case '.':
|
|
2310 if(ch=='.') {
|
|
2311 getch();
|
|
2312 if (ch=='.') {
|
|
2313 getch();
|
|
2314 return sym=DOTS;
|
|
2315 }
|
|
2316 error(CHERR);
|
|
2317 return getsym();
|
|
2318 } else
|
|
2319 return sym=PERIOD;
|
|
2320 case '/':
|
|
2321 if(ch!='*') return postequ(DIV,DIV+AS);
|
20
|
2322 in_comment = 1;
|
0
|
2323 getch();
|
|
2324 while(ch=='*'?getch()!='/':getch());
|
20
|
2325 in_comment = 0;
|
0
|
2326 getch();
|
|
2327 return getsym();
|
|
2328 default:
|
|
2329 error(CHERR);
|
|
2330 return getsym();
|
|
2331 }
|
|
2332 }
|
|
2333
|
|
2334 int
|
|
2335 postequ(int s1, int s2)
|
|
2336 {
|
|
2337 if(ch=='=') {getch();return sym=s2;}
|
|
2338 return sym=s1;
|
|
2339 }
|
|
2340
|
|
2341 int
|
|
2342 alpha(char c)
|
|
2343 {
|
|
2344 return(('a'<=c&&c<='z')||('A'<=c&&c<='Z')||c=='_');
|
|
2345 }
|
|
2346
|
|
2347 int
|
|
2348 digit(char c)
|
|
2349 {
|
|
2350 return('0'<=c&&c<='9');
|
|
2351 }
|
|
2352
|
|
2353
|
|
2354 NMTBL *
|
|
2355 gsearch(void)
|
|
2356 {
|
|
2357 NMTBL *nptr,*iptr;
|
|
2358
|
|
2359 iptr=nptr= &ntable[hash % GSYMS];
|
|
2360 while(nptr->sc!=0 && neqname(nptr->nm)) {
|
|
2361 if (++nptr== &ntable[GSYMS])
|
|
2362 nptr=ntable;
|
|
2363 if (nptr==iptr) error(GSERR);
|
|
2364 }
|
|
2365 if (nptr->sc == 0) {
|
|
2366 copy(nptr,name);
|
|
2367 nptr->sc=EMPTY;
|
|
2368 }
|
|
2369 return nptr;
|
|
2370 }
|
|
2371
|
|
2372 NMTBL *
|
|
2373 lsearch(char *name)
|
|
2374 {
|
|
2375 NMTBL *nptr,*iptr;
|
|
2376
|
|
2377 iptr=nptr= &ntable[hash%LSYMS+GSYMS];
|
|
2378 while(nptr->sc!=0 && neqname(nptr->nm)) {
|
|
2379 if (++nptr== &ntable[LSYMS+GSYMS])
|
|
2380 nptr= &ntable[GSYMS];
|
|
2381 if (nptr==iptr) error(LSERR);
|
|
2382 }
|
|
2383 if (nptr->sc == 0) {
|
|
2384 nptr->nm=name; /* already saved in gsearch */
|
|
2385 nptr->sc=EMPTY;
|
|
2386 nptr->dsp=0;
|
|
2387 }
|
|
2388 return nptr;
|
|
2389 }
|
|
2390
|
|
2391 void
|
|
2392 copy(NMTBL *nptr, char *s)
|
|
2393 {
|
|
2394 nptr->nm = cheapp;
|
18
|
2395 while((*cheapp++ = *s++));
|
0
|
2396 }
|
|
2397
|
|
2398 int
|
|
2399 neqname(char *p)
|
|
2400 {
|
|
2401 char *q;
|
|
2402
|
|
2403 if (!p)
|
|
2404 return 0;
|
|
2405 q=name;
|
|
2406 while(*p && *p!='.')
|
|
2407 if(*p++ != *q++) return 1;
|
|
2408 return (*q!=0);
|
|
2409 }
|
|
2410
|
|
2411 void
|
|
2412 getstring(void)
|
|
2413 {
|
|
2414 getch();
|
|
2415 symval = 0;
|
|
2416 sptr = cheapp;
|
|
2417 while (ch != '"') {
|
|
2418 *cheapp++ = escape();
|
|
2419 symval++;
|
|
2420 if (cheapp >= cheap+CHEAPSIZE) error(STRERR);
|
|
2421 }
|
|
2422 getch();
|
|
2423 *cheapp++ = '\0';
|
|
2424 symval++;
|
|
2425 }
|
|
2426
|
|
2427 int
|
|
2428 skipspc(void)
|
|
2429 {
|
|
2430 while(ch=='\t'||ch=='\n'||ch==' '||ch=='\r')
|
|
2431 getch();
|
|
2432 return ch;
|
|
2433 }
|
|
2434
|
|
2435 int
|
|
2436 getch(void)
|
|
2437 {
|
|
2438 if(*chptr) return ch= *chptr++;
|
|
2439 if(mflag) {
|
|
2440 mflag=0;chptr=chptrsave;return ch=chsave;
|
|
2441 }
|
|
2442 getline();
|
|
2443 return getch();
|
|
2444 }
|
|
2445
|
|
2446 char
|
|
2447 escape(void)
|
|
2448 {
|
|
2449 char c;
|
|
2450 if ((c=ch) == '\\') {
|
|
2451 if (digit(c=getch())) {
|
|
2452 c = ch-'0';
|
|
2453 if (digit(getch())) {
|
|
2454 c = c*8+ch-'0';
|
|
2455 if (digit(getch())) {
|
|
2456 c=c*8+ch-'0';getch();
|
|
2457 }
|
|
2458 }
|
|
2459 return c;
|
|
2460 }
|
|
2461 getch();
|
|
2462 switch(c) {
|
|
2463 case 'n':
|
|
2464 return '\n';
|
|
2465 case 't':
|
|
2466 return '\t';
|
|
2467 case 'b':
|
|
2468 return '\b';
|
|
2469 case 'r':
|
|
2470 return '\r';
|
|
2471 case 'f':
|
|
2472 return '\f';
|
|
2473 case '\n':
|
|
2474 return escape();
|
|
2475 default:
|
|
2476 return c;
|
|
2477 }
|
|
2478 }
|
|
2479 if (c == '\n') error(EXERR);
|
|
2480 getch();
|
|
2481 return c;
|
|
2482 }
|
|
2483
|
|
2484 FILE *
|
|
2485 getfname(void)
|
|
2486 {
|
|
2487 int i;
|
25
|
2488 char *s,name[LBUFSIZE];
|
0
|
2489 FILE *fp;
|
|
2490
|
|
2491 getch();
|
|
2492 if(skipspc()!='"') error(INCERR);
|
|
2493 for(i=0;(getch()!='"' && ch!='\n');) {
|
|
2494 if(i<LBUFSIZE-1) name[i++]=ch;
|
|
2495 }
|
|
2496 if(ch=='\n') error(INCERR);
|
|
2497 name[i]=0;
|
|
2498 fp = fopen(name,"r") ;
|
25
|
2499 s = name;
|
|
2500 (filep+1)->name0 = cheapp;
|
|
2501 while((*cheapp++ = *s++));
|
0
|
2502 return ( (filep+1)->fcb = fp );
|
|
2503 }
|
|
2504
|
18
|
2505 static int macro_if_depth ;
|
|
2506 static int macro_if_current ;
|
|
2507 static int macro_if_skip ;
|
|
2508
|
0
|
2509 void
|
|
2510 getline(void)
|
|
2511 {
|
|
2512 int i;
|
|
2513 int c;
|
|
2514
|
18
|
2515 do {
|
|
2516 lineno++;
|
|
2517 glineno++;
|
|
2518 chptr=linebuf;
|
|
2519 i=0;
|
23
|
2520 while ((*chptr++ = c = getc(filep->fcb)) != '\n') {
|
18
|
2521 if (++i > LBUFSIZE-2) error(LNERR);
|
|
2522 if (c==EOF) {
|
|
2523 error(EOFERR);
|
|
2524 --chptr;
|
|
2525 }
|
|
2526 }
|
|
2527 *chptr = '\0';
|
23
|
2528 if (lsrc && !asmf && !macro_if_skip) gen_comment(linebuf);
|
20
|
2529 if (*(chptr = linebuf) == '#' && !in_comment) {
|
18
|
2530 macro_processing();
|
|
2531 }
|
23
|
2532 } while(macro_if_skip || linebuf[0] == '#');
|
18
|
2533 }
|
|
2534
|
|
2535 void
|
|
2536 macro_processing()
|
|
2537 {
|
|
2538 int i;
|
|
2539 int c;
|
|
2540 int mode_save;
|
|
2541
|
|
2542 ++chptr;
|
19
|
2543 if (macroeq("ifdef") || macroeq("ifndef")) {
|
|
2544 c = (chptr[-3]=='n');
|
18
|
2545 macro_if_current++;
|
|
2546 if (!macro_if_skip) {
|
19
|
2547 mode_save = mode; mode = IFDEF;
|
|
2548 ch= *chptr;
|
|
2549 i = getsym();
|
|
2550 mode = mode_save;
|
|
2551 macro_if_depth = macro_if_current;
|
|
2552 macro_if_skip = (!i)^c;
|
|
2553 }
|
|
2554 return;
|
|
2555 } else if (macroeq("if")) {
|
|
2556 macro_if_current++;
|
|
2557 if (!macro_if_skip) {
|
23
|
2558 for(c=0;chptr[c];c++);
|
|
2559 chptr[c] = ';';
|
19
|
2560 ch= *chptr;
|
18
|
2561 getsym();
|
|
2562 i=cexpr(expr());
|
|
2563 macro_if_depth = macro_if_current;
|
|
2564 macro_if_skip = !i;
|
|
2565 }
|
19
|
2566 return;
|
18
|
2567 } else if (macroeq("else")) {
|
|
2568 if (macro_if_current==0) {
|
|
2569 error(MCERR); /* extra #else */
|
19
|
2570 return;
|
18
|
2571 }
|
|
2572 if (macro_if_current == macro_if_depth)
|
|
2573 macro_if_skip = !macro_if_skip;
|
19
|
2574 return;
|
18
|
2575 } else if (macroeq("endif")) {
|
|
2576 if (macro_if_current == macro_if_depth) {
|
|
2577 macro_if_skip = 0;
|
19
|
2578 macro_if_depth = --macro_if_current;
|
18
|
2579 } else {
|
19
|
2580 if (macro_if_current<=0) {
|
18
|
2581 error(MCERR); /* extra #if */
|
19
|
2582 return;
|
18
|
2583 }
|
19
|
2584 macro_if_current--;
|
18
|
2585 }
|
19
|
2586 return;
|
|
2587 }
|
|
2588 if (macro_if_skip) return;
|
|
2589 if (macroeq("define")) {
|
18
|
2590 i=mode;
|
|
2591 mode=GDECL;
|
|
2592 ch= *chptr;
|
|
2593 if (getsym() == IDENT) {
|
|
2594 if (nptr->sc == EMPTY) {
|
|
2595 nptr->sc = MACRO;
|
|
2596 nptr->dsp = (int)cheapp;
|
|
2597 while ((*cheapp++ = c = *chptr++)
|
|
2598 && c != '\n');
|
|
2599 *cheapp++ = '\0';
|
|
2600 if (cheapp >= cheap+CHEAPSIZE)
|
|
2601 error(STRERR);
|
19
|
2602 /* if (!c) error(EOFERR); ??? #define hoge only case */
|
0
|
2603 } else error(MCERR);
|
18
|
2604 } else error(MCERR);
|
|
2605 mode=i;
|
|
2606 *(chptr = linebuf) = '\0';
|
19
|
2607 } else if (macroeq("undef")) {
|
|
2608 i=mode;
|
|
2609 mode=GDECL;
|
|
2610 ch= *chptr;
|
|
2611 if (getsym() == IDENT) {
|
|
2612 if (nptr->sc == MACRO) {
|
|
2613 nptr->sc = EMPTY;
|
|
2614 } else error(MCERR);
|
|
2615 }
|
|
2616 mode=i;
|
18
|
2617 } else if (macroeq("include")) {
|
|
2618 if(filep+1 >= filestack + FILES) error(FILERR);
|
|
2619 if ( ((filep+1)->fcb=getfname()) == NULL) error(FILERR);
|
|
2620 (filep+1)->ln=lineno;
|
|
2621 lineno=0;
|
|
2622 ++filep;
|
|
2623 *(chptr = linebuf) = '\0';
|
|
2624 } else if (macroeq("asm")) {
|
|
2625 if (asmf) error(MCERR);
|
|
2626 asmf = 1;
|
|
2627 getline();
|
|
2628 while (asmf) {
|
|
2629 gen_source(linebuf);
|
0
|
2630 getline();
|
18
|
2631 }
|
|
2632 } else if (macroeq("endasm")) {
|
|
2633 if (!asmf) error(MCERR);
|
|
2634 asmf = 0;
|
|
2635 } else if (macroeq(" "))
|
|
2636 getline();
|
|
2637 else error(MCERR);
|
0
|
2638 }
|
|
2639
|
|
2640 int
|
|
2641 macroeq(char *s)
|
|
2642 {
|
|
2643 char *p;
|
|
2644
|
|
2645 for (p = chptr; *s;) if (*s++ != *p++) return 0;
|
|
2646 chptr = p;
|
|
2647 return 1;
|
|
2648 }
|
|
2649
|
|
2650 int
|
|
2651 car(int e)
|
|
2652 {
|
|
2653 return heap[e];
|
|
2654 }
|
|
2655
|
|
2656 int
|
|
2657 cadr(int e)
|
|
2658 {
|
|
2659 return heap[e+1];
|
|
2660 }
|
|
2661
|
|
2662 int
|
|
2663 caddr(int e)
|
|
2664 {
|
|
2665 return heap[e+2];
|
|
2666 }
|
|
2667
|
|
2668 int
|
|
2669 cadddr(int e)
|
|
2670 {
|
|
2671 return heap[e+3];
|
|
2672 }
|
|
2673
|
|
2674 int
|
|
2675 list2(int e1, int e2)
|
|
2676 {
|
|
2677 int e;
|
|
2678
|
|
2679 e=getfree(2);
|
|
2680 heap[e]=e1;
|
|
2681 heap[e+1]=e2;
|
|
2682 return e;
|
|
2683 }
|
|
2684
|
|
2685 int
|
|
2686 list3(int e1, int e2, int e3)
|
|
2687 {
|
|
2688 int e;
|
|
2689
|
|
2690 e=getfree(3);
|
|
2691 heap[e]=e1;
|
|
2692 heap[e+1]=e2;
|
|
2693 heap[e+2]=e3;
|
|
2694 return e;
|
|
2695 }
|
|
2696
|
|
2697 int
|
|
2698 list4(int e1, int e2, int e3, int e4)
|
|
2699 {
|
|
2700 int e;
|
|
2701
|
|
2702 e=getfree(4);
|
|
2703 heap[e]=e1;
|
|
2704 heap[e+1]=e2;
|
|
2705 heap[e+2]=e3;
|
|
2706 heap[e+3]=e4;
|
|
2707 return e;
|
|
2708 }
|
|
2709
|
|
2710 int
|
|
2711 getfree(int n)
|
|
2712 {
|
|
2713 int e;
|
|
2714
|
|
2715 switch (mode) {
|
|
2716 case GDECL: case GSDECL: case GUDECL: case GTDECL:
|
|
2717 e=gfree;
|
|
2718 gfree+=n;
|
|
2719 break;
|
|
2720 default:
|
|
2721 lfree-=n;
|
|
2722 e=lfree;
|
|
2723 }
|
|
2724 if(lfree<gfree) error(HPERR);
|
|
2725 return e;
|
|
2726 }
|
|
2727
|
|
2728 int
|
|
2729 rplacad(int e, int n)
|
|
2730 {
|
|
2731 heap[e+1]=n;
|
|
2732 return e;
|
|
2733 }
|
|
2734
|
|
2735 int
|
|
2736 rplacadd(int e, int n)
|
|
2737 {
|
|
2738 heap[e+2]=n;
|
|
2739 return e;
|
|
2740 }
|
|
2741
|
7
|
2742 int
|
|
2743 glist2(int e1,int e2)
|
|
2744 {
|
|
2745 int smode,ret;
|
|
2746 smode = mode;
|
|
2747 mode = GDECL;
|
|
2748 ret = list2(e1,e2);
|
|
2749 mode = smode;
|
|
2750 return ret;
|
|
2751 }
|
|
2752
|
18
|
2753 void
|
0
|
2754 display_ntable(NMTBL *n, char *s)
|
|
2755 {
|
18
|
2756 fprintf(stderr,"\n%s %0x %0x ",s,(int)n,(int)ntable);
|
0
|
2757 fprintf(stderr,"nptr->sc %d ",n->sc);
|
|
2758 fprintf(stderr,"nptr->dsp %d ",n->dsp);
|
|
2759 fprintf(stderr,"nptr->ty %d ",n->ty);
|
|
2760 fprintf(stderr,"nptr->nm %s\n",n->nm);
|
|
2761 }
|
|
2762
|
|
2763 /* end */
|