Mercurial > hg > CbC > old > device
annotate mc-parse.c @ 91:9b1aeb62e0b9
powerpc continue... (floating point)
author | kono |
---|---|
date | Fri, 07 Mar 2003 05:22:01 +0900 |
parents | 1738f313f98b |
children | 1ad7045741a7 |
rev | line source |
---|---|
1 | 1 /* Micro-C Parser Part */ |
2 /* $Id$ */ | |
3 | |
0 | 4 #define EXTERN /**/ |
5 #include "mc.h" | |
61 | 6 #include "mc-codegen.h" |
0 | 7 |
61 | 8 static NMTBL *decl0(void),*decl1(void),*lsearch(char *name),*gsearch(void); |
9 static NMTBL *def(NMTBL *n); | |
10 static NMTBL *free_nptr(); | |
11 static NMTBL *msearch(char *name); | |
12 static NMTBL *msearch0(char *name); | |
13 static char * mappend(int lists); | |
0 | 14 static int alpha(char c); |
61 | 15 static int append3(int p,int a1,int a2); |
0 | 16 static int binop(int op, int e1, int e2, int t1, int t2); |
61 | 17 static int cexpr(int e); |
18 static int decl_data(int t, NMTBL *n,int offset); | |
0 | 19 static int digit(char c); |
69 | 20 static int expr(int); |
0 | 21 static int expr0(void); |
22 static int expr1(void); | |
61 | 23 static int expr10(void); |
24 static int expr11(void); | |
25 static int expr12(void); | |
26 static int expr13(void); | |
27 static int expr14(void); | |
28 static int expr15(int e1); | |
29 static int expr16(int e1); | |
0 | 30 static int expr2(void); |
31 static int expr3(void); | |
32 static int expr4(void); | |
33 static int expr5(void); | |
34 static int expr6(void); | |
35 static int expr7(void); | |
36 static int expr8(void); | |
37 static int expr9(void); | |
38 static int getch(void); | |
39 static int getfree(int n); | |
40 static int getsym(void); | |
41 static int indop(int e); | |
61 | 42 static int macro_args(char **pcheapp,char* max,char **pchptr); |
43 static int macro_eval(int macrop,char *body,int history); | |
44 static int macro_function(int macrop,char **pchptr,NMTBL *nptr,int history); | |
0 | 45 static int macroeq(char *s); |
46 static int ndecl0(void); | |
47 static int ndecl1(void); | |
30 | 48 static int neqname(char *p,char *name); |
0 | 49 static int postequ(int s1, int s2); |
50 static int rvalue(int e); | |
51 static int sdecl(int s); | |
52 static int skipspc(void); | |
53 static int strop(int e); | |
54 static int typeid(int s); | |
55 static int typename(void); | |
56 static int typespec(void); | |
87 | 57 static int adecl(NMTBL *n); |
0 | 58 static void code_decl(NMTBL *n); |
61 | 59 static void compatible(int t1, int t2); |
60 static void copy(NMTBL *nptr, char *s); | |
61 static void decl(void); | |
62 static void docase(void); | |
63 static void docomp(void); | |
64 static void dodefault(void); | |
65 static void dodo(void); | |
66 static void dofor(void); | |
67 static void dogoto(void); | |
68 static void doif(void); | |
69 static void dolabel(void); | |
70 static void doreturn(void); | |
71 static void doswitch(void); | |
72 static void dowhile(void); | |
73 static void errmsg(void); | |
74 static void fcheck(NMTBL *n); | |
75 static void fdecl(NMTBL *n); | |
76 static void fdecl_struct(int type); | |
77 static void getline(void); | |
78 static void getstring(void); | |
79 static void init(void); | |
80 static void lcheck(int e); | |
28 | 81 static void local_define(); |
82 static void local_undef(); | |
61 | 83 static void macro_define(); |
84 static void macro_define0(); | |
85 static void macro_processing(); | |
86 static void newfile(void); | |
39 | 87 static void replace_return_struct(int func,int left); |
61 | 88 static void reserve(char *s, int d); |
89 static void reverse(int t1); | |
59 | 90 static void set_converter(char *s); |
61 | 91 static void statement(void); |
0 | 92 |
18 | 93 |
37 | 94 static int struct_return = 0; |
76 | 95 static int sdecl_f = 1; |
96 static int stypedecl; | |
37 | 97 |
82 | 98 Converter *conv = &null_converter; |
99 /* Converter *conv = &c_converter; */ | |
59 | 100 |
65 | 101 static char *ccout = 0; |
102 | |
0 | 103 int |
104 main(int argc, char **argv) | |
105 { | |
106 NMTBL *nptr; | |
107 int i; | |
108 | |
109 if(argc==1) exit(1); | |
110 lsrc = chk = asmf = 0; | |
111 ac=argc; | |
112 av=argv; | |
113 for (ac2=1; (ac2 < ac) && (*av[ac2] == '-'); ++ac2) { | |
114 switch (*(av[ac2]+1)) { | |
59 | 115 case 's': |
0 | 116 lsrc = 1; |
117 break; | |
59 | 118 case 'o': |
0 | 119 ccout = av[ac2]+2; |
120 break; | |
59 | 121 case 'c': |
0 | 122 chk = 1; |
123 break; | |
59 | 124 case 'd': |
0 | 125 debug = 1; |
126 break; | |
59 | 127 case 'C': |
66 | 128 if (av[ac2+1]) set_converter(av[ac2]+2); |
129 chk = 1; | |
130 ccout=0; | |
59 | 131 break; |
0 | 132 default: |
133 error(OPTION); | |
134 exit(1); | |
135 } | |
136 } | |
65 | 137 if (!chk && ccout) |
18 | 138 if ( (freopen(ccout,"w",stdout)) == NULL ) error(FILERR); |
0 | 139 init(); |
140 while(1) { | |
2 | 141 for (nptr = &ntable[GSYMS],i=LSYMS; i--;) { |
0 | 142 (nptr++)->sc = 0; |
2 | 143 } |
144 emit_init(); | |
0 | 145 mode=TOP; |
146 lfree= HEAPSIZE; | |
66 | 147 while(getsym()==SM) conv->sm_(); |
0 | 148 mode=GDECL; |
149 stmode=0; | |
150 args=0; | |
151 decl(); | |
152 } | |
153 /*NOTREACHED*/ | |
154 } | |
155 | |
156 void | |
157 error(int n) | |
158 { | |
159 if(n == EOFERR) { | |
160 if(filep!=filestack) { | |
161 fclose(filep->fcb); | |
162 lineno=filep->ln; | |
163 --filep; | |
164 return; | |
165 } else if(ac2!=ac) { | |
166 fclose(filep->fcb); | |
167 newfile(); | |
168 return; | |
169 } else if(mode == TOP) { | |
66 | 170 if (chk) { |
171 fprintf(stderr, "Total internal labels : %u.\n",labelno-1); | |
172 fprintf(stderr, "Total global variables: %u bytes.\n",gpc); | |
173 } | |
0 | 174 closing(); |
175 exit(0); | |
176 } | |
177 } | |
66 | 178 if (conv->error_(n)) return; |
25 | 179 fprintf(stderr,"%s:%d:%s\n",filep->name0,lineno, |
0 | 180 (n==FILERR) ? "Can't open specified file" : |
181 (n==DCERR) ? "Declaration syntax" : | |
182 (n==STERR) ? "Statement syntax" : | |
183 (n==EXERR) ? "Expression syntax" : | |
184 (n==CNERR) ? "Constant required" : | |
185 (n==CHERR) ? "Illegal character" : | |
186 (n==GSERR) ? "Too many global symbols" : | |
187 (n==LSERR) ? "Too many local symbols" : | |
29 | 188 (n==MSERR) ? "Too many macro symbols" : |
0 | 189 (n==STRERR) ? "Too many strings or macros" : |
190 (n==LNERR) ? "Line too long" : | |
191 (n==EOFERR) ? "Unexpected end of file" : | |
192 (n==MCERR) ? "Macro syntax" : | |
193 (n==INCERR) ? "Include syntax" : | |
194 (n==HPERR) ? "Too long expression" : | |
195 (n==TYERR) ? "Type mismatch" : | |
196 (n==LVERR) ? "Lvalue required" : | |
197 (n==UDERR) ? "Undeclared identifier" : | |
198 (n==OPTION) ? "Illegal option" : | |
199 (n==REG_ERR) ? "illegal register var" : | |
200 (n==CODE_ERR) ? "goto code is necessary" : | |
201 "Bug of compiler"); | |
202 errmsg(); | |
203 exit(1); | |
204 } | |
205 | |
61 | 206 static void |
0 | 207 errmsg(void) |
208 { | |
209 char *p,*lim; | |
210 | |
211 if(lineno==0) return; | |
212 fprintf(stderr,"%s",linebuf); | |
29 | 213 lim=chptr; |
34 | 214 if (chptrsave) { |
215 lim = chptrsave; | |
29 | 216 } |
0 | 217 for (p=linebuf; p < lim;) |
218 fprintf(stderr,(*p++ == '\t') ? "\t" : " "); | |
219 fprintf (stderr,"^\n"); | |
220 } | |
221 | |
61 | 222 static void |
0 | 223 checksym(int s) |
224 { | |
225 char *p; | |
226 | |
227 if (sym != s) { | |
228 p=(s==RPAR) ? "')'": (s==RBRA) ? "']'": (s==SM) ? "';'": | |
229 (s==LPAR) ? "'('": (s==WHILE) ? "'while'": | |
230 (s==COLON) ? "':'": "Identifier"; | |
231 fprintf(stderr,"%d:%s expected.\n",lineno,p); | |
232 errmsg(); | |
233 } else | |
234 getsym(); | |
235 } | |
236 | |
61 | 237 static void |
0 | 238 init(void) |
239 { | |
240 NMTBL *nptr; | |
241 int i; | |
242 | |
243 cheapp=cheap; | |
244 for(nptr = ntable,i = GSYMS; i--;) (nptr++)->sc = 0; | |
30 | 245 for(nptr = mtable,i = MSYMS; i--;) (nptr++)->sc = 0; |
0 | 246 reserve("int",INT); |
247 reserve("void",VOID); | |
248 reserve("char",CHAR); | |
20 | 249 reserve("const",KONST); |
0 | 250 reserve("struct",STRUCT); |
251 reserve("union",UNION); | |
252 reserve("unsigned",UNSIGNED); | |
253 reserve("static",STATIC); | |
254 reserve("goto",GOTO); | |
255 reserve("return",RETURN); | |
256 reserve("break",BREAK); | |
257 reserve("continue",CONTINUE); | |
258 reserve("if",IF); | |
259 reserve("else",ELSE); | |
260 reserve("for",FOR); | |
261 reserve("do",DO); | |
262 reserve("while",WHILE); | |
263 reserve("switch",SWITCH); | |
264 reserve("case",CASE); | |
265 reserve("default",DEFAULT); | |
266 reserve("typedef",TYPEDEF); | |
267 reserve("sizeof",SIZEOF); | |
268 reserve("long",LONG); | |
269 reserve("short",SHORT); | |
270 reserve("extern",EXTRN); | |
18 | 271 reserve("defined",DEFINED); |
0 | 272 reserve("register",REGISTER); |
273 reserve("code",CODE); | |
274 reserve("environment",ENVIRONMENT); | |
78 | 275 reserve("float",FLOAT); |
276 reserve("double",DOUBLE); | |
19 | 277 |
34 | 278 gpc=glineno=0; |
0 | 279 gfree=ilabel=1; |
280 labelno=2; | |
281 lfree=HEAPSIZE; | |
282 filep=filestack; | |
283 code_init(); | |
284 newfile(); | |
32 | 285 |
286 macro_define("__micro_c__ 1\n"); | |
287 | |
0 | 288 getline(); |
289 getch(); | |
290 } | |
291 | |
61 | 292 static void |
0 | 293 newfile(void) |
294 { | |
25 | 295 char *s; |
65 | 296 |
0 | 297 lineno=0; |
66 | 298 if (chk) fprintf(stderr,"%s:\n",av[ac2]); |
0 | 299 if ( (filep->fcb = fopen(av[ac2++],"r")) == NULL ) error(FILERR); |
25 | 300 s = av[ac2-1]; |
301 filep->name0 = cheapp; | |
302 while((*cheapp++ = *s++)); | |
65 | 303 if(!ccout) { |
304 ccout=s=cheapp; s= filep->name0; | |
305 while((*cheapp++ = *s++)) { | |
306 if(s[0]=='.'&&s[1]=='c') { | |
307 *cheapp++=*s++; *cheapp++=*s++; | |
308 cheapp[-1]='s'; | |
309 } | |
310 } | |
311 if ( (freopen(ccout,"w",stdout)) == NULL ) error(FILERR); | |
312 cheapp=ccout; | |
313 ccout=0; | |
314 } | |
315 opening(filep->name0); | |
67 | 316 conv->open_(filep->name0); |
0 | 317 } |
318 | |
61 | 319 static void |
59 | 320 set_converter(char *s) |
321 { | |
322 chptr = s; | |
66 | 323 #if 0 |
59 | 324 if (macroeq("c2cbc")) conv=&c2cbc_converter; |
325 else if (macroeq("cbc2c")) conv=&cbc2c_converter; | |
326 else if (macroeq("c")) conv=&c_converter; | |
66 | 327 #else |
328 if (macroeq("c")) conv=&c_converter; | |
82 | 329 else conv=&null_converter; |
66 | 330 #endif |
59 | 331 } |
332 | |
61 | 333 static void |
0 | 334 reserve(char *s, int d) |
335 { | |
336 NMTBL *nptr; | |
337 int i; | |
338 | |
339 hash=0; name=namebuf; i=0; | |
340 while((name[i++] = *s)) { | |
341 hash=((7*hash) ^ *s++); | |
342 } | |
343 if (cheapp+i >= cheap+CHEAPSIZE) error(STRERR); | |
344 name[i++] = 0; | |
345 (nptr = gsearch())->sc = RESERVE; | |
19 | 346 if (d==0) { |
347 nptr->sc = MACRO; | |
29 | 348 nptr->dsp = (int)""; nptr->ty=0; |
19 | 349 } else { |
350 nptr->dsp = d; | |
351 } | |
0 | 352 } |
353 | |
354 static | |
355 NMTBL null_nptr; | |
356 | |
61 | 357 static void |
0 | 358 decl(void) |
359 { | |
360 NMTBL *n; | |
76 | 361 int t,sd; |
77 | 362 if (mode==GDECL) { typedefed=0; } |
0 | 363 |
364 if(sym==STATIC) { | |
365 if(mode==LDECL) { | |
366 getsym(); | |
69 | 367 conv->static_(); |
0 | 368 mode=STADECL; |
369 stmode=LDECL; | |
370 } else if(mode==GDECL) { | |
371 getsym(); | |
69 | 372 conv->static_(); |
0 | 373 stmode=STATIC; |
374 } else | |
375 error(DCERR); | |
376 } else if(sym==REGISTER) { | |
377 if(mode!=LDECL) | |
378 error(DCERR); | |
379 stmode=REGISTER; | |
380 getsym(); | |
69 | 381 conv->register_(); |
0 | 382 } else if(sym==EXTRN) { |
69 | 383 getsym(); |
66 | 384 conv->extern_(); |
0 | 385 stmode=EXTRN; |
386 } else if(sym==TYPEDEF) { | |
387 if(mode==GDECL) { | |
388 getsym(); | |
69 | 389 conv->typedef_(); |
0 | 390 mode=GTDECL; |
391 } else if(mode==LDECL) { | |
392 getsym(); | |
69 | 393 conv->typedef_(); |
0 | 394 mode=LTDECL; |
395 } else | |
396 error(DCERR); | |
397 } | |
398 if((t=typespec())==0) return; | |
66 | 399 if(sym==SM) { |
72 | 400 conv->return_type_(t,0,stypedecl); |
66 | 401 conv->sm_(); return; |
402 } | |
76 | 403 type=t;sd=stypedecl; |
0 | 404 n=decl0(); |
405 reverse(t); | |
406 if (n == &null_nptr) { | |
407 error(DCERR); | |
408 return; | |
409 } | |
410 if(sym==LC || ( sym!=SM && sym!=COMMA && sym!=ASS )) { | |
76 | 411 stypedecl=sd; |
0 | 412 if (car(type)==CODE) { |
413 code_decl(n); return; | |
414 } else if (car(type)==FUNCTION) { | |
415 fdecl(n); return; | |
66 | 416 } else error(TYERR); |
0 | 417 } |
75 | 418 conv->return_type_(type,n,sd); |
0 | 419 def(n); |
420 while(sym==COMMA) { | |
66 | 421 conv->comma_(); |
0 | 422 getsym(); |
423 type=t; | |
424 n=decl0(); | |
425 reverse(t); | |
426 if(n == &null_nptr) error(DCERR); | |
427 /* if(args) error(DCERR); */ | |
69 | 428 conv->return_type_(type,n,1); |
0 | 429 def(n); |
430 } | |
431 if(sym!=SM) error(DCERR); | |
66 | 432 conv->sm_(); |
0 | 433 if(mode==GTDECL) |
434 mode=GDECL; | |
435 if(mode==STADECL||mode==LTDECL) | |
436 mode=LDECL; | |
437 } | |
438 | |
61 | 439 static int |
0 | 440 typespec(void) |
441 { | |
442 int t; | |
72 | 443 stypedecl = 0; |
0 | 444 |
20 | 445 while (sym==KONST) { |
446 getsym(); | |
447 } | |
0 | 448 switch(sym) { |
449 case VOID: | |
450 case INT: | |
451 case CHAR: | |
452 case CODE: | |
78 | 453 case FLOAT: |
454 case DOUBLE: | |
0 | 455 t= sym; |
456 getsym(); | |
457 break; | |
458 case STRUCT: | |
459 case UNION: | |
460 t=sdecl(sym); | |
461 break; | |
462 case UNSIGNED: | |
463 t = UNSIGNED; | |
464 if(getsym()==INT) getsym(); | |
465 break; | |
466 case SHORT: | |
78 | 467 t=INT; |
0 | 468 if(getsym()==INT) getsym(); |
469 break; | |
470 case LONG: | |
471 t=INT; | |
78 | 472 getsym(); |
473 if(sym==LONG) { | |
474 getsym(); | |
475 t=LONGLONG; | |
476 } | |
477 if(sym==INT) getsym(); | |
0 | 478 break; |
479 default: | |
480 if(sym==IDENT) { | |
481 if(nptr->sc==TYPE) { | |
482 t=nptr->ty; | |
72 | 483 typedefed=glist2((int)nptr,typedefed); |
0 | 484 getsym(); |
485 break; | |
486 } else if(nptr->sc==EMPTY && gnptr->sc==TYPE) { | |
487 getsym(); | |
488 break; | |
489 } | |
490 } | |
20 | 491 while (sym==KONST) { |
492 getsym(); | |
493 } | |
0 | 494 if(mode==LDECL) return 0; |
495 t= INT; | |
496 } | |
20 | 497 while (sym==KONST) { |
498 getsym(); | |
499 } | |
0 | 500 return t; |
501 } | |
502 | |
61 | 503 static struct nametable * |
0 | 504 decl0(void) |
505 { | |
506 NMTBL *n; | |
507 if(sym==MUL) { | |
508 getsym(); | |
509 n=decl0(); | |
510 type=list2(POINTER,type); | |
511 return n; | |
512 } | |
513 return decl1(); | |
514 } | |
515 | |
516 | |
61 | 517 static NMTBL * |
0 | 518 decl1(void) |
519 { | |
520 NMTBL *n; | |
521 int i,t; | |
522 | |
523 if(sym==LPAR) { | |
524 getsym(); | |
525 n=decl0(); | |
526 checksym(RPAR); | |
527 } else if (sym == IDENT) { | |
528 n=nptr; | |
529 getsym(); | |
530 } else { | |
531 /* error(DCERR); */ | |
532 n= &null_nptr; | |
533 } | |
534 while(1) { | |
535 if(sym==LBRA) { | |
536 if(getsym()==RBRA) { | |
537 getsym(); | |
538 if(mode==ADECL) { | |
539 type=list2(POINTER,type); | |
540 } else if (mode==GDECL) { | |
79 | 541 type=list3(ARRAY,type,0); |
0 | 542 } else { |
543 error(DCERR); | |
544 } | |
545 } else { | |
546 t=type; | |
69 | 547 i=cexpr(expr(1)); |
0 | 548 checksym(RBRA); |
549 type=list3(ARRAY,t,i); | |
550 } | |
551 } else if(sym==LPAR) { | |
552 if(mode==GDECL) { | |
553 mode=ADECL;getsym();mode=GDECL; /* ??? */ | |
554 } else | |
555 getsym(); | |
77 | 556 n->dsp=0; |
557 if (type==CODE) { | |
87 | 558 n->ty=CODE; |
77 | 559 n->sc=EMPTY; |
560 if(sym==RPAR) { | |
87 | 561 getsym();t=0; |
77 | 562 } else { |
0 | 563 stmode=REGISTER; |
87 | 564 t=adecl(n); |
0 | 565 stmode=0; |
77 | 566 } |
87 | 567 type=list3(CODE,CODE,t); |
77 | 568 } else { |
569 n->ty=type; | |
570 n->sc=EMPTY; | |
571 if(sym==RPAR) { | |
87 | 572 getsym();t=0; |
77 | 573 } else |
87 | 574 t=adecl(n); |
575 type=list3(FUNCTION,type,t); | |
0 | 576 } |
87 | 577 /* in GDECL mode dsp contains real parameter, if not, |
578 it contains arg type list. Real parameter list is compatible | |
579 with arg type list. See def/ADECL */ | |
580 if (mode!=GDECL) | |
581 n->dsp=t; | |
0 | 582 } else |
583 return n; | |
584 } | |
77 | 585 /* NOT REACHED */ |
0 | 586 } |
587 | |
588 | |
87 | 589 static int |
0 | 590 adecl(NMTBL *n) |
591 { | |
592 NMTBL *arg,*sfnptr; | |
593 int sreg_var,t; | |
79 | 594 int stype,smode,sd,sargs; |
87 | 595 int argtypes; |
0 | 596 |
597 stype=type; | |
598 sfnptr=fnptr; | |
599 fnptr=n; | |
76 | 600 sd = sdecl_f; |
601 sdecl_f = 0; | |
0 | 602 sreg_var=reg_var; |
603 reg_var=0; | |
87 | 604 argtypes = 0; |
16 | 605 smode = mode; |
0 | 606 mode=ADECL; |
46
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
607 args = 0; |
67 | 608 n->dsp=0; |
0 | 609 for(;;) { |
610 if(sym==IDENT && nptr->sc!=TYPE) { | |
76 | 611 type=INT; /* naked argument, old K&R C */ |
46
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
612 def(nptr); |
0 | 613 getsym(); |
614 if(sym==RPAR) break; | |
615 } else { | |
616 if(sym==DOTS) { | |
87 | 617 argtypes=list2(DOTS,argtypes); |
0 | 618 getsym(); |
619 break; | |
620 } | |
621 if((t=typespec())==0) { | |
622 error(DCERR); | |
623 break; | |
624 } | |
625 if(sym!=COMMA && sym!=RPAR) { | |
626 if(sym==RPAR) break; | |
627 type=t; | |
79 | 628 sargs = args; |
0 | 629 arg=decl0(); |
79 | 630 args = sargs; |
0 | 631 reverse(t); |
67 | 632 if (arg != &null_nptr) { |
633 if (smode==GDECL) | |
634 def(arg); | |
87 | 635 } |
636 argtypes=list2(type,argtypes); | |
0 | 637 } |
638 if(sym==RPAR) break; | |
639 } | |
640 if (sym!=COMMA) error(DCERR); | |
641 getsym(); | |
642 } | |
87 | 643 argtypes=reverse0(argtypes); |
67 | 644 n->dsp=reverse0(n->dsp); |
0 | 645 checksym(RPAR); |
16 | 646 mode=smode; |
0 | 647 reg_var=sreg_var; |
648 fnptr=sfnptr; | |
649 type=stype; | |
76 | 650 sdecl_f = sd; |
87 | 651 return argtypes; |
0 | 652 } |
653 | |
61 | 654 static void |
0 | 655 reverse(int t1) |
656 { | |
657 int t2,t3; | |
658 t2=t1; | |
659 | |
660 while(type!=t1) { | |
661 t3=cadr(type); | |
662 rplacad(type,t2); | |
663 t2=type; | |
664 type=t3; | |
665 } | |
666 type = t2; | |
667 } | |
668 | |
669 int | |
670 reverse0(int t1) | |
671 { | |
672 int t2,t3; | |
673 | |
674 t2=0; | |
675 while(t1) { | |
676 t3=cadr(t1); | |
677 rplacad(t1,t2); | |
678 t2=t1; | |
679 t1=t3; | |
680 } | |
681 return t2; | |
682 } | |
683 | |
684 int | |
685 size(int t) | |
686 { | |
687 if(t==CHAR) return 1; | |
688 if(t==VOID) return 0; | |
76 | 689 if(t==REGISTER) return size_of_int; /* could be float? */ |
3 | 690 if(scalar(t)) return size_of_int; |
81 | 691 if(t==FLOAT) return size_of_float; |
692 if(t==DOUBLE) return size_of_double; | |
693 if(t==LONGLONG) return size_of_longlong; | |
0 | 694 if(car(t)==STRUCT||car(t)==UNION) { |
695 if(cadr(t)==-1) error(DCERR); | |
696 return(cadr(t)); | |
697 } | |
698 if(car(t)==ARRAY) | |
699 return(size(cadr(t))*caddr(t)); | |
77 | 700 else if(car(t)==CODE) |
701 return size_of_int; | |
702 else if(car(t)==FUNCTION) | |
703 return size_of_int; | |
0 | 704 else |
705 error(DCERR); | |
706 return 0; | |
707 } | |
708 | |
61 | 709 static NMTBL * |
0 | 710 def(NMTBL *n) |
711 { | |
81 | 712 int sz,nsc,ndsp; |
0 | 713 |
67 | 714 conv->def_(n); |
37 | 715 if (n==0) { |
716 n=free_nptr(); | |
717 n->nm = "_"; | |
718 } | |
0 | 719 nsc=ndsp=0; |
720 if(car(type)==FUNCTION) { | |
53 | 721 if (n->sc==EXTRN || (mode==GDECL)) { |
722 fcheck(n); | |
723 return n; | |
724 } | |
0 | 725 } |
726 if (n->sc!=EMPTY && | |
727 !(n->sc==GVAR&&n->dsp==EXTRN) && | |
728 !(n->sc==FUNCTION&&n->dsp==EXTRN) && | |
729 (mode!=ADECL || n->sc!=LVAR || n->ty!=INT) && | |
730 (mode!=ADECL || n->sc!=REGISTER || n->ty!=INT) && | |
731 ((mode!=GSDECL&&mode!=LSDECL) || n->sc!=FIELD || n->dsp!=disp) && | |
732 ((mode!=GUDECL&&mode!=LUDECL) || n->sc!=FIELD || n->dsp!=0) ) | |
733 error(DCERR); | |
734 sz = size(n->ty = type); | |
735 switch(mode) { | |
736 case GDECL: | |
737 gen_gdecl(n->nm,gpc); | |
738 case STADECL: | |
739 nsc = GVAR; | |
740 ndsp = gpc; | |
741 if (stmode==EXTRN) | |
742 n->dsp = EXTRN; | |
743 else | |
744 n->dsp = ndsp; /* emit_data will override this */ | |
745 n->sc = nsc; | |
746 if (stmode==LDECL) { | |
747 copy(n,n->nm); | |
748 cheapp[-1] = '.'; | |
749 ndsp = ++stat_no; | |
750 while(ndsp>0) { | |
751 *cheapp++ = ndsp%10+'0'; | |
752 ndsp /= 10; | |
753 } | |
754 *cheapp++ = 0; | |
755 } | |
756 if(sym==ASS) { | |
76 | 757 conv->op_(sym); |
13 | 758 decl_data(type,n,0); |
0 | 759 emit_data_closing(n); |
760 /* gpc is incremented by emit_data */ | |
761 } else | |
762 gpc +=sz; | |
37 | 763 return n; |
0 | 764 case GSDECL: |
765 nsc = FIELD; | |
766 ndsp = disp; | |
767 disp += sz; | |
768 break; | |
769 case GUDECL: | |
770 nsc = FIELD; | |
771 ndsp = 0; | |
772 if (disp < sz) disp = sz; | |
773 break; | |
774 case GTDECL: | |
775 nsc = TYPE; | |
75 | 776 if (gnptr!=n) error(-1); |
777 gtypedefed=glist2((int)gnptr,gtypedefed); | |
0 | 778 break; |
779 case ADECL: | |
79 | 780 if(!integral(type)&&(car(type)==FUNCTION||car(type)==CODE)) { |
781 type=list2(POINTER,type); n->ty = type; | |
782 } | |
783 fnptr->dsp=list4(type,fnptr->dsp,(int)n,0); | |
53 | 784 if (stmode==REGISTER && reg_var <MAX_REGISTER_VAR && |
80 | 785 size(type)==size_of_int) { |
39 | 786 n->sc = REGISTER; |
0 | 787 reg_var++; |
79 | 788 cadddr(fnptr->dsp)=size_of_int; |
37 | 789 return n; |
0 | 790 } |
39 | 791 n->sc = LVAR; |
0 | 792 if(type==CHAR) { |
39 | 793 if (n->dsp==0) { |
794 n->dsp = args; | |
0 | 795 if (endian) |
3 | 796 n->dsp += size_of_int-1; |
0 | 797 } |
3 | 798 args += size_of_int; |
0 | 799 } else { |
39 | 800 if (n->dsp==0) |
801 n->dsp = args; | |
0 | 802 args += sz; |
803 } | |
79 | 804 cadddr(fnptr->dsp)=sz; |
0 | 805 if(type==VOID) { |
81 | 806 } else { |
807 n->ty = type; | |
0 | 808 } |
37 | 809 return n; |
810 case STAT: /* of course this is wrong */ | |
0 | 811 case LDECL: |
812 if (stmode==REGISTER && reg_var <=MAX_REGISTER_VAR) { | |
813 if(!scalar(type)) /* non integer register type ... */ | |
814 error(DCERR); | |
815 nsc = REGISTER; | |
816 reg_var++; | |
77 | 817 if ((ndsp = get_register_var())<0) |
818 error(-1); | |
0 | 819 } else { |
820 nsc = LVAR; | |
821 ndsp = (disp -= sz); | |
822 } | |
14 | 823 n->sc = nsc; |
824 n->dsp = ndsp; | |
0 | 825 if(sym==ASS) { |
76 | 826 conv->op_(sym); |
13 | 827 decl_data(type,n,0); |
0 | 828 } |
37 | 829 return n; |
0 | 830 case LSDECL: |
831 nsc = FIELD; | |
832 ndsp = disp; | |
833 disp += sz; | |
834 break; | |
835 case LUDECL: | |
836 nsc = FIELD; | |
837 ndsp = 0; | |
838 if (disp < sz) disp = sz; | |
839 break; | |
840 case LTDECL: | |
841 nsc = TYPE; | |
842 break; | |
843 default: | |
844 error(DCERR); | |
845 } | |
846 n->sc = nsc; | |
847 if (stmode==EXTRN) | |
848 n->dsp = EXTRN; | |
849 else | |
850 n->dsp = ndsp; | |
37 | 851 return n; |
0 | 852 } |
853 | |
61 | 854 static void |
0 | 855 emit_init_vars(void) |
856 { | |
13 | 857 if (!init_vars) return; |
858 init_vars = reverse0(init_vars); | |
0 | 859 while(init_vars) { |
83 | 860 gexpr(car(init_vars),0); |
0 | 861 init_vars = cadr(init_vars); |
862 } | |
863 } | |
864 | |
13 | 865 int |
866 assign_data(int e, int t, NMTBL *n,int offset) | |
0 | 867 { |
868 int ass; | |
869 | |
870 if(mode==GDECL) { | |
13 | 871 emit_data(e,t,n); |
872 return offset+size(t); | |
0 | 873 } else if(mode==LDECL) { |
82 | 874 ass = assign_expr0(list2(LVAR,n->dsp+offset),e,t,type); |
0 | 875 init_vars = list2(ass,init_vars); |
13 | 876 return offset+size(t); |
0 | 877 } else { |
878 error(DCERR); | |
879 } | |
18 | 880 return 0; /* not reached */ |
0 | 881 } |
882 | |
61 | 883 static int |
13 | 884 decl_data(int t, NMTBL *n,int offset) |
0 | 885 { |
32 | 886 int t1,e,i,mode_save; |
0 | 887 |
69 | 888 conv->decl_data_(); |
32 | 889 mode_save = mode; |
890 mode=STAT; | |
0 | 891 getsym(); |
892 if (scalar(t)) { | |
893 e=expr1(); | |
32 | 894 mode = mode_save; |
0 | 895 if(car(e)!=CONST && t==CHAR) |
896 error(TYERR); | |
13 | 897 offset = assign_data(e,t,n,offset); |
0 | 898 type=t; |
13 | 899 return offset; |
0 | 900 } |
82 | 901 if (t==FLOAT||t==DOUBLE) { |
902 e=expr1(); | |
903 mode = mode_save; | |
904 offset = assign_data(e,t,n,offset); | |
905 type=t; | |
906 return offset; | |
907 } | |
0 | 908 t1 = car(t); |
909 if (t1==ARRAY) { | |
910 if (sym==LC) { | |
66 | 911 conv->decl_data_begin_(); |
32 | 912 mode = mode_save; |
0 | 913 t1 = cadr(t); |
914 for(i=0;;i++) { | |
915 if (sym!=RC) | |
32 | 916 offset=decl_data(t1,n,offset); /* array of some thing */ |
66 | 917 if (sym==COMMA) { |
918 conv->comma_(); | |
919 continue; | |
0 | 920 } else if (sym==RC) { |
66 | 921 conv->decl_data_end_(); |
13 | 922 if (caddr(t)==0) { /* size not defined */ |
923 heap[t+2]=i+1; /* define array size */ | |
924 } else if (caddr(t)!=i+1) { /* size match? */ | |
0 | 925 error(TYERR); |
926 } | |
927 getsym(); | |
13 | 928 return offset; |
0 | 929 } else { |
930 error(TYERR); | |
931 } | |
932 } | |
66 | 933 /* NOT REACHED */ |
0 | 934 } else if (cadr(t)==CHAR) { |
935 e=expr1(); | |
32 | 936 mode = mode_save; |
0 | 937 if(car(e)!=STRING) |
938 error(TYERR); | |
13 | 939 offset=assign_data(e,list3(ARRAY,CHAR,size(type)),n,offset); |
940 if (caddr(t)==0) { /* size not defined */ | |
941 heap[t+2]=size(type); /* define array size */ | |
942 } else if (caddr(t)!=size(type)) { /* size match? */ | |
943 error(TYERR); | |
944 } | |
0 | 945 } else |
946 error(DCERR); | |
947 } else if (t1==STRUCT) { | |
76 | 948 if (sym==LC) { |
949 conv->lc_(); conv->decl_data_begin_(); | |
950 mode = mode_save; | |
951 if(cadr(t)==-1) error(DCERR); | |
952 t1 = caddr(t); /* list of fields */ | |
953 while(t1) { | |
954 offset = decl_data(car(t1),n,offset); /* alignment? */ | |
955 t1 = cadr(t1); | |
956 if ( t1 && sym==COMMA) { conv->comma_(); continue; } | |
957 if (!t1 && sym!=RC) error(DCERR); | |
958 } | |
959 conv->decl_data_end_(); conv->rc_(); | |
960 getsym(); | |
961 return offset; | |
962 } else | |
963 error(DCERR); | |
0 | 964 } else { |
32 | 965 mode = mode_save; |
0 | 966 error(TYERR); /* should be initialization error */ |
967 } | |
18 | 968 return offset; /* not reached */ |
0 | 969 } |
970 | |
61 | 971 static int |
0 | 972 sdecl(int s) |
973 { | |
18 | 974 int smode,sdisp,type0; |
0 | 975 NMTBL *nptr0,*gnptr0; |
976 int tags; | |
977 | |
978 smode=mode; | |
979 if (mode==GDECL || mode==GSDECL || mode==GUDECL || mode==GTDECL) | |
980 mode=(s==STRUCT?GSDECL:GUDECL); | |
981 else | |
982 mode=(s==STRUCT?LSDECL:LUDECL); | |
983 sdisp=disp; | |
984 disp=0; | |
76 | 985 if (sdecl_f) conv->sdecl_(s); |
0 | 986 if (getsym() == IDENT) { |
987 nptr0 = nptr; | |
988 gnptr0 = gnptr; | |
76 | 989 if (sdecl_f) conv->id_(sym,nptr); |
0 | 990 if (getsym() == LC) { |
76 | 991 if (sdecl_f) conv->lc_(); |
0 | 992 if (nptr0->sc != EMPTY) error(DCERR); |
993 nptr0->sc = TAG; | |
994 tags = 0; | |
67 | 995 nptr0->ty = list4(s,-1,tags,(int)nptr0); |
0 | 996 while (getsym() != RC) { |
997 decl(); | |
67 | 998 tags = list3(type,tags,(int)nptr); |
0 | 999 } |
76 | 1000 if (sdecl_f) conv->rc_(); |
0 | 1001 getsym(); |
1002 tags=reverse0(tags); | |
1003 heap[nptr0->ty+2]=tags; | |
1004 rplacad(type0 = nptr0->ty,disp); | |
1005 } else { | |
13 | 1006 /* struct tag name */ |
0 | 1007 if(nptr0->sc == EMPTY) nptr0=gnptr0; |
1008 if(nptr0->sc == EMPTY) error(UDERR); | |
1009 if(nptr0->sc != TAG) error(TYERR); | |
13 | 1010 tags = caddr(nptr0->ty); |
1011 disp = cadr(nptr0->ty); | |
76 | 1012 conv->comment_(' '); |
0 | 1013 } |
67 | 1014 type0 = list4(s,disp,tags,(int)nptr0); |
0 | 1015 } else if(sym==LC) { |
76 | 1016 if (sdecl_f) conv->lc_(); |
0 | 1017 tags = 0; |
1018 while(getsym() != RC) { | |
1019 decl(); | |
67 | 1020 tags = list3(type,tags,(int)nptr); |
0 | 1021 } |
76 | 1022 if (sdecl_f) conv->rc_(); |
0 | 1023 getsym(); |
1024 tags=reverse0(tags); | |
67 | 1025 type0 = list4(s,disp,tags,0); |
0 | 1026 } |
1027 else error(DCERR); | |
72 | 1028 stypedecl=1; |
0 | 1029 disp=sdisp; |
1030 mode=smode; | |
1031 return type0; | |
1032 } | |
1033 | |
61 | 1034 static void |
0 | 1035 code_decl(NMTBL *n) |
1036 { | |
79 | 1037 int t,arglist; |
53 | 1038 |
0 | 1039 if (n->sc==EMPTY) n->sc = CODE; |
66 | 1040 if(!chk) code_enter(n->nm); |
0 | 1041 fnptr=n; |
3 | 1042 disp = -args; |
0 | 1043 mode=ADECL; |
76 | 1044 if (sym!=LC) { |
1045 stmode=REGISTER; | |
1046 reg_var=0; | |
79 | 1047 args=0; fnptr->dsp=0; |
76 | 1048 while (sym!=LC) { /* argument declaration !ANSI */ |
1049 decl(); getsym(); | |
1050 } | |
1051 fnptr->dsp=reverse0(fnptr->dsp); | |
1052 disp = -args; | |
0 | 1053 } |
53 | 1054 /* reverse all argument offset (with size) */ |
79 | 1055 arglist = fnptr->dsp; |
53 | 1056 for(t=arglist;t;t=cadr(t)) { |
79 | 1057 n=(NMTBL *)caddr(t); |
53 | 1058 if(n->sc==LVAR) |
79 | 1059 n->dsp = -n->dsp-cadddr(t); |
53 | 1060 } |
79 | 1061 arg_register(fnptr); |
1062 conv->code_(fnptr); | |
70 | 1063 typedefed=0; |
0 | 1064 /* local variable declaration */ |
1065 stmode=0; | |
1066 mode=STAT; | |
1067 init_vars=0; | |
1068 while (typeid(getsym()) || sym==STATIC || sym==EXTRN || sym==TYPEDEF) { | |
1069 mode=LDECL; | |
1070 decl(); | |
1071 mode=STAT; | |
1072 } | |
66 | 1073 conv->localvar_end_(); |
0 | 1074 control=1; |
66 | 1075 if(!chk) code_enter1(args); |
0 | 1076 emit_init_vars(); |
1077 while(sym!=RC) statement(); | |
1078 if(control) | |
1079 error(STERR); | |
1080 control=0; | |
66 | 1081 conv->code_end_(); |
1082 if(!chk) code_leave(n->nm); | |
79 | 1083 args = 0; |
0 | 1084 } |
1085 | |
45 | 1086 static NMTBL *tmp_struct; |
1087 | |
61 | 1088 static void |
0 | 1089 fdecl(NMTBL *n) |
1090 { | |
75 | 1091 int sd = stypedecl; |
66 | 1092 if(!chk) enter(n->nm); |
0 | 1093 fnptr=n; |
1094 retlabel=fwdlabel(); | |
1095 retcont = 0; | |
45 | 1096 tmp_struct = 0; |
0 | 1097 |
1098 reg_var=0; | |
1099 fcheck(n); | |
1100 mode=ADECL; | |
67 | 1101 if (sym!=LC) { |
79 | 1102 args=0; fnptr->dsp=0; |
67 | 1103 while (sym!=LC) { /* argument declaration !ANSI */ |
1104 stmode=0; | |
1105 decl(); getsym(); | |
1106 } | |
79 | 1107 } else |
67 | 1108 fnptr->dsp=reverse0(fnptr->dsp); |
46
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1109 fdecl_struct(fnptr->ty); |
79 | 1110 arg_register(fnptr); |
70 | 1111 typedefed=0; |
79 | 1112 conv->function_(fnptr,sd); conv->lc_(); |
0 | 1113 disp=0; |
1114 init_vars=0; | |
1115 /* local variable declaration */ | |
1116 mode=STAT; | |
1117 while (typeid(getsym()) || sym==STATIC || sym==EXTRN | |
1118 || sym==REGISTER || sym==TYPEDEF) { | |
1119 mode=LDECL; | |
1120 stmode=0; | |
1121 decl(); | |
1122 mode=STAT; | |
1123 } | |
66 | 1124 conv->localvar_end_(); |
0 | 1125 control=1; |
66 | 1126 if(!chk) enter1(); |
0 | 1127 emit_init_vars(); |
1128 while(sym!=RC) statement(); | |
1129 | |
68 | 1130 conv->function_end_(); conv->rc_(); |
66 | 1131 if(!chk) leave(control,n->nm); |
0 | 1132 retpending = 0; |
1133 control=0; | |
75 | 1134 arglist=0; |
0 | 1135 } |
1136 | |
76 | 1137 extern NMTBL str_ret; |
1138 NMTBL str_ret; | |
46
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1139 |
66 | 1140 /* |
1141 If function has structure return value, it has extra | |
1142 argument for where to write the structure. It have to be | |
1143 a first argument. We add it here and we have to fix all arguments' | |
1144 offset. If it is the last value, we don't have to fix, but | |
1145 gcc has a first argument convention. | |
1146 */ | |
1147 | |
61 | 1148 static void |
46
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1149 fdecl_struct(int fntype) |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1150 { |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1151 int type_save,mode_save,t,sz; |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1152 NMTBL *n; |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1153 |
67 | 1154 t = fntype; |
46
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1155 if (!scalar(t) && (car(t)==STRUCT||car(t)==UNION)) { |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1156 mode_save = mode; |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1157 mode=ADECL; |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1158 type_save = type; |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1159 /* extra argument for struct return */ |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1160 /* this extra dummy arguments are set at calling sequence */ |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1161 str_ret.nm = "str_ret"; str_ret.sc = EMPTY; |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1162 str_ret.dsp = 0; str_ret.ty = 0; |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1163 type=list2(POINTER,t); |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1164 /* fix all arguments's offset */ |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1165 sz = size(type); |
79 | 1166 for(t=fnptr->dsp;t;t=cadr(t)) { |
1167 n=(NMTBL *)caddr(t); | |
46
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1168 n->dsp += sz; |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1169 } |
79 | 1170 fnptr->dsp = reverse0(fnptr->dsp); |
67 | 1171 if ((t=size(fntype))==-1) error(TYERR); |
46
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1172 else { |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1173 args = 0; |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1174 def(&str_ret); |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1175 struct_return = list3(list2(LVAR,str_ret.dsp),t,type); |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1176 } |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1177 type = type_save; |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1178 mode = mode_save; |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1179 } else { |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1180 struct_return = 0; |
79 | 1181 fnptr->dsp = reverse0(fnptr->dsp); |
46
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1182 } |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1183 } |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1184 |
0 | 1185 void |
1186 fcheck(NMTBL *n) | |
1187 { | |
53 | 1188 if(!(mode==GDECL||mode==ADECL)||car(type)!=FUNCTION) error(DCERR); |
67 | 1189 if(n->sc==FUNCTION) compatible(n->ty,cadr(type)); |
0 | 1190 else { |
1191 if(n->sc!=EMPTY) | |
1192 error(DCERR); | |
1193 else { | |
1194 n->sc=FUNCTION; | |
67 | 1195 n->ty=cadr(type); |
0 | 1196 } |
1197 } | |
1198 } | |
1199 | |
61 | 1200 static void |
0 | 1201 compatible(int t1, int t2) |
1202 { | |
1203 if(integral(t1)) { | |
1204 if(t1!=t2) error(TYERR); | |
1205 } | |
1206 else if(car(t1)!=car(t2)) | |
1207 error(TYERR); | |
1208 else if((car(t1)==STRUCT || car(t1)==UNION) && cadr(t1)!=cadr(t2)) | |
1209 error(TYERR); | |
1210 else if(car(t1)==POINTER || car(t1)==ARRAY ||car(t1)==FUNCTION) | |
1211 compatible(cadr(t1),cadr(t2)); | |
1212 } | |
1213 | |
1214 int | |
1215 scalar(int t) | |
1216 { | |
1217 return(integral(t)||car(t)==POINTER); | |
1218 } | |
1219 | |
1220 int | |
1221 integral(int t) | |
1222 { | |
1223 return(t==INT||t==CHAR||t==UNSIGNED); | |
1224 } | |
1225 | |
61 | 1226 static void |
0 | 1227 checkret(void) |
1228 { | |
1229 if (retpending) { | |
1230 ret(); | |
1231 control=0; | |
1232 retpending=0; | |
1233 } | |
1234 } | |
1235 | |
61 | 1236 static void |
0 | 1237 statement(void) |
1238 { | |
1239 int slfree; | |
1240 | |
1241 if(sym==SM) { | |
66 | 1242 conv->sm_(); |
0 | 1243 getsym(); return; |
1244 } | |
1245 checkret(); | |
1246 switch(sym) { | |
1247 case IF: | |
1248 doif(); | |
1249 return; | |
1250 case WHILE: | |
1251 dowhile(); | |
1252 return; | |
1253 case DO: | |
1254 dodo(); | |
1255 return; | |
1256 case FOR: | |
1257 dofor(); | |
1258 return; | |
1259 case SWITCH: | |
1260 doswitch(); | |
1261 return; | |
1262 case LC: | |
1263 docomp(); | |
1264 return; | |
1265 case BREAK: | |
69 | 1266 conv->break_(); |
0 | 1267 jmp(blabel); |
1268 getsym(); | |
1269 checksym(SM); | |
1270 return; | |
1271 case CONTINUE: | |
69 | 1272 conv->continue_(); |
0 | 1273 jmp(clabel); |
1274 getsym(); | |
1275 checksym(SM); | |
1276 return; | |
1277 case CASE: | |
1278 docase(); | |
1279 statement(); | |
1280 return; | |
1281 case DEFAULT: | |
1282 dodefault(); | |
1283 statement(); | |
1284 return; | |
1285 case RETURN: | |
1286 doreturn(); | |
1287 return; | |
1288 case GOTO: | |
1289 dogoto(); | |
1290 return; | |
1291 default: | |
1292 if(sym==IDENT&&skipspc()==':') { | |
1293 dolabel(); | |
1294 statement(); | |
1295 } else { | |
1296 slfree=lfree; | |
83 | 1297 gexpr(expr(0),0); |
0 | 1298 lfree=slfree; |
69 | 1299 conv->sm_(); |
0 | 1300 checksym(SM); |
1301 } | |
1302 } | |
1303 } | |
1304 | |
61 | 1305 static void |
0 | 1306 doif(void) |
1307 { | |
1308 int l1,l2,slfree; | |
1309 getsym(); | |
1310 checksym(LPAR); | |
66 | 1311 conv->if_(); |
0 | 1312 slfree=lfree; |
69 | 1313 bexpr(expr(0),0,l1=fwdlabel()); |
0 | 1314 lfree=slfree; |
71 | 1315 conv->if_then_(); |
0 | 1316 checksym(RPAR); |
1317 statement(); | |
1318 checkret(); | |
1319 if(sym==ELSE) { | |
66 | 1320 conv->if_else_(); |
0 | 1321 if ((l2 = control)) |
1322 jmp(l2=fwdlabel()); | |
1323 fwddef(l1); | |
1324 getsym(); | |
1325 statement(); | |
1326 checkret(); | |
1327 if (l2) fwddef(l2); | |
1328 } | |
1329 else fwddef(l1); | |
66 | 1330 conv->if_endif_(); |
0 | 1331 } |
1332 | |
61 | 1333 static void |
0 | 1334 dowhile(void) |
1335 { | |
1336 int sbreak,scontinue,slfree,e; | |
1337 | |
1338 sbreak=blabel; | |
1339 scontinue=clabel; | |
1340 blabel=fwdlabel(); | |
1341 clabel=backdef(); | |
66 | 1342 conv->while_(); |
0 | 1343 getsym(); |
1344 checksym(LPAR); | |
1345 slfree=lfree; | |
69 | 1346 e=expr(0); |
0 | 1347 checksym(RPAR); |
66 | 1348 conv->while_body_(); |
0 | 1349 if(sym==SM) { |
1350 bexpr(e,1,clabel); | |
1351 lfree=slfree; | |
72 | 1352 conv->sm_(); |
0 | 1353 getsym(); |
1354 } else { | |
1355 bexpr(e,0,blabel); | |
1356 lfree=slfree; | |
1357 statement(); | |
1358 checkret(); | |
1359 if(control) | |
1360 jmp(clabel); | |
1361 } | |
66 | 1362 conv->while_end_(); |
0 | 1363 fwddef(blabel); |
1364 clabel=scontinue; | |
1365 blabel=sbreak; | |
1366 } | |
1367 | |
61 | 1368 static void |
0 | 1369 dodo(void) |
1370 { | |
1371 int sbreak,scontinue,l,slfree; | |
1372 | |
1373 sbreak=blabel; | |
1374 scontinue=clabel; | |
1375 blabel=fwdlabel(); | |
1376 clabel=fwdlabel(); | |
1377 l=backdef(); | |
66 | 1378 conv->dowhile_(); |
0 | 1379 getsym(); |
1380 statement(); | |
1381 checkret(); | |
1382 fwddef(clabel); | |
1383 checksym(WHILE); | |
1384 checksym(LPAR); | |
1385 slfree=lfree; | |
66 | 1386 conv->dowhile_cond_(); |
69 | 1387 bexpr(expr(0),1,l); |
0 | 1388 lfree=slfree; |
1389 checksym(RPAR); | |
72 | 1390 conv->dowhile_end_(); |
0 | 1391 checksym(SM); |
1392 fwddef(blabel); | |
1393 clabel=scontinue; | |
1394 blabel=sbreak; | |
1395 } | |
1396 | |
61 | 1397 static void |
0 | 1398 dofor(void) |
1399 { | |
1400 int sbreak,scontinue,l,e,slfree; | |
1401 | |
1402 sbreak=blabel; | |
1403 scontinue=clabel; | |
1404 blabel=fwdlabel(); | |
66 | 1405 conv->for_(); |
0 | 1406 getsym(); |
1407 checksym(LPAR); | |
1408 slfree=lfree; | |
1409 if(sym!=SM) { | |
83 | 1410 gexpr(expr(0),0); |
0 | 1411 checksym(SM); |
69 | 1412 conv->for1_(); |
72 | 1413 } else { |
1414 conv->for1_(); | |
1415 getsym(); | |
0 | 1416 } |
1417 lfree=slfree; | |
1418 l=backdef(); | |
1419 if(sym!=SM) { | |
69 | 1420 bexpr(expr(0),0,blabel); |
0 | 1421 checksym(SM); |
69 | 1422 conv->for2_(); |
72 | 1423 } else { |
1424 conv->for2_(); | |
1425 getsym(); | |
0 | 1426 } |
1427 lfree=slfree; | |
1428 if(sym==RPAR) { | |
1429 clabel=l; | |
69 | 1430 conv->for_body_(); |
0 | 1431 getsym(); |
1432 statement(); | |
1433 checkret(); | |
1434 } else { | |
1435 clabel=fwdlabel(); | |
69 | 1436 e=expr(0); |
66 | 1437 conv->for_body_(); |
0 | 1438 checksym(RPAR); |
1439 statement(); | |
1440 checkret(); | |
1441 fwddef(clabel); | |
83 | 1442 gexpr(e,0); |
0 | 1443 lfree=slfree; |
1444 } | |
66 | 1445 conv->for_end_(); |
0 | 1446 jmp(l); |
1447 fwddef(blabel); | |
1448 clabel=scontinue; | |
1449 blabel=sbreak; | |
1450 } | |
1451 | |
61 | 1452 static void |
0 | 1453 doswitch(void) |
1454 { | |
1455 int sbreak,scase,sdefault,slfree,svalue; | |
1456 | |
1457 sbreak=blabel; /* save parents break label */ | |
1458 blabel=fwdlabel(); | |
1459 sdefault=dlabel; /* save parents default label */ | |
1460 dlabel=0; | |
1461 scase=cslabel; /* save parents next case label */ | |
66 | 1462 conv->switch_(); |
0 | 1463 getsym(); |
1464 checksym(LPAR); | |
1465 slfree=lfree; | |
1466 svalue=csvalue1; /* save parents switch value */ | |
83 | 1467 gexpr(expr(0),1); |
42 | 1468 csvalue1=csvalue() ; |
0 | 1469 lfree=slfree; |
1470 checksym(RPAR); | |
66 | 1471 conv->switch_body_(); |
0 | 1472 cslabel = control = 0; |
1473 /* should be case statement but... */ | |
1474 statement(); | |
66 | 1475 conv->switch_end_(); |
0 | 1476 checkret(); |
1477 if(dlabel) def_label(cslabel,dlabel); | |
1478 else fwddef(cslabel); | |
1479 csvalue1=svalue; | |
1480 cslabel=scase; | |
1481 dlabel=sdefault; | |
1482 fwddef(blabel); | |
1483 blabel=sbreak; | |
1484 } | |
1485 | |
61 | 1486 static void |
0 | 1487 docomp(void) |
1488 { | |
66 | 1489 conv->lc_(); |
0 | 1490 getsym(); |
1491 while(sym!=RC) { statement(); checkret();} | |
66 | 1492 conv->rc_(); |
0 | 1493 getsym(); |
1494 } | |
1495 | |
61 | 1496 static void |
0 | 1497 docase(void) |
1498 { | |
1499 int c,l,slfree; | |
1500 | |
1501 c=0; | |
1502 slfree=lfree; | |
1503 while(sym==CASE) { | |
67 | 1504 conv->case_begin_(c,0); |
0 | 1505 getsym(); |
69 | 1506 c=list2(cexpr(expr(1)),c); |
66 | 1507 conv->case_(c,0); |
0 | 1508 checksym(COLON); |
1509 } | |
1510 l=fwdlabel(); | |
1511 if (control) { | |
1512 control=0; | |
1513 jmp(l); | |
1514 } | |
1515 if (cslabel) fwddef(cslabel); | |
1516 while(cadr(c)) { | |
1517 cmpdimm(car(c),csvalue1); | |
1518 jcond(l,0); | |
1519 c=cadr(c); | |
1520 } | |
1521 lfree=slfree; | |
1522 cmpdimm(car(c),csvalue1); | |
1523 jcond(cslabel=fwdlabel(),1); | |
1524 fwddef(l); | |
1525 } | |
1526 | |
61 | 1527 static void |
0 | 1528 dodefault(void) |
1529 { | |
1530 getsym(); | |
1531 checksym(COLON); | |
1532 if (dlabel) error(STERR); | |
1533 if (!cslabel) jmp(cslabel = fwdlabel()); | |
1534 dlabel = backdef(); | |
66 | 1535 conv->case_(0,1); |
0 | 1536 } |
1537 | |
61 | 1538 static void |
0 | 1539 doreturn(void) |
1540 { | |
39 | 1541 int slfree,e,e1; |
0 | 1542 |
1543 if(getsym()==SM) { | |
71 | 1544 conv->return_(); |
1545 conv->return_end_(); | |
0 | 1546 getsym(); |
1547 retpending = 1; | |
1548 return; | |
1549 } | |
66 | 1550 conv->return_(); |
0 | 1551 slfree=lfree; |
37 | 1552 if (struct_return) { |
69 | 1553 e = expr(0); |
37 | 1554 if ((car(type)==STRUCT || car(type)==UNION)&& |
1555 size(type)==cadr(struct_return)) { | |
46
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1556 if(car(e)==RSTRUCT && car(cadr(e))==FUNCTION) { |
83 | 1557 /* pass the return pointer to the called function */ |
46
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1558 replace_return_struct(cadr(e), |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1559 rvalue_t(car(struct_return),caddr(struct_return))); |
83 | 1560 gexpr(cadr(e),0); |
46
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1561 } else { |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1562 e = rvalue(e); |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1563 type = caddr(struct_return); |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1564 e1 = rvalue_t(cadr(struct_return),INT); /* size */ |
83 | 1565 gexpr(list4(SASS,rvalue(car(struct_return)),e,e1),0); |
46
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1566 } |
37 | 1567 } else { |
39 | 1568 error(TYERR); /* should check compatible */ |
37 | 1569 } |
1570 } else { | |
83 | 1571 gexpr(expr(0),1); |
37 | 1572 } |
0 | 1573 lfree=slfree; |
69 | 1574 conv->return_end_(); |
0 | 1575 checksym(SM); |
39 | 1576 /* control = 0; still control continue until pending return emittion */ |
0 | 1577 retpending = 1; |
1578 } | |
1579 | |
39 | 1580 void |
1581 replace_return_struct(int func,int left) { | |
46
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1582 int e = caddr(func); /* arg lists */ |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1583 while(cadr(e)) e=cadr(e); /* find first arg */ |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
1584 e = car(e); /* return_struct arg */ |
39 | 1585 rplacad(e,left); |
1586 } | |
0 | 1587 |
61 | 1588 static void |
0 | 1589 dogoto(void) |
1590 { | |
1591 NMTBL *nptr0; | |
1592 int t,e1,e2,env; | |
1593 | |
66 | 1594 conv->goto_(); |
0 | 1595 getsym(); |
69 | 1596 e1 = expr(0); |
0 | 1597 t=car(e1); |
1598 if (t==FNAME) { | |
1599 nptr0 = (NMTBL *)cadr(e1); | |
1600 t = nptr0->sc; | |
1601 if (t==EMPTY) { | |
1602 nptr0->sc = FLABEL; | |
1603 jmp(nptr0->dsp = fwdlabel()); | |
1604 } else if (t==FLABEL||t==BLABEL) { | |
1605 jmp(nptr0->dsp); | |
1606 } | |
1607 control=0; | |
76 | 1608 conv->sm_(); |
0 | 1609 checksym(SM); |
66 | 1610 conv->goto_label_(nptr0); |
0 | 1611 return; |
1612 } | |
1613 if (t==COMMA) { | |
1614 env = caddr(e1); | |
1615 e1 = cadr(e1); | |
1616 t = car(e1); | |
1617 } else { | |
1618 env = 0; | |
1619 } | |
1620 if (t==FUNCTION) { | |
66 | 1621 conv->jump_(env); |
0 | 1622 e2 = cadr(e1); |
1623 if (car(e2) == FNAME) { | |
1624 nptr0=(NMTBL *)cadr(e2); | |
1625 nptr0->sc = CODE; | |
1626 } | |
83 | 1627 gexpr(list3(CODE,e1,env),0); |
0 | 1628 control=0; |
76 | 1629 conv->sm_(); |
0 | 1630 checksym(SM); |
1631 return; | |
1632 } | |
1633 error(STERR); | |
1634 return; | |
1635 } | |
1636 | |
61 | 1637 static void |
0 | 1638 dolabel(void) |
1639 { | |
1640 if(nptr->sc == FLABEL) | |
1641 fwddef(nptr->dsp); | |
1642 else if(nptr->sc != EMPTY) | |
1643 error(TYERR); | |
1644 nptr->sc = BLABEL; | |
1645 nptr->dsp = backdef(); | |
72 | 1646 conv->label_(); |
0 | 1647 getsym(); |
1648 checksym(COLON); | |
1649 } | |
1650 | |
1651 int | |
85 | 1652 float_value(int e2,int type) |
1653 { | |
1654 if (car(e2)==CONST) return dlist2(DCONST,(double)cadr(e2)); | |
1655 if(type==FLOAT||type==DOUBLE) return e2; | |
1656 if(type==UNSIGNED) return list2(U2D,e2); | |
1657 if(integral(type)) return list2(I2D,e2); | |
1658 error(TYERR); return dlist2(DCONST,1.0); | |
1659 } | |
1660 | |
1661 int | |
1662 int_value(int e2,int type) | |
1663 { | |
1664 if (car(e2)==DCONST||car(e2)==FCONST) return list2(CONST,(int)dcadr(e2)); | |
86 | 1665 if(scalar(type)||car(type)==ARRAY) return e2; |
85 | 1666 if(type==FLOAT||type==DOUBLE) return list2(D2I,e2); |
1667 error(TYERR); return list2(CONST,1); | |
1668 } | |
1669 | |
1670 int | |
1671 unsigned_value(int e2,int type) | |
1672 { | |
1673 if(scalar(type)) return e2; | |
86 | 1674 if(type==FLOAT||type==DOUBLE) return list2(D2U,e2); |
85 | 1675 error(TYERR); return e2; |
1676 } | |
1677 | |
1678 | |
1679 int | |
49 | 1680 assign_expr0(int e1,int e2,int t,int type) { |
1681 int stype; | |
1682 stype=type; | |
50 | 1683 e1=assign_expr(e1,rvalue_t(e2,type),t,type); |
49 | 1684 type=stype; |
1685 return e1; | |
1686 } | |
1687 | |
1688 int | |
48 | 1689 assign_expr(int e1,int e2,int t,int type) { |
1690 if(t==VOID) | |
1691 error(TYERR); | |
1692 if(t==CHAR) { | |
85 | 1693 e2=int_value(e2,type); |
1694 if (!integral(type)) error(TYERR); | |
48 | 1695 type= INT;return(list3(CASS,e1,e2)); |
81 | 1696 } else if(t==DOUBLE) { |
85 | 1697 e2=float_value(e2,type); |
82 | 1698 type= t;return(list3(DASS,e1,e2)); |
81 | 1699 } else if(t==FLOAT) { |
85 | 1700 e2=float_value(e2,type); |
82 | 1701 type= t;return(list3(FASS,e1,e2)); |
1702 } else if(scalar(t)) { | |
86 | 1703 e2=(t==UNSIGNED)?unsigned_value(e2,type):int_value(e2,type); |
82 | 1704 type=t; |
1705 return(list3(ASS,e1,e2)); | |
1706 } else if((car(t)==STRUCT||car(t)==UNION)) { | |
48 | 1707 if (size(t)!=size(type)) error(TYERR); |
49 | 1708 type=t; |
48 | 1709 if(car(e2)==RSTRUCT && car(cadr(e2))==FUNCTION) { |
1710 replace_return_struct(cadr(e2),e1); | |
1711 return cadr(e2); | |
1712 } else { | |
1713 return (list4(SASS,e1,e2,size(t))); | |
1714 } | |
1715 } else { | |
82 | 1716 error(TYERR); return list3(ASS,e1,e2); |
48 | 1717 } |
1718 } | |
1719 | |
1720 int | |
69 | 1721 expr(int noconv) |
0 | 1722 { |
66 | 1723 int r; |
69 | 1724 conv->noconv_(noconv); |
66 | 1725 r=rvalue(expr0()); |
1726 return r; | |
0 | 1727 } |
1728 | |
61 | 1729 static int |
0 | 1730 expr0(void) |
1731 { | |
1732 int e; | |
1733 | |
1734 e=expr1(); | |
1735 while(sym==COMMA) { | |
66 | 1736 conv->op_(sym); |
0 | 1737 getsym();e=list3(COMMA,e,rvalue(expr1())); |
1738 } | |
1739 return e; | |
1740 } | |
1741 | |
61 | 1742 static int |
0 | 1743 expr1(void) |
1744 { | |
1745 int e1,e2,t,op; | |
1746 e1=expr2(); | |
1747 switch (sym) { | |
1748 case ASS: | |
69 | 1749 conv->op_(sym); |
0 | 1750 lcheck(e1); |
1751 t=type; | |
1752 getsym(); | |
1753 e2=rvalue(expr1()); | |
48 | 1754 return assign_expr(e1,e2,t,type); |
0 | 1755 case ADD+AS: case SUB+AS: case MUL+AS: case DIV+AS: case MOD+AS: |
1756 case RSHIFT+AS: case LSHIFT+AS: case BAND+AS: case EOR+AS: case BOR+AS: | |
69 | 1757 conv->op_(sym); |
0 | 1758 op = sym-AS; |
1759 lcheck(e1); | |
1760 t=type; | |
1761 getsym(); | |
1762 e2=rvalue(expr1()); | |
66 | 1763 |
85 | 1764 if(!(integral(type)||type==FLOAT||type==DOUBLE)) error(TYERR); |
1765 if (t==FLOAT) { | |
1766 e2=float_value(e2,type); type=t; | |
86 | 1767 return(list4(FASSOP,e1,e2,op+DOP)); |
85 | 1768 } |
1769 if (t==DOUBLE) { | |
1770 e2=float_value(e2,type); type=t; | |
86 | 1771 return(list4(DASSOP,e1,e2,op+DOP)); |
85 | 1772 } |
0 | 1773 if(!integral(type)) error(TYERR); |
1774 if((t==UNSIGNED||type==UNSIGNED)&& | |
1775 (op==MUL||op==DIV||op==MOD||op==RSHIFT||op==LSHIFT)) | |
1776 op=op+US; | |
1777 if(t==CHAR) { | |
1778 type= INT; | |
1779 return(list4(CASSOP,e1,e2,op)); | |
1780 } | |
1781 type=t; | |
1782 if(integral(t)) return(list4(ASSOP,e1,e2,op)); | |
1783 if((op!=ADD&&op!=SUB)||car(t)!=POINTER) error(TYERR); | |
1784 e2=binop(MUL,e2,list2(CONST,size(cadr(t))),INT,UNSIGNED); | |
1785 type=t; | |
66 | 1786 |
0 | 1787 return list4(ASSOP,e1,e2,op); |
1788 default: | |
1789 return(e1); | |
1790 } | |
1791 } | |
1792 | |
61 | 1793 static int |
0 | 1794 expr2(void) |
1795 { | |
1796 int e1,e2,e3,t; | |
1797 | |
1798 e1=expr3(); | |
1799 if(sym==COND) { | |
82 | 1800 conv->cond_(); |
0 | 1801 e1=rvalue(e1); |
1802 getsym(); | |
66 | 1803 conv->cond1_(); |
0 | 1804 e2=rvalue(expr2()); |
1805 t=type; | |
69 | 1806 conv->cond2_(); |
0 | 1807 checksym(COLON); |
1808 e3=rvalue(expr2()); | |
66 | 1809 conv->cond_end_(); |
0 | 1810 if(car(e1)==CONST) { |
1811 if(cadr(e1)) { | |
1812 type=t;return e2; | |
1813 } else | |
1814 return e3; | |
1815 } | |
1816 if(type==INT||(t!=INT&&type==UNSIGNED)) | |
1817 type=t; | |
1818 return(list4(COND,e1,e2,e3)); | |
1819 } | |
1820 return(e1); | |
1821 } | |
1822 | |
61 | 1823 static int |
0 | 1824 expr3(void) |
1825 { | |
1826 int e; | |
1827 | |
1828 e=expr4(); | |
1829 while(sym==LOR) { | |
66 | 1830 conv->op_(sym); |
0 | 1831 e=rvalue(e); |
1832 getsym(); | |
1833 e=list3(LOR,e,rvalue(expr4())); | |
1834 type= INT; | |
1835 } | |
1836 return(e); | |
1837 } | |
1838 | |
61 | 1839 static int |
0 | 1840 expr4(void) |
1841 { | |
1842 int e; | |
1843 | |
1844 e=expr5(); | |
1845 while(sym==LAND) { | |
66 | 1846 conv->op_(sym); |
0 | 1847 e=rvalue(e); |
1848 getsym(); | |
1849 e=list3(LAND,e,rvalue(expr5())); | |
1850 type= INT; | |
1851 } | |
1852 return(e); | |
1853 } | |
1854 | |
61 | 1855 static int |
0 | 1856 expr5(void) |
1857 { | |
1858 int e1,e2,t; | |
1859 | |
1860 e1=expr6(); | |
1861 while(sym==BOR) { | |
66 | 1862 conv->op_(sym); |
0 | 1863 e1=rvalue(e1); |
1864 t=type; | |
1865 getsym(); | |
1866 e2=rvalue(expr6()); | |
1867 e1=binop(BOR,e1,e2,t,type); | |
1868 } | |
1869 return(e1); | |
1870 } | |
1871 | |
61 | 1872 static int |
0 | 1873 expr6(void) |
1874 { | |
1875 int e1,e2,t; | |
1876 | |
1877 e1=expr7(); | |
1878 while(sym==EOR) { | |
66 | 1879 conv->op_(sym); |
0 | 1880 e1=rvalue(e1); |
1881 t=type; | |
1882 getsym(); | |
1883 e2=rvalue(expr7()); | |
1884 e1=binop(EOR,e1,e2,t,type); | |
1885 } | |
1886 return(e1); | |
1887 } | |
1888 | |
61 | 1889 static int |
0 | 1890 expr7(void) |
1891 { | |
1892 int e1,e2,t; | |
1893 | |
1894 e1=expr8(); | |
1895 while(sym==BAND) { | |
66 | 1896 conv->op_(sym); |
0 | 1897 e1=rvalue(e1); |
1898 t=type; | |
1899 getsym(); | |
1900 e2=rvalue(expr8()); | |
1901 e1=binop(BAND,e1,e2,t,type); | |
1902 } | |
1903 return(e1); | |
1904 } | |
1905 | |
61 | 1906 static int |
0 | 1907 expr8(void) |
1908 { | |
82 | 1909 int e1,e2,op,t; |
0 | 1910 |
82 | 1911 e1=expr9(); |
0 | 1912 while((op=sym)==EQ||op==NEQ) { |
66 | 1913 conv->op_(sym); |
82 | 1914 e1=rvalue(e1); |
1915 t=type; | |
0 | 1916 getsym(); |
82 | 1917 e2=rvalue(expr9()); |
1918 e1=binop(op,e1,e2,t,type); | |
0 | 1919 type= INT; |
1920 } | |
82 | 1921 return e1; |
0 | 1922 } |
1923 | |
61 | 1924 static int |
0 | 1925 expr9(void) |
1926 { | |
1927 int e1,e2,t,op; | |
1928 | |
1929 e1=expr10(); | |
1930 while((op=sym)==GT||op==GE||op==LT||op==LE) { | |
66 | 1931 conv->op_(sym); |
0 | 1932 e1=rvalue(e1); |
1933 t=type; | |
1934 getsym(); | |
1935 e2=rvalue(expr10()); | |
1936 if(t==INT&&type==INT) | |
62 | 1937 e1=binop(op,e1,e2,t,type); |
82 | 1938 else if(t==DOUBLE||type==DOUBLE|| |
1939 t==FLOAT||type==FLOAT) | |
1940 /* binop will handle op+DOP */ | |
1941 e1=binop(op,e1,e2,t,type); | |
0 | 1942 else |
62 | 1943 e1=binop(op+US,e1,e2,t,type); |
0 | 1944 type= INT; |
1945 } | |
1946 return e1; | |
1947 } | |
1948 | |
61 | 1949 static int |
0 | 1950 expr10(void) |
1951 { | |
1952 int e1,e2,t,op; | |
1953 | |
1954 e1=expr11(); | |
1955 while((op=sym)==RSHIFT||op==LSHIFT) { | |
66 | 1956 conv->op_(sym); |
0 | 1957 e1=rvalue(e1); |
1958 t=type; | |
1959 getsym(); | |
1960 e2=rvalue(expr11()); | |
1961 e1=binop(op,e1,e2,t,type); | |
1962 } | |
1963 return e1; | |
1964 } | |
1965 | |
61 | 1966 static int |
0 | 1967 expr11(void) |
1968 { | |
1969 int e1,e2,t,op; | |
1970 | |
1971 e1=expr12(); | |
1972 while((op=sym)==ADD||op==SUB) { | |
66 | 1973 conv->op_(sym); |
0 | 1974 e1=rvalue(e1); |
1975 t=type; | |
1976 getsym(); | |
1977 e2=rvalue(expr12()); | |
1978 e1=binop(op,e1,e2,t,type); | |
1979 } | |
1980 return e1; | |
1981 } | |
1982 | |
61 | 1983 static int |
0 | 1984 expr12(void) |
1985 { | |
1986 int e1,e2,t,op; | |
1987 | |
1988 e1=expr13(); | |
1989 while((op=sym)==MUL||op==DIV||op==MOD) { | |
66 | 1990 conv->op_(sym); |
0 | 1991 e1=rvalue(e1); |
1992 t=type; | |
1993 getsym(); | |
1994 e2=rvalue(expr13()); | |
1995 e1=binop(op,e1,e2,t,type); | |
1996 } | |
1997 return e1; | |
1998 } | |
1999 | |
61 | 2000 static int |
0 | 2001 expr13(void) |
2002 { | |
2003 int e,op; | |
2004 | |
2005 switch (op = sym) { | |
66 | 2006 case INC: case DEC: |
69 | 2007 conv->prefix_(sym); |
0 | 2008 getsym(); |
2009 lcheck(e=expr13()); | |
2010 if(type==CHAR) { | |
2011 type= INT; | |
2012 return(list2(op==INC?CPREINC:CPREDEC,e)); | |
2013 } | |
2014 if(integral(type)) | |
2015 return(list3(PREINC,e,op==INC?1:-1)); | |
83 | 2016 if(type==FLOAT) |
2017 return(list3(FPREINC,e,op==INC?1:-1)); | |
2018 if(type==DOUBLE) | |
2019 return(list3(DPREINC,e,op==INC?1:-1)); | |
0 | 2020 if(car(type)!=POINTER) |
2021 error(TYERR); | |
2022 return(list3(PREINC,e, | |
2023 op==INC?size(cadr(type)):-size(cadr(type)) )); | |
2024 case MUL: | |
69 | 2025 conv->prefix_(sym); |
0 | 2026 getsym(); |
2027 e=rvalue(expr13()); | |
2028 return(indop(e)); | |
2029 case BAND: | |
69 | 2030 conv->prefix_(sym); |
0 | 2031 getsym(); |
2032 switch(car(e=expr13())) { | |
2033 case INDIRECT: | |
2034 e=cadr(e); | |
2035 break; | |
2036 case GVAR: | |
2037 case LVAR: | |
2038 e=list2(ADDRESS,e); | |
2039 break; | |
2040 case FNAME: | |
2041 return e; | |
2042 default:error(LVERR); | |
2043 } | |
2044 type=list2(POINTER,type); | |
2045 return e; | |
2046 case SUB: | |
69 | 2047 conv->prefix_(sym); |
0 | 2048 getsym(); |
2049 e=rvalue(expr13()); | |
82 | 2050 if(type==FLOAT||type==DOUBLE) |
2051 return list2(DMINUS,e); | |
0 | 2052 if(!integral(type)) |
2053 error(TYERR); | |
2054 return(car(e)==CONST?list2(CONST,-cadr(e)):list2(MINUS,e)); | |
2055 case BNOT: | |
69 | 2056 conv->prefix_(sym); |
0 | 2057 getsym(); |
2058 e=rvalue(expr13()); | |
2059 if(!integral(type)) | |
2060 error(TYERR); | |
2061 return(car(e)==CONST?list2(CONST,~cadr(e)):list2(BNOT,e)); | |
2062 case LNOT: | |
69 | 2063 conv->prefix_(sym); |
0 | 2064 getsym(); |
19 | 2065 e=rvalue(expr13()); |
82 | 2066 if(type==FLOAT||type==DOUBLE) |
2067 return(car(e)==DCONST?list2(CONST,!dcadr(e)): | |
2068 list3(DOP+NEQ,list2(CONST,0),e)); | |
20 | 2069 if(!scalar(type)) |
19 | 2070 error(TYERR); |
2071 return(car(e)==CONST?list2(CONST,!cadr(e)):list2(LNOT,e)); | |
0 | 2072 case SIZEOF: |
69 | 2073 conv->prefix_(sym); |
0 | 2074 if(getsym()==LPAR) { |
2075 if(typeid(getsym())) { | |
2076 e=list2(CONST,size(typename())); | |
2077 type=INT; | |
2078 checksym(RPAR); | |
2079 return e; | |
2080 } else { | |
2081 e=expr0(); | |
2082 checksym(RPAR); | |
2083 expr16(e); | |
2084 if(sym==INC||sym==DEC) { | |
2085 getsym(); | |
2086 if(type==CHAR) type=INT; | |
83 | 2087 else if(!scalar(type)&&type!=FLOAT&&type!=DOUBLE) |
0 | 2088 error(TYERR); |
2089 } | |
2090 } | |
2091 } else | |
2092 expr13(); | |
2093 e=list2(CONST,size(type)); | |
2094 type=INT; | |
2095 return e; | |
2096 } | |
2097 e=expr14(); | |
2098 if((op=sym)==INC||op==DEC) { | |
69 | 2099 conv->postfix_(sym); |
0 | 2100 lcheck(e); |
2101 getsym(); | |
2102 if(type==CHAR) { | |
2103 type= INT; | |
2104 return(list2(op==INC?CPOSTINC:CPOSTDEC,e)); | |
2105 } | |
2106 if(integral(type)) | |
2107 return(list3(POSTINC,e,op==INC?1:-1)); | |
83 | 2108 if(type==FLOAT) |
2109 return(list3(FPOSTINC,e,op==INC?1:-1)); | |
2110 if(type==DOUBLE) | |
2111 return(list3(DPOSTINC,e,op==INC?1:-1)); | |
0 | 2112 if(car(type)!=POINTER) |
2113 error(TYERR); | |
2114 return (list3(POSTINC,e, | |
2115 op == INC ? size(cadr(type)): -size(cadr(type)) )); | |
2116 } | |
2117 return e; | |
2118 } | |
2119 | |
61 | 2120 static int |
0 | 2121 expr14(void) |
2122 { | |
2123 int e1,t; | |
2124 | |
2125 switch(sym) { | |
2126 case IDENT: | |
68 | 2127 conv->id_(sym,nptr); |
0 | 2128 switch(nptr->sc) { |
2129 case GVAR: | |
2130 e1=list3(GVAR,nptr->dsp,(int)nptr->nm); | |
2131 type=nptr->ty; | |
2132 getsym(); | |
2133 break; | |
2134 case LVAR: | |
2135 e1=list2(LVAR,nptr->dsp); | |
2136 type=nptr->ty; | |
2137 getsym(); | |
2138 break; | |
2139 case REGISTER: | |
2140 e1=list2(REGISTER,nptr->dsp); | |
2141 type=nptr->ty; | |
2142 getsym(); | |
2143 break; | |
2144 case FLABEL: case BLABEL: | |
2145 case FUNCTION: case CODE: | |
2146 e1=list2(FNAME,(int)nptr); | |
67 | 2147 type=list3(nptr->sc,nptr->ty,nptr->dsp); |
0 | 2148 getsym(); |
2149 break; | |
2150 case EMPTY: | |
2151 if(getsym()==LPAR) { | |
2152 nptr->sc = FUNCTION; | |
67 | 2153 nptr->ty= INT; |
0 | 2154 type= list3(FUNCTION,INT,0); |
2155 e1=expr15(list2(FNAME,(int)nptr)); | |
2156 break; | |
2157 } else { | |
2158 e1=list2(FNAME,(int)nptr); | |
67 | 2159 type=list3(nptr->sc,nptr->ty,nptr->dsp); |
0 | 2160 break; |
2161 } | |
2162 default:error(UDERR); | |
2163 } | |
2164 break; | |
2165 case STRING: | |
68 | 2166 conv-> string_(sptr); |
0 | 2167 e1=list3(STRING,(int)sptr,symval); |
2168 type=list3(ARRAY,CHAR,symval); | |
2169 getsym(); | |
2170 break; | |
2171 case CONST: | |
68 | 2172 conv-> const_(symval); |
0 | 2173 type= INT; |
2174 e1=list2(CONST,symval); | |
2175 getsym(); | |
2176 break; | |
81 | 2177 case DCONST: |
2178 conv-> const_(symval); | |
2179 type= DOUBLE; | |
2180 e1=dlist2(DCONST,dsymval); | |
2181 getsym(); | |
2182 break; | |
0 | 2183 case RETURN: |
68 | 2184 conv-> return_f_(); |
0 | 2185 if (fnptr->sc != FUNCTION) { |
2186 error(STERR); | |
2187 } | |
2188 type=list2(POINTER,CODE); | |
2189 e1=list2(RETURN,(int)fnptr); | |
2190 getsym(); | |
2191 break; | |
18 | 2192 case DEFINED: |
2193 getsym(); | |
2194 t = mode; mode = IFDEF; | |
2195 checksym(LPAR); | |
68 | 2196 conv-> defined_(name); |
18 | 2197 mode = t; |
2198 type= INT; | |
2199 e1=list2(CONST,symval); | |
2200 getsym(); | |
2201 checksym(RPAR); | |
2202 break; | |
0 | 2203 case ENVIRONMENT: |
68 | 2204 conv-> environment_(); |
2 | 2205 type=list2(POINTER,VOID); |
0 | 2206 e1=list2(ENVIRONMENT,0); |
2207 getsym(); | |
2208 break; | |
2209 case LPAR: | |
66 | 2210 conv->lpar_(); |
0 | 2211 if(typeid(getsym())) { |
2212 t=typename(); | |
72 | 2213 conv->return_type_(t,0,0); |
2214 conv->rpar_(); | |
0 | 2215 checksym(RPAR); |
2216 e1=expr13(); | |
85 | 2217 if (integral(t)) { |
2218 if(t==UNSIGNED) e1=unsigned_value(e1,type); | |
2219 else e1=int_value(e1,type); | |
2220 } else if(t==FLOAT||t==DOUBLE) { | |
2221 if(integral(type)) e1=float_value(e1,type); | |
81 | 2222 } |
0 | 2223 type=t; |
2224 return e1; | |
2225 } | |
2226 e1=expr0(); | |
66 | 2227 conv->rpar_(); |
0 | 2228 checksym(RPAR); |
2229 break; | |
2230 default:error(EXERR); | |
2231 } | |
2232 return expr16(e1); | |
2233 } | |
2234 | |
61 | 2235 static int |
0 | 2236 expr16(int e1) |
2237 { | |
2238 int e2,t; | |
2239 | |
2240 while(1) { | |
2241 if(sym==LBRA) { | |
66 | 2242 conv->lbra_(sym); |
0 | 2243 e1=rvalue(e1); |
2244 t=type; | |
2245 getsym(); | |
2246 e2=rvalue(expr0()); | |
2247 checksym(RBRA); | |
66 | 2248 conv->rbra_(sym); |
0 | 2249 e1=binop(ADD,e1,e2,t,type); |
2250 e1=indop(e1); | |
68 | 2251 } else if(sym==LPAR) e1=expr15(e1); |
66 | 2252 else { |
69 | 2253 if(sym==PERIOD) { conv->op_(sym);e1=strop(e1); |
2254 } else if(sym==ARROW) { conv->op_(sym);e1=strop(indop(rvalue(e1))); | |
68 | 2255 } else break; |
66 | 2256 } |
0 | 2257 } |
2258 if(car(e1)==FNAME) type=list2(POINTER,type); | |
2259 return e1; | |
2260 } | |
2261 | |
61 | 2262 static int |
0 | 2263 rvalue(int e) |
2264 { | |
2265 int t; | |
2266 if(type==CHAR) { | |
2267 type= INT; | |
2268 switch(car(e)) { | |
2269 case GVAR: | |
2270 return(list3(CRGVAR,cadr(e),caddr(e))); | |
2271 case LVAR: | |
2272 return(list2(CRLVAR,cadr(e))); | |
2273 case INDIRECT: | |
2274 return(list2(CRINDIRECT,cadr(e))); | |
2275 default:return(e); | |
2276 } | |
2277 } | |
81 | 2278 if(type==FLOAT) { |
2279 switch(car(e)) { | |
2280 case GVAR: | |
2281 return(list3(FRGVAR,cadr(e),caddr(e))); | |
2282 case LVAR: | |
2283 return(list2(FRLVAR,cadr(e))); | |
2284 case INDIRECT: | |
2285 return(list2(FRINDIRECT,cadr(e))); | |
2286 default:return(e); | |
2287 } | |
2288 } | |
2289 if(type==DOUBLE) { | |
2290 switch(car(e)) { | |
2291 case GVAR: | |
2292 return(list3(DRGVAR,cadr(e),caddr(e))); | |
2293 case LVAR: | |
2294 return(list2(DRLVAR,cadr(e))); | |
2295 case INDIRECT: | |
2296 return(list2(DRINDIRECT,cadr(e))); | |
2297 default:return(e); | |
2298 } | |
2299 } | |
2300 if(type==LONGLONG) { | |
2301 switch(car(e)) { | |
2302 case GVAR: | |
2303 return(list3(LRGVAR,cadr(e),caddr(e))); | |
2304 case LVAR: | |
2305 return(list2(LRLVAR,cadr(e))); | |
2306 case INDIRECT: | |
2307 return(list2(LRINDIRECT,cadr(e))); | |
2308 default:return(e); | |
2309 } | |
2310 } | |
0 | 2311 if(!integral(type)&&type!=VOID) { |
79 | 2312 if(type==CODE) { |
78 | 2313 return e; |
79 | 2314 } if((t=car(type))==ARRAY) { |
0 | 2315 type=list2(POINTER,cadr(type)); |
2316 if(car(e)==INDIRECT) return cadr(e); | |
2317 return list2(ADDRESS,e); | |
37 | 2318 } else if(t==STRUCT || t==UNION) { |
2319 t = cadr(type); /* size */ | |
38 | 2320 return list3(RSTRUCT,e,t); |
79 | 2321 } else if(t==FUNCTION) { |
2322 return e; | |
2323 } else if(t==CODE) { | |
2324 return e; | |
0 | 2325 } else if(t!=POINTER) error(TYERR); |
2326 } | |
2327 switch(car(e)) { | |
2328 case GVAR: | |
2329 return(list3(RGVAR,cadr(e),caddr(e))); | |
2330 case LVAR: | |
2331 return(list2(RLVAR,cadr(e))); | |
2332 case INDIRECT: | |
2333 return(list2(RINDIRECT,cadr(e))); | |
2334 default:return(e); | |
2335 } | |
2336 } | |
2337 | |
46
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
2338 int |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
2339 rvalue_t(int e,int t) |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
2340 { |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
2341 int stype = type; |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
2342 type = t; |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
2343 e = rvalue(e); |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
2344 type = stype; |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
2345 return e; |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
2346 } |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
2347 |
61 | 2348 static void |
0 | 2349 lcheck(int e) |
2350 { | |
2351 int t; | |
81 | 2352 if(!(scalar(type)||type==DOUBLE||type==FLOAT)|| |
0 | 2353 (car(e)!=GVAR&&car(e)!=LVAR&&car(e)!=INDIRECT&&car(e)!=REGISTER)) |
2354 if ((t=car(type))<0 && t!=STRUCT && t!=UNION) | |
2355 error(LVERR); | |
2356 } | |
2357 | |
61 | 2358 static int |
0 | 2359 indop(int e) |
2360 { | |
2361 if(type!=INT&&type!=UNSIGNED) { | |
79 | 2362 if(car(type)==POINTER) |
0 | 2363 type=cadr(type); |
79 | 2364 else if(car(type)==CODE || car(type)==FUNCTION) |
2365 type=type; | |
0 | 2366 else error(TYERR); |
2367 } else | |
2368 type= CHAR; | |
2369 if(car(e)==ADDRESS) | |
2370 return(cadr(e)); | |
2371 return(list2(INDIRECT,e)); | |
2372 } | |
2373 | |
61 | 2374 static int |
0 | 2375 strop(int e) |
2376 { | |
2377 getsym(); | |
2378 if (sym!=IDENT||nptr->sc!=FIELD) error(TYERR); | |
69 | 2379 conv->id_(sym,nptr); |
0 | 2380 if (integral(type)||(car(type)!=STRUCT && car(type)!=UNION)) |
2381 e=rvalue(e); | |
2382 type = nptr->ty; | |
40 | 2383 if(nptr->dsp) { |
2384 switch(car(e)) { | |
2385 case GVAR: | |
2386 e=list2(INDIRECT,list3(ADD,e,list2(CONST,nptr->dsp))); | |
2387 break; | |
2388 case LVAR: | |
53 | 2389 e=list2(LVAR,cadr(e) + nptr->dsp); |
40 | 2390 break; |
2391 case INDIRECT: | |
2392 e=list2(INDIRECT,list3(ADD,cadr(e),list2(CONST,nptr->dsp))); | |
2393 break; | |
2394 default: | |
2395 e=list2(INDIRECT,list3(ADD,e,list2(CONST,nptr->dsp))); | |
2396 } | |
2397 } else { | |
2398 switch(car(e)) { | |
2399 case GVAR: case LVAR: case INDIRECT: | |
2400 break; | |
2401 default: | |
2402 e=list2(INDIRECT,e); | |
2403 } | |
0 | 2404 } |
2405 getsym(); | |
2406 return e; | |
2407 } | |
2408 | |
61 | 2409 static int |
81 | 2410 dbinop(int op, int e1, int e2, int t1, int t2) |
2411 { | |
2412 double d1,d2,d; | |
2413 | |
2414 type= DOUBLE; | |
85 | 2415 if (integral(t1)) { e1=float_value(e1,t1); t1=DOUBLE; } |
2416 if (integral(t2)) { e2=float_value(e2,t2); t2=DOUBLE; } | |
81 | 2417 if(car(e1)==DCONST&&car(e2)==DCONST) { |
85 | 2418 d1=dcadr(e1); |
2419 d2=dcadr(e2); | |
81 | 2420 switch(op) { |
2421 case ADD: d=d1+d2; break; | |
2422 case SUB: d=d1-d2; break; | |
2423 case MUL: d=d1*d2;break; | |
2424 case DIV: | |
2425 if(!d2) error(EXERR);d=d1/d2;break; | |
2426 case GT: | |
2427 d=(d1>d2);break; | |
2428 case GE: | |
2429 d=(d1>=d2);break; | |
2430 case LT: | |
2431 d=(d1<d2);break; | |
2432 case LE: | |
2433 d=(d1<=d2);break; | |
82 | 2434 case EQ: |
2435 d=(d1==d2);break; | |
2436 case NEQ: | |
2437 d=(d1!=d2);break; | |
81 | 2438 } |
2439 return dlist2(DCONST,d); | |
2440 } | |
82 | 2441 if(op==GT||op==GE||op==LT||op==LE||op==EQ||op==NEQ|| |
81 | 2442 ADD||SUB||MUL||DIV) |
2443 return(list3(op+DOP,e1,e2)); | |
82 | 2444 else |
2445 error(-1); | |
81 | 2446 } |
2447 | |
2448 static int | |
0 | 2449 binop(int op, int e1, int e2, int t1, int t2) |
2450 { | |
2451 int e; | |
2452 | |
82 | 2453 if(t1==DOUBLE||t2==DOUBLE||t1==FLOAT||t2==FLOAT) |
81 | 2454 return dbinop(op,e1,e2,t1,t2); |
2455 if(car(e1)==CONST&&car(e2)==CONST) { | |
0 | 2456 e1=cadr(e1); |
2457 e2=cadr(e2); | |
2458 type= INT; | |
2459 switch(op) { | |
2460 case BOR: | |
2461 e=e1|e2;break; | |
2462 case EOR: | |
2463 e=e1^e2;break; | |
2464 case BAND: | |
2465 e=e1&e2;break; | |
2466 case ADD: | |
2467 if(integral(t1)) { | |
2468 if(integral(t2)) { | |
2469 e=e1+e2; | |
2470 } else { | |
2471 if(car(t2)!=POINTER) error(TYERR); | |
2472 e=size(cadr(t2))*e1+e2; | |
2473 type=t2; | |
2474 } | |
2475 } else { | |
2476 if(car(t1)!=POINTER) error(TYERR); | |
2477 e=e1+size(cadr(t1))*e2; | |
2478 type=t1; | |
2479 } | |
2480 break; | |
2481 case SUB: | |
2482 if(integral(t1)) { | |
2483 e=e1-e2; | |
2484 } else { | |
2485 if(car(t1)!=POINTER) error(TYERR); | |
2486 e=e1-size(cadr(t1))*e2; | |
2487 type=t1; | |
2488 } | |
2489 break; | |
2490 case MUL: | |
2491 e=e1*e2;break; | |
2492 case DIV: | |
2493 if(!e2) error(EXERR);e=e1/e2;break; | |
2494 case MOD: | |
2495 if(!e2) error(EXERR);e=e1%e2;break; | |
2496 case RSHIFT: | |
2497 e=e1>>e2;break; | |
2498 case LSHIFT: | |
62 | 2499 e=e1<<e2;break; |
82 | 2500 case EQ: |
2501 e=(e1==e2);break; | |
2502 case NEQ: | |
2503 e=(e1!=e2);break; | |
62 | 2504 case GT: |
2505 e=(e1>e2);break; | |
2506 case GE: | |
2507 e=(e1>=e2);break; | |
2508 case LT: | |
2509 e=(e1<e2);break; | |
2510 case LE: | |
2511 e=(e1<=e2);break; | |
2512 case UGT: | |
2513 e=((unsigned)e1>(unsigned)e2);break; | |
2514 case UGE: | |
2515 e=((unsigned)e1>=(unsigned)e2);break; | |
2516 case ULT: | |
2517 e=((unsigned)e1<(unsigned)e2);break; | |
2518 case ULE: | |
2519 e=((unsigned)e1<=(unsigned)e2);break; | |
0 | 2520 } |
2521 return list2(CONST,e); | |
2522 } | |
82 | 2523 if(op==GT||op==GE||op==LT||op==LE|| |
2524 op==UGT||op==UGE||op==ULT||op==ULE|| | |
2525 op==EQ||op==NEQ | |
2526 ) | |
62 | 2527 return(list3(op,e1,e2)); |
0 | 2528 if((op==ADD||op==MUL||op==BOR||op==EOR||op==BAND)&& |
2529 (car(e1)==CONST||(car(e2)!=CONST&& | |
2530 (car(e1)==RGVAR||car(e1)==RLVAR)))) { | |
2531 e=e1;e1=e2;e2=e;e=t1;t1=t2;t2=e; | |
2532 } | |
2533 if(op==ADD) { | |
2534 if(integral(t1)) { | |
2535 if(integral(t2)) { | |
2536 if(t1==INT) type=t2;else type=t1; | |
2537 return(list3(ADD,e1,e2)); | |
2538 } | |
2539 if(car(t2)!=POINTER) error(TYERR); | |
2540 e=binop(MUL,e1,list2(CONST,size(cadr(t2))),t1,INT); | |
2541 type=t2; | |
2542 return(list3(ADD,e,e2)); | |
2543 } | |
2544 if(car(t1)!=POINTER||!integral(t2)) error(TYERR); | |
2545 e=binop(MUL,e2,list2(CONST,size(cadr(t1))),t2,INT); | |
2546 type=t1; | |
40 | 2547 if (car(e)==CONST && cadr(e)==0) |
2548 return(e1); | |
0 | 2549 if(car(e1)==ADDRESS&&car(e)==CONST&&car(cadr(e1))!=GVAR) |
2550 return(list2(ADDRESS,list2(car(cadr(e1)), | |
2551 cadr(cadr(e1))+cadr(e)))); | |
2552 return(list3(ADD,e1,e)); | |
2553 } | |
2554 if(op==SUB) { | |
2555 if(integral(t1)) { | |
2556 if(!integral(t2)) error(TYERR); | |
2557 if(t1==INT) type=t2;else type=t1; | |
2558 return(list3(SUB,e1,e2)); | |
2559 } | |
2560 if(car(t1)!=POINTER) error(TYERR); | |
2561 if(integral(t2)) { | |
2562 e=binop(MUL,e2,list2(CONST,size(cadr(t1))),t2,INT); | |
2563 type=t1; | |
2564 return(list3(SUB,e1,e)); | |
2565 } | |
2566 if(car(t2)!=POINTER) | |
2567 error(TYERR); | |
2568 compatible(t1,t2); | |
2569 e=list3(SUB,e1,e2); | |
2570 e=binop(DIV,e,list2(CONST,size(cadr(t1))),UNSIGNED,INT); | |
2571 type= INT; | |
2572 return e; | |
2573 } | |
2574 if(!integral(t1)||!integral(t2)) error(TYERR); | |
87 | 2575 if(t1==INT) type=t2; else type=t1; |
0 | 2576 if((op==MUL||op==DIV)&&car(e2)==CONST&&cadr(e2)==1) return e1; |
2577 if(op==BOR||op==EOR||op==BAND) return(list3(op,e1,e2)); | |
2578 return(list3(type==UNSIGNED?op+US:op,e1,e2)); | |
2579 } | |
2580 | |
87 | 2581 int |
2582 function_args(int e,int t) | |
2583 { | |
2584 int t1; | |
2585 e = rvalue(e); | |
2586 if (type==FLOAT && t==DOTS) { type=DOUBLE;} | |
2587 if (type==CHAR && t==DOTS) { type=INT;} | |
2588 if (t==DOTS) return e; | |
2589 if (t==UNSIGNED) e = unsigned_value(e,type); | |
2590 else if (integral(t)) e = int_value(e,type); | |
2591 else if (t==FLOAT||t==DOUBLE) e = float_value(e,type); | |
2592 else if ((t1=car(t))==STRUCT||t1==UNION) { | |
2593 if(size(t)!=size(type)) error(TYERR); | |
2594 } | |
2595 type = t; | |
2596 return e; | |
2597 } | |
2598 | |
61 | 2599 static int |
0 | 2600 expr15(int e1) |
2601 { | |
87 | 2602 int t,arglist,e,sz,argtypes,at; |
0 | 2603 |
39 | 2604 /* function call */ |
79 | 2605 if(car(type)==POINTER) { |
2606 if (car(cadr(type))==FUNCTION||car(cadr(type))==CODE) { | |
2607 e1=rvalue(e1); | |
2608 type=cadr(type); | |
2609 } | |
2610 } | |
87 | 2611 if(integral(type)|| ((car(type)!=FUNCTION)&&(car(type)!=CODE))) { |
0 | 2612 error(TYERR); |
79 | 2613 } |
66 | 2614 conv->funcall_(type); |
0 | 2615 getsym(); |
87 | 2616 argtypes = caddr(type); |
2617 if (!integral(t=cadr(type))&&(car(t)==STRUCT||car(t)==UNION)) { | |
2618 /* skip return struct pointer */ | |
2619 if (argtypes==0) error(-1); | |
2620 argtypes = cadr(argtypes); | |
2621 } | |
2622 t=type; | |
0 | 2623 arglist=0; |
2624 while(sym!=RPAR) { | |
3 | 2625 e=rvalue(expr1()); |
87 | 2626 if(argtypes==0) at=DOTS; |
2627 else if(car(argtypes)==DOTS) at=DOTS; | |
2628 else { at=car(argtypes); argtypes=cadr(argtypes); } | |
2629 e = function_args(e,at); | |
3 | 2630 arglist=list3(e,arglist,type); |
0 | 2631 if(sym!=COMMA) break; |
69 | 2632 conv->comma_(); |
0 | 2633 getsym(); |
2634 } | |
2635 checksym(RPAR); | |
66 | 2636 conv->funcall_args_(); |
39 | 2637 if(car(t)==CODE) |
2638 return list3(FUNCTION,e1,arglist); | |
2639 type=cadr(t); | |
2640 if(type==CHAR) type=INT; | |
2641 else if(car(type)==STRUCT||car(type)==UNION) { | |
2642 /* make temporaly struct for return value */ | |
45 | 2643 /* but it is better to see we can reuse old one */ |
2644 if (tmp_struct) { | |
2645 sz = size(tmp_struct->ty); | |
2646 if (sz>=size(type)) { | |
2647 /* reuse it */ | |
2648 } else if (tmp_struct->dsp-sz==disp) { | |
2649 /* extendable */ | |
2650 disp -= tmp_struct->dsp-sz; | |
2651 tmp_struct->dsp = disp; | |
2652 } else { | |
2653 tmp_struct = def(0); | |
2654 } | |
2655 } else { | |
2656 tmp_struct = def(0); | |
2657 } | |
2658 e = list2(LVAR,tmp_struct->dsp); | |
2659 | |
39 | 2660 /* pass the pointer as an argument */ |
2661 /* this is recognized by called function declaration */ | |
45 | 2662 /* but I don't know this sequece is compatible with gcc */ |
2663 | |
46
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
2664 append3(arglist,list2(ADDRESS,e),list2(POINTER,type)); |
0 | 2665 } |
2666 return list3(FUNCTION,e1,arglist); | |
2667 } | |
2668 | |
61 | 2669 static int |
0 | 2670 typeid(int s) |
2671 { | |
37 | 2672 return (integral(s) || s==CODE || s==SHORT || |
2673 s==LONG || s==STRUCT || s==UNION || | |
81 | 2674 s==LONGLONG || s==FLOAT || s==DOUBLE || |
0 | 2675 (s==IDENT && nptr->sc==TYPE)); |
2676 } | |
2677 | |
61 | 2678 static int |
0 | 2679 typename(void) |
2680 { | |
2681 int t; | |
2682 | |
2683 type=t=typespec(); | |
2684 ndecl0(); | |
2685 reverse(t); | |
2686 return type; | |
2687 } | |
2688 | |
61 | 2689 static int |
0 | 2690 ndecl0(void) |
2691 { | |
2692 if(sym==MUL) { | |
2693 getsym(); | |
2694 return type=list2(POINTER,ndecl0()); | |
2695 } | |
2696 return ndecl1(); | |
2697 } | |
2698 | |
61 | 2699 static int |
0 | 2700 ndecl1(void) |
2701 { | |
2702 int i,t,arglist; | |
2703 | |
2704 if(sym==LPAR) { | |
2705 if(getsym()==RPAR) { | |
2706 type=list3(FUNCTION,type,0); getsym(); | |
2707 } else { | |
2708 ndecl0(); | |
2709 checksym(RPAR); | |
2710 } | |
2711 } | |
2712 while(1) { | |
2713 if(sym==LBRA) { | |
2714 getsym(); | |
2715 t=type; | |
69 | 2716 i=cexpr(expr(1)); |
0 | 2717 checksym(RBRA); |
2718 type=list3(ARRAY,t,i); | |
2719 } else if(sym==LPAR) { | |
2720 t = type; | |
2721 getsym(); | |
2722 arglist=0; | |
2723 while(sym!=RPAR) { | |
2724 ndecl0(); | |
2725 arglist=list2(type,arglist); | |
2726 if(sym!=COMMA) break; | |
2727 getsym(); | |
2728 } | |
2729 checksym(RPAR); | |
2730 type=list3(FUNCTION,t,arglist); | |
2731 } | |
2732 else return type; | |
2733 } | |
2734 } | |
2735 | |
61 | 2736 static int |
0 | 2737 cexpr(int e) |
2738 { | |
69 | 2739 conv->conv_(); |
0 | 2740 if (car(e) != CONST) error(CNERR); |
2741 return (cadr(e)); | |
2742 } | |
2743 | |
61 | 2744 static int in_comment = 0; |
20 | 2745 |
81 | 2746 extern double strtod(const char *nptr, char **endptr); |
2747 | |
61 | 2748 static int |
0 | 2749 getsym(void) |
2750 { | |
29 | 2751 NMTBL *nptr0,*nptr1,*nptrm; |
82 | 2752 int i,slfree,macrop,d; |
81 | 2753 char *scheapp; |
35 | 2754 char c; |
0 | 2755 |
2756 if (alpha(skipspc())) { | |
2757 i = hash = 0; | |
2758 name = namebuf; | |
2759 while (alpha(ch) || digit(ch)) { | |
2760 if (i < LBUFSIZE-1) | |
2761 hash=(7*hash ^ (name[i++]=ch)); | |
2762 getch(); | |
2763 } | |
2764 name[i++] = '\0'; | |
29 | 2765 |
2766 nptrm=msearch(name); | |
2767 if (mode==MDECL) { | |
2768 nptr = nptrm; | |
2769 return (sym==MACRO); | |
2770 } | |
2771 if (mode==IFDEF) { | |
2772 if (nptrm->sc == MACRO||nptrm->sc==FMACRO) { | |
18 | 2773 return (symval=1); |
29 | 2774 } else { |
2775 return (symval=0); | |
18 | 2776 } |
29 | 2777 } |
34 | 2778 if (nptrm->sc!=EMPTY) { |
2779 i = mode; | |
2780 mode = STAT; | |
2781 macrop = 0; | |
2782 slfree = lfree; | |
2783 macropp = macro_buf; | |
29 | 2784 if (nptrm->sc == FMACRO) { |
34 | 2785 macrop=macro_function(macrop,&chptr,nptrm,0); |
2786 } else { | |
2787 macrop=macro_eval(macrop,(char *)car(nptrm->dsp),0); | |
29 | 2788 } |
34 | 2789 macropp = macro_buf; |
46
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
2790 mappend(reverse0(macrop)); |
35 | 2791 macropp[-1] ='\n'; |
2792 *macropp =0; | |
34 | 2793 lfree = slfree; |
42 | 2794 if (lsrc && !asmf && nptrm->sc==FMACRO) gen_comment(macro_buf); |
67 | 2795 macropp[-1] =0; |
34 | 2796 chptrsave = chptr; |
2797 chsave = ch = chptr[-1]; | |
2798 chptr = macro_buf; | |
2799 ch = *chptr++; | |
2800 mode = i; | |
2801 return getsym(); | |
0 | 2802 } |
29 | 2803 |
2804 nptr0 = gsearch(); | |
18 | 2805 if (nptr0->sc == RESERVE) return sym = nptr0->dsp; |
0 | 2806 sym = IDENT; |
2807 gnptr=nptr=nptr0; | |
2808 if (mode==ADECL && nptr0->sc ==TYPE) return sym; | |
2809 if (mode==GDECL || mode==GSDECL || mode==GUDECL || | |
2810 mode==GTDECL || mode==TOP) { | |
2811 return sym; | |
2812 } | |
2813 nptr1=lsearch(nptr0->nm); | |
18 | 2814 if (mode==STAT) { |
0 | 2815 if (nptr1->sc == EMPTY) return sym; |
18 | 2816 } |
0 | 2817 nptr=nptr1; |
2818 return sym; | |
81 | 2819 } else if (digit(ch)||ch=='.') { |
82 | 2820 symval=0; d=0; |
81 | 2821 scheapp = cheapp; |
2822 if(ch=='.') { | |
2823 getch(); | |
2824 if(ch=='.') { | |
2825 getch(); | |
2826 if (ch=='.') { | |
2827 getch(); | |
2828 return sym=DOTS; | |
2829 } | |
2830 error(CHERR); | |
2831 return getsym(); | |
2832 } else if (!digit(ch)) | |
2833 return sym=PERIOD; | |
82 | 2834 d=1; |
2835 *cheapp++ = '.'; /* .0 case */ | |
2836 } else if (ch == '0') { | |
2837 if (getch() == 'x' || ch == 'X') { | |
2838 while(1) { | |
2839 if(digit(getch())) | |
2840 symval=symval*16+ch-'0'; | |
2841 else if('a'<=ch&&ch<='f') | |
2842 symval=symval*16+ch-'a'+10; | |
2843 else if('A'<=ch&&ch<='F') | |
2844 symval=symval*16+ch-'A'+10; | |
2845 else break; | |
2846 } | |
2847 return sym=CONST; | |
2848 } else if (ch!='.') { | |
2849 while (digit(ch)) { | |
2850 symval=symval*8+ch-'0';getch(); | |
2851 } | |
2852 return sym=CONST; | |
2853 } | |
2854 d=1; | |
2855 *cheapp++ = '0'; /* 0. case */ | |
0 | 2856 } else { |
2857 while(digit(ch)) { | |
81 | 2858 *cheapp++ = ch; |
0 | 2859 symval=symval*10+ch-'0';getch(); |
2860 } | |
81 | 2861 if (!(ch=='.'||ch=='e')) { |
2862 cheapp=scheapp; | |
2863 return sym=CONST; | |
2864 } | |
0 | 2865 } |
81 | 2866 while(digit(ch)|| ch=='.'||ch=='e') { |
2867 *cheapp++ = ch; | |
2868 getch(); | |
2869 if (ch=='-' && cheapp[-1]=='e') { | |
2870 *cheapp++ = ch; getch(); | |
2871 } | |
2872 } | |
2873 *cheapp++ = 0; | |
2874 dsymval = strtod(scheapp,0); | |
2875 cheapp=scheapp; | |
2876 return sym=DCONST; | |
0 | 2877 } else if(ch=='\'') { |
2878 getch(); | |
2879 symval=escape(); | |
2880 if(ch!='\'') error(CHERR); | |
2881 getch(); | |
2882 return sym=CONST; | |
2883 } else if(ch=='"') { | |
2884 getstring(); | |
2885 return sym= STRING; | |
2886 } | |
2887 c=ch; | |
2888 getch(); | |
2889 switch(c) { | |
2890 case '*': | |
2891 return postequ(MUL,MUL+AS); | |
2892 case '&': | |
2893 if(ch=='&') {getch();return sym=LAND;} | |
2894 return postequ(BAND,BAND+AS); | |
2895 case '-': | |
2896 if(ch=='>') {getch();return sym=ARROW;} | |
2897 if(ch=='-') {getch();return sym=DEC;} | |
2898 return postequ(SUB,SUB+AS); | |
2899 case '!': | |
2900 return postequ(LNOT,NEQ); | |
2901 case '~': | |
2902 return sym=BNOT; | |
2903 case '+': | |
2904 if(ch=='+') {getch();return sym=INC;} | |
2905 return postequ(ADD,ADD+AS); | |
2906 case '%': | |
2907 return postequ(MOD,MOD+AS); | |
2908 case '^': | |
2909 return postequ(EOR,EOR+AS); | |
2910 case '|': | |
2911 if(ch=='|') {getch();return sym=LOR;} | |
2912 return postequ(BOR,BOR+AS); | |
2913 case '=': | |
2914 return postequ(ASS,EQ); | |
2915 case '>': | |
2916 if(ch=='>') {getch();return postequ(RSHIFT,RSHIFT+AS);} | |
2917 return postequ(GT,GE); | |
2918 case '<': | |
2919 if(ch=='<') {getch();return postequ(LSHIFT,LSHIFT+AS);} | |
2920 return postequ(LT,LE); | |
2921 case '(': | |
2922 return sym=LPAR; | |
2923 case ')': | |
2924 return sym=RPAR; | |
2925 case '[': | |
2926 return sym=LBRA; | |
2927 case ']': | |
2928 return sym=RBRA; | |
2929 case '{': | |
2930 return sym=LC; | |
2931 case '}': | |
2932 return sym=RC; | |
2933 case ',': | |
2934 return sym=COMMA; | |
2935 case ';': | |
2936 return sym=SM; | |
2937 case ':': | |
2938 return sym=COLON; | |
2939 case '?': | |
2940 return sym=COND; | |
2941 case '/': | |
34 | 2942 if(ch=='/') { |
66 | 2943 in_comment = 1; |
2944 conv->comment_('/'); conv->comment_('/'); | |
2945 while(ch!='\n') { getch(); conv->comment_(ch); } | |
2946 in_comment = 0; | |
34 | 2947 getch(); |
2948 return getsym(); | |
2949 } | |
66 | 2950 if(ch!='*') return postequ(DIV,DIV+AS); |
20 | 2951 in_comment = 1; |
66 | 2952 conv->comment_('/'); conv->comment_('*'); |
2953 do { | |
2954 c=ch; getch(); conv->comment_(ch); | |
2955 } while(!(c=='*'&&ch=='/')); | |
20 | 2956 in_comment = 0; |
0 | 2957 getch(); |
2958 return getsym(); | |
34 | 2959 case 0: |
2960 case '\n': | |
2961 getch(); | |
2962 return getsym(); | |
0 | 2963 default: |
2964 error(CHERR); | |
2965 return getsym(); | |
2966 } | |
2967 } | |
2968 | |
61 | 2969 static int |
0 | 2970 postequ(int s1, int s2) |
2971 { | |
2972 if(ch=='=') {getch();return sym=s2;} | |
2973 return sym=s1; | |
2974 } | |
2975 | |
61 | 2976 static int |
0 | 2977 alpha(char c) |
2978 { | |
2979 return(('a'<=c&&c<='z')||('A'<=c&&c<='Z')||c=='_'); | |
2980 } | |
2981 | |
61 | 2982 static int |
0 | 2983 digit(char c) |
2984 { | |
2985 return('0'<=c&&c<='9'); | |
2986 } | |
2987 | |
37 | 2988 int dummy_count = 0; |
2989 | |
61 | 2990 static NMTBL * |
37 | 2991 free_nptr() |
2992 { | |
2993 NMTBL *nptr,*iptr; | |
2994 | |
2995 iptr=nptr= &ntable[hash % GSYMS]; | |
2996 while(nptr->sc!=0) { | |
2997 if (++nptr== &ntable[GSYMS]) | |
2998 nptr=ntable; | |
2999 if (nptr==iptr) error(GSERR); | |
3000 } | |
3001 copy(nptr,"_00000"); | |
3002 dummy_count++; | |
3003 if (dummy_count>999) error(STRERR); | |
3004 nptr->nm[5]='0'+dummy_count%10; | |
3005 nptr->nm[4]='0'+(dummy_count/10)%10; | |
3006 nptr->nm[3]='0'+(dummy_count/100)%10; | |
3007 nptr->sc=EMPTY; | |
3008 return nptr; | |
3009 } | |
0 | 3010 |
61 | 3011 static NMTBL * |
0 | 3012 gsearch(void) |
3013 { | |
3014 NMTBL *nptr,*iptr; | |
3015 | |
3016 iptr=nptr= &ntable[hash % GSYMS]; | |
30 | 3017 while(nptr->sc!=0 && neqname(nptr->nm,name)) { |
0 | 3018 if (++nptr== &ntable[GSYMS]) |
3019 nptr=ntable; | |
3020 if (nptr==iptr) error(GSERR); | |
3021 } | |
3022 if (nptr->sc == 0) { | |
3023 copy(nptr,name); | |
3024 nptr->sc=EMPTY; | |
3025 } | |
3026 return nptr; | |
3027 } | |
3028 | |
61 | 3029 static NMTBL * |
0 | 3030 lsearch(char *name) |
3031 { | |
3032 NMTBL *nptr,*iptr; | |
3033 | |
3034 iptr=nptr= &ntable[hash%LSYMS+GSYMS]; | |
30 | 3035 while(nptr->sc!=0 && neqname(nptr->nm,name)) { |
0 | 3036 if (++nptr== &ntable[LSYMS+GSYMS]) |
3037 nptr= &ntable[GSYMS]; | |
3038 if (nptr==iptr) error(LSERR); | |
3039 } | |
3040 if (nptr->sc == 0) { | |
3041 nptr->nm=name; /* already saved in gsearch */ | |
3042 nptr->sc=EMPTY; | |
3043 nptr->dsp=0; | |
3044 } | |
3045 return nptr; | |
3046 } | |
3047 | |
61 | 3048 static NMTBL * |
29 | 3049 msearch(char *name) |
3050 { | |
3051 NMTBL *nptr,*iptr; | |
3052 | |
3053 iptr=nptr= &mtable[hash%MSYMS]; | |
30 | 3054 while(nptr->sc!=0 && neqname(nptr->nm,name)) { |
29 | 3055 if (++nptr== &mtable[MSYMS]) |
30 | 3056 nptr= &mtable[0]; |
29 | 3057 if (nptr==iptr) error(MSERR); |
3058 } | |
3059 if (nptr->sc == 0) { | |
3060 copy(nptr,name); | |
3061 nptr->sc=EMPTY; | |
3062 nptr->dsp=0; | |
3063 nptr->ty=0; | |
3064 } | |
3065 return nptr; | |
3066 } | |
3067 | |
61 | 3068 static NMTBL * |
30 | 3069 msearch0(char *name) |
3070 { | |
3071 NMTBL *nptr,*iptr; | |
3072 int hash,i; | |
3073 | |
31 | 3074 i = 0; hash = 0; |
30 | 3075 while((name[i])) { |
3076 hash=((7*hash) ^ name[i++]); | |
3077 } | |
3078 iptr=nptr= &mtable[hash%MSYMS]; | |
3079 while(nptr->sc!=0 && neqname(nptr->nm,name)) { | |
3080 if (++nptr== &mtable[MSYMS]) | |
3081 nptr= &mtable[0]; | |
3082 if (nptr==iptr) error(MSERR); | |
3083 } | |
3084 if (nptr->sc == 0) { | |
3085 copy(nptr,name); | |
3086 nptr->sc=EMPTY; | |
3087 nptr->dsp=0; | |
3088 nptr->ty=0; | |
3089 } | |
3090 return nptr; | |
3091 } | |
3092 | |
3093 | |
61 | 3094 static void |
0 | 3095 copy(NMTBL *nptr, char *s) |
3096 { | |
3097 nptr->nm = cheapp; | |
18 | 3098 while((*cheapp++ = *s++)); |
0 | 3099 } |
3100 | |
61 | 3101 static int |
30 | 3102 neqname(char *p,char *q) |
0 | 3103 { |
3104 if (!p) | |
3105 return 0; | |
3106 while(*p && *p!='.') | |
3107 if(*p++ != *q++) return 1; | |
3108 return (*q!=0); | |
3109 } | |
3110 | |
61 | 3111 static void |
0 | 3112 getstring(void) |
3113 { | |
3114 getch(); | |
3115 symval = 0; | |
3116 sptr = cheapp; | |
3117 while (ch != '"') { | |
3118 *cheapp++ = escape(); | |
3119 symval++; | |
3120 if (cheapp >= cheap+CHEAPSIZE) error(STRERR); | |
3121 } | |
3122 getch(); | |
3123 *cheapp++ = '\0'; | |
3124 symval++; | |
3125 } | |
3126 | |
69 | 3127 static int topspc = 0; |
3128 | |
61 | 3129 static int |
0 | 3130 skipspc(void) |
3131 { | |
69 | 3132 /* static int topspc = 0; */ |
3133 | |
67 | 3134 while(ch=='\t'||ch=='\n'||ch==' '||ch=='\r') { |
69 | 3135 if (ch=='\n'||ch=='\r') topspc=1; |
3136 if (topspc) | |
3137 conv->comment_(ch); | |
0 | 3138 getch(); |
67 | 3139 } |
69 | 3140 topspc=0; |
0 | 3141 return ch; |
3142 } | |
3143 | |
61 | 3144 static int |
0 | 3145 getch(void) |
3146 { | |
31 | 3147 if(*chptr) return ch = *chptr++; |
34 | 3148 else if (chptrsave) { |
3149 chptr = chptrsave; | |
3150 ch = chsave; | |
3151 chptrsave = 0; | |
3152 return ch; | |
0 | 3153 } |
3154 getline(); | |
3155 return getch(); | |
3156 } | |
3157 | |
3158 char | |
3159 escape(void) | |
3160 { | |
3161 char c; | |
3162 if ((c=ch) == '\\') { | |
3163 if (digit(c=getch())) { | |
3164 c = ch-'0'; | |
3165 if (digit(getch())) { | |
3166 c = c*8+ch-'0'; | |
3167 if (digit(getch())) { | |
3168 c=c*8+ch-'0';getch(); | |
3169 } | |
3170 } | |
3171 return c; | |
3172 } | |
3173 getch(); | |
3174 switch(c) { | |
3175 case 'n': | |
3176 return '\n'; | |
3177 case 't': | |
3178 return '\t'; | |
3179 case 'b': | |
3180 return '\b'; | |
3181 case 'r': | |
3182 return '\r'; | |
3183 case 'f': | |
3184 return '\f'; | |
3185 case '\n': | |
3186 return escape(); | |
3187 default: | |
3188 return c; | |
3189 } | |
3190 } | |
3191 if (c == '\n') error(EXERR); | |
3192 getch(); | |
3193 return c; | |
3194 } | |
3195 | |
61 | 3196 static FILE * |
0 | 3197 getfname(void) |
3198 { | |
3199 int i; | |
25 | 3200 char *s,name[LBUFSIZE]; |
0 | 3201 FILE *fp; |
3202 | |
3203 getch(); | |
3204 if(skipspc()!='"') error(INCERR); | |
3205 for(i=0;(getch()!='"' && ch!='\n');) { | |
3206 if(i<LBUFSIZE-1) name[i++]=ch; | |
3207 } | |
3208 if(ch=='\n') error(INCERR); | |
3209 name[i]=0; | |
3210 fp = fopen(name,"r") ; | |
25 | 3211 s = name; |
3212 (filep+1)->name0 = cheapp; | |
3213 while((*cheapp++ = *s++)); | |
0 | 3214 return ( (filep+1)->fcb = fp ); |
3215 } | |
3216 | |
18 | 3217 static int macro_if_depth ; |
3218 static int macro_if_current ; | |
3219 static int macro_if_skip ; | |
3220 | |
61 | 3221 static void |
0 | 3222 getline(void) |
3223 { | |
3224 int i; | |
3225 int c; | |
3226 | |
18 | 3227 do { |
3228 lineno++; | |
3229 glineno++; | |
3230 chptr=linebuf; | |
3231 i=0; | |
23 | 3232 while ((*chptr++ = c = getc(filep->fcb)) != '\n') { |
18 | 3233 if (++i > LBUFSIZE-2) error(LNERR); |
3234 if (c==EOF) { | |
3235 error(EOFERR); | |
3236 --chptr; | |
3237 } | |
3238 } | |
3239 *chptr = '\0'; | |
23 | 3240 if (lsrc && !asmf && !macro_if_skip) gen_comment(linebuf); |
20 | 3241 if (*(chptr = linebuf) == '#' && !in_comment) { |
18 | 3242 macro_processing(); |
3243 } | |
23 | 3244 } while(macro_if_skip || linebuf[0] == '#'); |
18 | 3245 } |
3246 | |
61 | 3247 static void |
18 | 3248 macro_processing() |
3249 { | |
3250 int i; | |
3251 int c; | |
3252 int mode_save; | |
3253 | |
3254 ++chptr; | |
19 | 3255 if (macroeq("ifdef") || macroeq("ifndef")) { |
28 | 3256 c = (chptr[-4]=='n'); |
18 | 3257 macro_if_current++; |
3258 if (!macro_if_skip) { | |
19 | 3259 mode_save = mode; mode = IFDEF; |
3260 ch= *chptr; | |
3261 i = getsym(); | |
3262 mode = mode_save; | |
3263 macro_if_depth = macro_if_current; | |
3264 macro_if_skip = (!i)^c; | |
3265 } | |
3266 return; | |
3267 } else if (macroeq("if")) { | |
3268 macro_if_current++; | |
3269 if (!macro_if_skip) { | |
23 | 3270 for(c=0;chptr[c];c++); |
33 | 3271 chptr[c] = ';'; /* this can't happen in macro expression */ |
19 | 3272 ch= *chptr; |
18 | 3273 getsym(); |
69 | 3274 i=cexpr(expr(1)); |
18 | 3275 macro_if_depth = macro_if_current; |
3276 macro_if_skip = !i; | |
3277 } | |
19 | 3278 return; |
18 | 3279 } else if (macroeq("else")) { |
3280 if (macro_if_current==0) { | |
3281 error(MCERR); /* extra #else */ | |
19 | 3282 return; |
18 | 3283 } |
3284 if (macro_if_current == macro_if_depth) | |
3285 macro_if_skip = !macro_if_skip; | |
19 | 3286 return; |
18 | 3287 } else if (macroeq("endif")) { |
3288 if (macro_if_current == macro_if_depth) { | |
3289 macro_if_skip = 0; | |
19 | 3290 macro_if_depth = --macro_if_current; |
18 | 3291 } else { |
19 | 3292 if (macro_if_current<=0) { |
18 | 3293 error(MCERR); /* extra #if */ |
19 | 3294 return; |
18 | 3295 } |
19 | 3296 macro_if_current--; |
18 | 3297 } |
19 | 3298 return; |
3299 } | |
3300 if (macro_if_skip) return; | |
3301 if (macroeq("define")) { | |
32 | 3302 macro_define0(); |
18 | 3303 *(chptr = linebuf) = '\0'; |
19 | 3304 } else if (macroeq("undef")) { |
3305 i=mode; | |
28 | 3306 mode=LDECL; |
19 | 3307 ch= *chptr; |
3308 if (getsym() == IDENT) { | |
3309 if (nptr->sc == MACRO) { | |
3310 nptr->sc = EMPTY; | |
29 | 3311 } else if (nptr->sc == FMACRO) { |
28 | 3312 nptr->sc = EMPTY; |
29 | 3313 /* we cannot reclaim it's arg */ |
19 | 3314 } else error(MCERR); |
3315 } | |
3316 mode=i; | |
18 | 3317 } else if (macroeq("include")) { |
3318 if(filep+1 >= filestack + FILES) error(FILERR); | |
3319 if ( ((filep+1)->fcb=getfname()) == NULL) error(FILERR); | |
3320 (filep+1)->ln=lineno; | |
3321 lineno=0; | |
3322 ++filep; | |
3323 *(chptr = linebuf) = '\0'; | |
3324 } else if (macroeq("asm")) { | |
3325 if (asmf) error(MCERR); | |
3326 asmf = 1; | |
3327 getline(); | |
3328 while (asmf) { | |
3329 gen_source(linebuf); | |
0 | 3330 getline(); |
18 | 3331 } |
3332 } else if (macroeq("endasm")) { | |
3333 if (!asmf) error(MCERR); | |
3334 asmf = 0; | |
3335 } else if (macroeq(" ")) | |
3336 getline(); | |
3337 else error(MCERR); | |
0 | 3338 } |
3339 | |
61 | 3340 static int |
0 | 3341 macroeq(char *s) |
3342 { | |
3343 char *p; | |
3344 | |
3345 for (p = chptr; *s;) if (*s++ != *p++) return 0; | |
3346 chptr = p; | |
3347 return 1; | |
3348 } | |
3349 | |
61 | 3350 static void |
32 | 3351 macro_define(char *macro) |
3352 { | |
3353 char *chptr_save; | |
3354 int chsave; | |
3355 chptr_save = chptr; | |
3356 chsave = ch; | |
3357 chptr = macro; | |
3358 ch= *chptr++; | |
3359 macro_define0(); | |
3360 chptr = chptr_save; | |
3361 ch = chsave; | |
3362 } | |
3363 | |
61 | 3364 static void |
32 | 3365 macro_define0() |
3366 { | |
3367 int i,args,c; | |
3368 i=mode; | |
3369 mode=MDECL; | |
3370 ch= *chptr; | |
3371 getsym(); | |
35 | 3372 /* fprintf(stderr,"macro def: %s =>",name); */ |
32 | 3373 if (nptr->sc != EMPTY) { /* override exisiting macro */ |
3374 } | |
3375 args = 0; | |
3376 if (ch=='(') { | |
3377 nptr->sc = FMACRO; | |
37 | 3378 args = macro_args(&cheapp,cheap+CHEAPSIZE,&chptr); |
32 | 3379 } else { |
3380 nptr->sc = MACRO; | |
33 | 3381 nptr->ty = -1; |
32 | 3382 } |
34 | 3383 nptr->dsp = list2((int)cheapp,args); /* macro body */ |
32 | 3384 while ((*cheapp++ = c = *chptr++) |
34 | 3385 && c != '\n') { |
3386 if (c=='\\' && chptr[1]=='\n') { | |
3387 cheapp--; | |
3388 getline(); | |
3389 } | |
3390 } | |
32 | 3391 *cheapp++ = '\0'; |
3392 if (cheapp >= cheap+CHEAPSIZE) /* too late? */ | |
3393 error(STRERR); | |
35 | 3394 /* fprintf(stderr,"%s\n",(char *)car(nptr->dsp)); */ |
32 | 3395 mode=i; |
3396 } | |
3397 | |
61 | 3398 static int |
37 | 3399 macro_args(char **pcheapp,char *maxcheap,char **pchptr) |
28 | 3400 { |
3401 int c; | |
3402 int in_quote = 0; | |
3403 int in_wquote = 0; | |
3404 int plevel = 0; | |
34 | 3405 char *cheapp = *pcheapp; |
3406 char *chptr = *pchptr; | |
3407 int args = list2((int)cheapp,0); | |
28 | 3408 for(;;) { |
3409 *cheapp++ = c = *chptr++; | |
37 | 3410 if (cheapp >= maxcheap) error(MCERR); |
33 | 3411 if (!c) { |
3412 chptr--; | |
3413 error(MCERR); | |
34 | 3414 *pchptr = chptr; |
3415 *pcheapp = cheapp; | |
33 | 3416 return reverse0(args); |
3417 } | |
28 | 3418 if (in_quote) { |
3419 if (c=='\\') { | |
3420 if (*chptr != '\n') { | |
3421 *cheapp++ = *chptr++; | |
3422 } else { | |
3423 getline(); | |
3424 } | |
3425 } else if (c=='\'') { | |
3426 in_quote = 0; | |
3427 } | |
3428 } else if (in_wquote) { | |
3429 if (c=='\\') { | |
3430 if (*chptr !='\n') { | |
3431 *cheapp++ = *chptr++; | |
3432 } else { | |
3433 *cheapp = '\n'; | |
3434 getline(); | |
3435 } | |
3436 } else if (c=='"') { | |
3437 in_wquote = 0; | |
3438 } | |
3439 } else if (c=='"') { | |
3440 in_wquote = 1; | |
3441 } else if (c=='\'') { | |
3442 in_quote = 1; | |
3443 } if (plevel==0) { | |
3444 if (c==',') { | |
3445 cheapp[-1] = 0; | |
34 | 3446 args = list2((int)cheapp,args); |
28 | 3447 } else if (c==')') { |
3448 cheapp[-1] = 0; | |
3449 break; | |
3450 } else if (c=='(') { | |
3451 plevel++; | |
3452 } else if (c=='\\') { | |
3453 if (*chptr=='\n') { | |
3454 cheapp--; | |
3455 getline(); | |
3456 } | |
3457 } else if (c==' '||c=='\t') { | |
3458 cheapp--; | |
3459 } else if (c=='\n') { | |
3460 cheapp--; | |
3461 getline(); | |
34 | 3462 chptr = *pchptr; |
28 | 3463 } |
3464 } else if (c==')') { | |
3465 plevel--; | |
3466 } else if (c=='\n') { | |
3467 cheapp--; | |
3468 getline(); | |
34 | 3469 chptr = *pchptr; |
28 | 3470 } |
3471 } | |
33 | 3472 ch = *chptr; |
3473 if (ch) chptr++; | |
34 | 3474 *pchptr = chptr; |
3475 *pcheapp = cheapp; | |
28 | 3476 return reverse0(args); |
3477 } | |
3478 | |
34 | 3479 /* output macro expansion result into macrobuf (macropp) */ |
3480 | |
61 | 3481 static int |
34 | 3482 macro_function(int macrop,char **pchptr,NMTBL *nptr,int history) |
28 | 3483 { |
34 | 3484 int args,sargs,values,evalues; |
3485 char *macro; | |
3486 | |
3487 sargs = args = cadr(nptr->dsp); | |
37 | 3488 values = macro_args(¯opp,macro_buf+MACROSIZE,pchptr); |
34 | 3489 evalues = 0; |
3490 while(values) { | |
3491 evalues = list2(macro_eval(0,(char *)car(values),history),evalues); | |
28 | 3492 values = cadr(values); |
3493 } | |
34 | 3494 evalues = reverse0(evalues); |
3495 while(args) { | |
46
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
3496 local_define((char *)car(args),mappend(reverse0(car(evalues)))); |
35 | 3497 /* fprintf(stderr,"%s: %s => %s\n",nptr->nm,(char *)car(args),(char *)car(msearch0((char *)car(args))->dsp)); */ |
34 | 3498 args = cadr(args); |
3499 evalues = cadr(evalues); | |
29 | 3500 } |
34 | 3501 macro = (char *)car(nptr->dsp); |
3502 macrop = macro_eval(macrop,macro,list2((int)macro,history)); | |
35 | 3503 /* fprintf(stderr,"%s: result %s => %s\n",nptr->nm,macro,(char *)car(macrop)); */ |
34 | 3504 args = sargs; |
3505 while(args) { | |
3506 local_undef((char *)car(args)); | |
3507 args = cadr(args); | |
3508 } | |
3509 return macrop; | |
28 | 3510 } |
3511 | |
61 | 3512 static void |
28 | 3513 local_define(char *macro,char *value) |
3514 { | |
3515 NMTBL *nptr0; | |
30 | 3516 nptr0 = msearch0(macro); |
34 | 3517 nptr0->ty=list3(nptr0->sc,nptr0->ty,nptr0->dsp); |
29 | 3518 nptr0->sc=MACRO; |
3519 nptr0->dsp=list2((int)value,0); | |
28 | 3520 } |
3521 | |
61 | 3522 static void |
28 | 3523 local_undef(char *macro) |
3524 { | |
3525 NMTBL *nptr0; | |
3526 int save; | |
30 | 3527 nptr0 = msearch0(macro); |
28 | 3528 save = nptr0->ty; |
3529 nptr0->sc=car(save); | |
33 | 3530 nptr0->dsp=caddr(save); |
3531 nptr0->ty=cadr(save); | |
0 | 3532 } |
3533 | |
61 | 3534 static int |
34 | 3535 macro_eval(int macrop,char *body,int history) |
3536 { | |
3537 int c; | |
3538 int in_quote = 0; | |
3539 int in_wquote = 0; | |
3540 char *macro; | |
3541 int i; | |
3542 NMTBL *nptrm; | |
3543 c = 1; | |
3544 macrop = list2((int)macropp,macrop); | |
3545 while(c && (*macropp++ = c = *body++)) { | |
37 | 3546 if (macropp>macro_buf+MACROSIZE) error(STRERR); |
34 | 3547 if (in_quote) { |
3548 if (c=='\\') { | |
3549 *macropp++ = c = *body++; | |
3550 } else if (c=='\'') { | |
3551 in_quote = 0; | |
3552 } | |
3553 } else if (in_wquote) { | |
3554 if (c=='\\') { | |
3555 *macropp++ = c = *body++; | |
3556 } else if (c=='"') { | |
3557 in_wquote = 0; | |
3558 } | |
3559 } else if (c=='"') { | |
3560 in_wquote = 1; | |
3561 } else if (c=='\'') { | |
3562 in_quote = 1; | |
3563 } else if (alpha(c)) { | |
3564 macropp--; | |
3565 for(i=0;alpha(c)||digit(c);i++) { namebuf[i] = c; c=*body++;} | |
3566 namebuf[i]=0; | |
3567 nptrm = msearch0(namebuf); | |
3568 macro = (char *)car(nptrm->dsp); | |
3569 if (nptrm->sc==MACRO) { | |
3570 while((*macropp++ = *macro++)); | |
3571 macropp[-1]=c; | |
3572 } else if (nptrm->sc==FMACRO) { | |
3573 if(c!='(') error(MCERR); | |
3574 *macropp++=0; | |
3575 macrop = macro_function(macrop,&body,nptrm, | |
3576 list2((int)macro,history)); | |
3577 macrop = list2((int)macropp,macrop); | |
3578 } else { | |
3579 macro = namebuf; | |
3580 while((*macropp++ = *macro++)); | |
3581 macropp[-1]=c; | |
3582 } | |
3583 } | |
3584 } | |
3585 *macropp++=0; | |
3586 return macrop; | |
3587 } | |
3588 | |
3589 int | |
81 | 3590 dlist2(int e1, double d1) |
3591 { | |
3592 int e; | |
3593 | |
3594 e=getfree((size_of_int+size_of_double)/size_of_int); | |
3595 heap[e]=e1; | |
3596 dcadr(e)=d1; | |
3597 return e; | |
3598 } | |
3599 | |
3600 int | |
3601 dlist3(int e1, int e2,double d1) | |
3602 { | |
3603 int e; | |
3604 | |
3605 e=getfree((size_of_int*2+size_of_double)/size_of_int); | |
3606 heap[e]=e1; | |
3607 heap[e+1]=e2; | |
3608 dcaddr(e)=d1; | |
3609 return e; | |
3610 } | |
3611 | |
3612 int | |
0 | 3613 list2(int e1, int e2) |
3614 { | |
3615 int e; | |
3616 | |
3617 e=getfree(2); | |
3618 heap[e]=e1; | |
3619 heap[e+1]=e2; | |
3620 return e; | |
3621 } | |
3622 | |
3623 int | |
3624 list3(int e1, int e2, int e3) | |
3625 { | |
3626 int e; | |
3627 | |
3628 e=getfree(3); | |
3629 heap[e]=e1; | |
3630 heap[e+1]=e2; | |
3631 heap[e+2]=e3; | |
3632 return e; | |
3633 } | |
3634 | |
3635 int | |
3636 list4(int e1, int e2, int e3, int e4) | |
3637 { | |
3638 int e; | |
3639 | |
3640 e=getfree(4); | |
3641 heap[e]=e1; | |
3642 heap[e+1]=e2; | |
3643 heap[e+2]=e3; | |
3644 heap[e+3]=e4; | |
3645 return e; | |
3646 } | |
3647 | |
61 | 3648 static int |
0 | 3649 getfree(int n) |
3650 { | |
3651 int e; | |
3652 | |
3653 switch (mode) { | |
3654 case GDECL: case GSDECL: case GUDECL: case GTDECL: | |
87 | 3655 case MDECL: case ADECL: case LSDECL: case LUDECL: |
0 | 3656 e=gfree; |
3657 gfree+=n; | |
3658 break; | |
3659 default: | |
3660 lfree-=n; | |
3661 e=lfree; | |
3662 } | |
3663 if(lfree<gfree) error(HPERR); | |
3664 return e; | |
3665 } | |
3666 | |
3667 int | |
33 | 3668 glist2(int e1,int e2) |
3669 { | |
3670 int smode,ret; | |
3671 smode = mode; | |
3672 mode = GDECL; | |
3673 ret = list2(e1,e2); | |
3674 mode = smode; | |
3675 return ret; | |
3676 } | |
3677 | |
3678 int | |
0 | 3679 rplacad(int e, int n) |
3680 { | |
3681 heap[e+1]=n; | |
3682 return e; | |
3683 } | |
3684 | |
3685 int | |
3686 rplacadd(int e, int n) | |
3687 { | |
3688 heap[e+2]=n; | |
3689 return e; | |
3690 } | |
3691 | |
46
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
3692 int |
55 | 3693 append4(int p,int a1,int a2,int a3) |
3694 { | |
3695 int p1; | |
3696 if(!p) return list4(a1,0,a2,a3); | |
3697 p1=p; | |
3698 while(cadr(p)) p = cadr(p); | |
3699 rplacad(p,list4(a1,0,a2,a3)); | |
3700 return p1; | |
3701 } | |
3702 | |
3703 int | |
46
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
3704 append3(int p,int a1,int a2) |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
3705 { |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
3706 int p1; |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
3707 if(!p) return list3(a1,0,a2); |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
3708 p1=p; |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
3709 while(cadr(p)) p = cadr(p); |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
3710 rplacad(p,list3(a1,0,a2)); |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
3711 return p1; |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
3712 } |
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
3713 |
61 | 3714 static char * |
46
b1c8ac8c308d
fix cascading struct retrun. Now it should be compatible with gcc
kono
parents:
45
diff
changeset
|
3715 mappend(int lists) |
34 | 3716 { |
3717 char *p; | |
3718 char *result = macropp; | |
3719 while(lists) { | |
37 | 3720 if (macropp>macro_buf+MACROSIZE) error(STRERR); |
34 | 3721 p = (char *)car(lists); |
35 | 3722 while((*macropp++=*p++)) if (p[-1]=='\n') macropp[-1]=' '; |
34 | 3723 macropp--; |
3724 lists = cadr(lists); | |
3725 } | |
3726 macropp++; | |
3727 return result; | |
3728 } | |
7 | 3729 |
18 | 3730 void |
0 | 3731 display_ntable(NMTBL *n, char *s) |
3732 { | |
18 | 3733 fprintf(stderr,"\n%s %0x %0x ",s,(int)n,(int)ntable); |
0 | 3734 fprintf(stderr,"nptr->sc %d ",n->sc); |
3735 fprintf(stderr,"nptr->dsp %d ",n->dsp); | |
3736 fprintf(stderr,"nptr->ty %d ",n->ty); | |
3737 fprintf(stderr,"nptr->nm %s\n",n->nm); | |
3738 } | |
3739 | |
40 | 3740 int c0(int d) { fprintf(stderr,"heap[%d]=",d);return car(d); } |
3741 int c1(int d) { fprintf(stderr,"heap[%d]=",d);return cadr(d); } | |
3742 int c2(int d) { fprintf(stderr,"heap[%d]=",d);return caddr(d); } | |
3743 int c3(int d) { fprintf(stderr,"heap[%d]=",d);return cadddr(d); } | |
3744 char *cc0(int d) { fprintf(stderr,"heap[%d]=",d);return (char *)car(d); } | |
3745 char *cc1(int d) { fprintf(stderr,"heap[%d]=",d);return (char *)cadr(d); } | |
3746 char *cc2(int d) { fprintf(stderr,"heap[%d]=",d);return (char *)caddr(d); } | |
3747 char *cc3(int d) { fprintf(stderr,"heap[%d]=",d);return (char *)cadddr(d); } | |
37 | 3748 |
0 | 3749 /* end */ |