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