changeset 161:cc2fc5c0dfe5 struct-field-fix

struct field fix
author kono
date Sun, 23 Nov 2003 22:40:26 +0900
parents 1f440a2790fb
children 0c604d2ff585
files Changes Makefile mc-parse.c test/tmp12.c
diffstat 4 files changed, 85 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Sun Nov 23 19:54:02 2003 +0900
+++ b/Changes	Sun Nov 23 22:40:26 2003 +0900
@@ -3478,4 +3478,14 @@
 そうすると、構造体のfiledかどうかをgetsymがチェック
 するときにちょっと困る。
 
-
+filed をlinear searchするのは嫌だけど、しかたないか。
+
+なんか、struct の中に、
+    void (*case_)(int cases,int def);
+とかがあると、
+    void (*case_)();
+    int cases;
+    int def;
+という感じで余計なfieldが定義されてるみたい。
+
+adecl で nptr が引数の最後を指してしまうのがまずかった。
--- a/Makefile	Sun Nov 23 19:54:02 2003 +0900
+++ b/Makefile	Sun Nov 23 22:40:26 2003 +0900
@@ -49,6 +49,7 @@
 	make check TARGET=test/tmp
 	make check TARGET=test/tmp10
 	make check TARGET=test/tmp11
+	make check TARGET=test/tmp12
 	make check TARGET=test/tmp7
 	make check TARGET=test/tmp8
 	make check TARGET=test/tmp9
--- a/mc-parse.c	Sun Nov 23 19:54:02 2003 +0900
+++ b/mc-parse.c	Sun Nov 23 22:40:26 2003 +0900
@@ -533,7 +533,7 @@
 decl1(void)
 {
     NMTBL *n;
-    int i,t,sstmode;
+    int i,t;
 
     if(sym==LPAR) {
 	getsym();
@@ -577,18 +577,14 @@
 		if(sym==RPAR) {
 		    getsym();t=0;
 		} else {
-		    sstmode=stmode; stmode=REGISTER;
 		    t=adecl(n);
-		    stmode=sstmode;
 		}
 		type=glist3(CODE,CODE,t);
 	    } else {
 		if(sym==RPAR) {
 		    getsym();t=0;
 		} else {
-		    sstmode=stmode; stmode=REGISTER;
 		    t=adecl(n);
-		    stmode=sstmode;
 		}
 		type=glist3(FUNCTION,type,t);
 	    }
@@ -610,9 +606,10 @@
 {
     NMTBL *arg,*sfnptr;
     int sreg_var,t;
-    int stype,smode,sd,sargs;
+    int stype,smode,sd,sargs,sstmode;
     int argtypes;
 
+    sstmode=stmode; stmode=REGISTER;
     stype=type;
     sfnptr=fnptr;
     fnptr=n;
@@ -666,6 +663,12 @@
     fnptr=sfnptr;
     type=stype;
     sdecl_f = sd;
+    /* Now nptr is the last of the arguments if any.
+       In struct_fields, nptr have to be a defined funciton
+       pointer body, so nptr should be set back to n.
+       struct { void (*error_)(char *s); } */
+    nptr=n; 
+    stmode=sstmode;
     return argtypes;
 }
 
@@ -1061,22 +1064,33 @@
 static int
 sdecl_field()
 {
-    int tags = 0;
+    int fields = 0;
     while (getsym() != RC) {
         decl();
-        tags = list3(type,tags,(int)nptr);
+        fields = list4(type,fields,(int)(nptr->nm),nptr->dsp);
+	nptr->sc = nptr->ty = 0; nptr->nm = 0;
     }
     if (sdecl_f) conv->rc_();
     getsym();
-    return reverse0(tags);
+    return reverse0(fields);
 }
 
+#if 0
+static void
+print_fields(int fields,char *s) {
+    for(;fields;fields=cadr(fields)) {
+	fprintf(stderr,"%s %s %d %d\n",s,(char*)caddr(fields),car(fields),cadddr(fields));
+    }
+    fprintf(stderr,"\n");
+}
+#endif
+
 static int
 sdecl(int s)
 {
     int smode,sdisp,type0=0;
     NMTBL *nptr0,*gnptr0;
-    int tags;
+    int fields;
 
     smode=mode;
     if (mode==GDECL || mode==GSDECL || mode==GUDECL || mode==GTDECL)
@@ -1095,25 +1109,28 @@
 	    if (nptr0->sc != EMPTY) error(DCERR);
 	    nptr0->sc = TAG;
 	    nptr0->ty = list4(s,-1,0,(int)nptr0);
-	    tags = sdecl_field();
-	    heap[nptr0->ty+2]=tags;
+	    fields = sdecl_field();
+	    heap[nptr0->ty+2]=fields;
 	    rplacad(type0 = nptr0->ty,disp);
+	    /* type0 = list4(s,disp,fields,0); now ... */
 	} else {
 	    /* struct tag name */
 	    if(nptr0->sc == EMPTY) nptr0=gnptr0;
 	    if(nptr0->sc == EMPTY) error(UDERR);
 	    if(nptr0->sc != TAG) error(TYERR);
-	    tags = caddr(nptr0->ty);
+	    fields = caddr(nptr0->ty);
 	    disp = cadr(nptr0->ty);
 	    conv->comment_(' ');
 	}
-	type0 = list4(s,disp,tags,(int)nptr0);
+	type0 = list4(s,disp,fields,(int)nptr0);
     } else if(sym==LC) {
 	if (sdecl_f) conv->lc_();
-	tags = sdecl_field();
-	type0 = list4(s,disp,tags,0);
+	fields = sdecl_field();
+	type0 = list4(s,disp,fields,0);
     }
     else error(DCERR);
