Mercurial > hg > CbC > old > device
diff mc-parse.c @ 308:e1d17d6adfcc
struct field init (first try, no compile error)
author | kono |
---|---|
date | Thu, 10 Jun 2004 16:24:15 +0900 |
parents | fda28752d301 |
children | a86612cf1a19 |
line wrap: on
line diff
--- a/mc-parse.c Wed Jun 09 23:01:18 2004 +0900 +++ b/mc-parse.c Thu Jun 10 16:24:15 2004 +0900 @@ -93,6 +93,7 @@ static void statement(void); static int correct_type(int e,int t); static int arg_reorder(int old_arg,int new_arg); +static int search_struct_type(int t,char *name,int *dsp); static int struct_return = 0; @@ -265,6 +266,7 @@ if (sym != s) { p=(s==RPAR) ? "')'": (s==RBRA) ? "']'": (s==SM) ? "';'": (s==LPAR) ? "'('": (s==WHILE) ? "'while'": + (s==ASS) ? "'='": (s==COLON) ? "':'": "Identifier"; fprintf(stderr,"%d:%s expected.\n",lineno,p); errmsg(); @@ -1103,6 +1105,14 @@ } } +static void +str_init_eq() +{ + // error(-1); // duplicate struct field value +} + +static int decl_str_init; + int assign_data(int e, int t, NMTBL *n,int offset) { @@ -1122,12 +1132,70 @@ e,t,type); init_vars = list2(ass,init_vars); return offset+size(t); + } else if(mode==SFDINIT) { + insert_ascend(decl_str_init,list4(offset,0,e,t),str_init_eq); + return offset+size(t); } else { error(DCERR); } return 0; /* not reached */ } +static void +decl_data_field(int type,NMTBL *n,int offset) +{ + int e,t1; + int foffset; + int offset0 = offset; + int decl_str_init_save = decl_str_init; + int mode_save=mode; + + decl_str_init = 0; + if(cadr(type)==-1) { + error(DCERR); + return; + } + mode=SFDINIT; + t1 = caddr(type); /* list of fields */ + while(t1) { + if (skipspc()=='.') { /* struct/union field initializaer */ + getsym(0); + if (sym==IDENT) { + type = search_struct_type(type,nptr->nm,&foffset); + if (sym==ASS) { + decl_data(type,n,foffset); + continue; + } + } + error(TYERR); /* should be initialization error */ + continue; + } + offset = decl_data(car(t1),n,offset); /* alignment? */ + t1 = cadr(t1); + if ( t1 && sym==COMMA) { conv->comma_(); continue; } + if (!t1 && sym==COMMA) getsym(0); /* extra comma */ + if (sym==RC) break; // premature end + } + mode = mode_save; + offset = offset0; + /* + decl_str_init + list4(offset,next,expression,type); + */ + while (decl_str_init) { + offset= car(decl_str_init); + e=caddr(decl_str_init); + type=cadddr(decl_str_init); + if (offset!=offset0) { + // make space + assign_data(list2(CONST,offset-offset0),EMPTY,n,offset0); + } + offset0 = assign_data(e,type,n,offset); + decl_str_init = cadr(decl_str_init); + } + decl_str_init = decl_str_init_save; +} + static int decl_data(int t, NMTBL *n,int offset) { @@ -1137,12 +1205,11 @@ mode_save = mode; mode=STAT; getsym(0); - if (sym==RC) { /* premature end */ + if (sym==RC) { /* premature end (not necessary?) */ conv->decl_data_end_(); mode = mode_save; return offset; - } - if (scalar(t)) { + } else if (scalar(t)) { e=expr1(); mode = mode_save; if(car(e)!=CONST && t==CHAR) @@ -1150,16 +1217,13 @@ offset = assign_data(e,t,n,offset); type=t; return offset; - } - if (t==FLOAT||t==DOUBLE||t==LONGLONG||t==ULONGLONG) { + } else if (t==FLOAT||t==DOUBLE||t==LONGLONG||t==ULONGLONG) { e=expr1(); mode = mode_save; offset = assign_data(e,t,n,offset); type=t; return offset; - } - t1 = car(t); - if (t1==ARRAY) { + } else if ((t1 = car(t)) && t1==ARRAY) { if (sym==LC) { conv->decl_data_begin_(); mode = mode_save; @@ -1179,8 +1243,6 @@ } getsym(0); return offset; - } else { - error(TYERR); } } /* NOT REACHED */ @@ -1195,33 +1257,23 @@ } else if (caddr(t)!=size(type)) { /* size match? */ error(TYERR); } - } else - error(DCERR); + return offset; /* not reached */ + } } else if (t1==STRUCT) { - if (sym==LC) { - conv->lc_(); conv->decl_data_begin_(); - mode = mode_save; - if(cadr(t)==-1) error(DCERR); - t1 = caddr(t); /* list of fields */ - while(t1) { - offset = decl_data(car(t1),n,offset); /* alignment? */ - t1 = cadr(t1); - if ( t1 && sym==COMMA) { conv->comma_(); continue; } - if (!t1 && sym==COMMA) getsym(0); /* extra comma */ - if (sym==RC) break; // premature end - } - conv->decl_data_end_(); conv->rc_(); - getsym(0); - return offset; + if (sym==LC) { + conv->lc_(); conv->decl_data_begin_(); + mode = mode_save; + decl_data_field(t,n,offset); + conv->decl_data_end_(); conv->rc_(); + checksym(RC); + return offset+size(t); } else if (sym==RC) { /* empty case */ conv->lc_(); return offset; - } else - error(DCERR); - } else { - mode = mode_save; - error(TYERR); /* should be initialization error */ - } + } + } + mode = mode_save; + error(TYERR); /* should be initialization error */ return offset; /* not reached */ }