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