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 */
 }