+    /* print_fields(fields,"def"); */
+
     stypedecl=1;
     disp=sdisp;
     mode=smode;
@@ -2559,27 +2576,44 @@
 }
 
 static int
+search_struct_type(int t,char *name,int *dsp)
+{
+    for(;t;t = cadr(t)) {
+	if (neqname((char *)caddr(t),name)==0) {
+	    *dsp = cadddr(t);
+	    return car(t);
+	}
+    }
+    return 0;
+}
+
+static int
 strop(int e)
 {
+    int dsp = 0;
+
     getsym();
-    if (sym!=IDENT||nptr->sc!=FIELD) error(TYERR); /* ??? */
+    if (sym!=IDENT) error(TYERR);
     conv->id_(sym,nptr);
     if (integral(type)||(car(type)!=STRUCT && car(type)!=UNION))
 	e=rvalue(e);
-    type = nptr->ty;
-    if(nptr->dsp) {
+    /* type = list4(s,disp,fields,tag_nptr); */
+    /* print_fields(caddr(type),"strop"); */
+    type = search_struct_type(caddr(type),nptr->nm,&dsp);
+    if (!type) { error(TYERR); return INT; }
+    if(dsp) {
 	switch(car(e)) {
 	case GVAR:
-	    e=list2(INDIRECT,list3(ADD,e,list2(CONST,nptr->dsp)));
+	    e=list2(INDIRECT,list3(ADD,e,list2(CONST,dsp)));
 	    break;
 	case LVAR:
-	    e=list2(LVAR,cadr(e) + nptr->dsp);
+	    e=list2(LVAR,cadr(e) + dsp);
 	    break;
 	case INDIRECT:
-	    e=list2(INDIRECT,list3(ADD,cadr(e),list2(CONST,nptr->dsp)));
+	    e=list2(INDIRECT,list3(ADD,cadr(e),list2(CONST,dsp)));
 	    break;
 	default:
-	    e=list2(INDIRECT,list3(ADD,e,list2(CONST,nptr->dsp)));
+	    e=list2(INDIRECT,list3(ADD,e,list2(CONST,dsp)));
 	}
     } else {
 	switch(car(e)) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tmp12.c	Sun Nov 23 22:40:26 2003 +0900
@@ -0,0 +1,16 @@
+
+
+struct {
+    int a;
+    char *b;
+} x1;
+
+// int b;
+
+main()
+{
+    int a;
+    x1.a = 1;
+    a = 133;
+    printf("%d %d\n",x1.a,a);
+}