Make declarator and type parser output detailed types, in addition to old style
authorNick Downing <downing.nick@gmail.com>
Mon, 13 Feb 2017 15:32:07 +0000 (02:32 +1100)
committerNick Downing <downing.nick@gmail.com>
Mon, 13 Feb 2017 15:32:07 +0000 (02:32 +1100)
16 files changed:
c0.h
c00.c
c01.c
c02.c
c03.c
c04.c
ccom.h
test/arr0.c [new file with mode: 0644]
test/arr0.dump [new file with mode: 0644]
test/arr0.s [new file with mode: 0644]
test/arr1.c [new file with mode: 0644]
test/arr1.dump [new file with mode: 0644]
test/arr1.s [new file with mode: 0644]
test/arr2.c [new file with mode: 0644]
test/arr2.dump [new file with mode: 0644]
test/arr2.s [new file with mode: 0644]

diff --git a/c0.h b/c0.h
index dc66d34..28cbec6 100644 (file)
--- a/c0.h
+++ b/c0.h
@@ -250,14 +250,15 @@ void errflush __P((int ao));
 
 /* c03.c */
 int declist __P((int sclass));
-int getkeywords __P((int *scptr, struct nmlist *tptr));
-union str *strdec __P((int mosf, int kind));
-int declare __P((int askw, struct nmlist *tptr, int offset));
-int decl1 __P((int askw, struct nmlist *atptr, int offset, struct nmlist *absname));
+/*int*/struct type *getkeywords __P((int *scptr/*, struct nmlist *tptr*/));
+/*union str*/struct stype *strdec __P((int mosf, int kind));
+int declare __P((int askw, struct /*nmlist*/type *tptr, int offset));
+int decl1 __P((int askw, struct /*nmlist*/type *atptr, int offset, struct nmlist *absname));
 struct nmlist *pushdecl __P((register struct nmlist *sp));
-int getype __P((register struct tdim *dimp, struct nmlist *absname));
+/*int getype __P((register struct tdim *dimp, struct nmlist *absname));*/
+struct type *getype __P((struct type *tptr, int *nullok, int anonok));
 void typov __P((void));
-int align __P((int type, int offset, int aflen));
+int align __P((/*int*/struct type *type, int offset, int aflen));
 void decsyn __P((int o));
 void redec __P((void));
 int goodreg __P((struct nmlist *hp));
@@ -271,8 +272,8 @@ void treeout __P((register struct node *tp, int isstruct));
 void branch0 __P((int lab));
 void label0 __P((int l));
 int plength __P((register struct node *p));
-int length __P((struct node *cs));
-int rlength __P((struct node *cs));
+int length __P((struct /*node*/type *cs));
+int rlength __P((struct /*node*/type *cs));
 int simplegoto __P((void));
 int nextchar __P((void));
 int spnextchar __P((void));
diff --git a/c00.c b/c00.c
index dd99db7..0068fab 100644 (file)
--- a/c00.c
+++ b/c00.c
@@ -158,6 +158,7 @@ int lookup() {
        rp->nl_offset = 0;
        rp->nl_subsp = NULL;
        rp->nl_strp = NULL;
+ rp->nl_dtype = NULL;
        rp->nl_sparent = NULL;
        rp->nl_blklev = blklev;
        rp->nl_flag = mossym;
@@ -716,7 +717,8 @@ advanc:
                  (union str *)NULL, (struct node *)cs, (struct node *)NULL);*/
                cs->nl_flag = 0;
                cs->nl_type = unscflg? ARRAY+UNCHAR:ARRAY+CHAR;
-               cs->nl_strp = (union str *)&nchstr;
+               cs->nl_subsp = &nchstr;
+               cs->nl_strp = (union str *)NULL;
                cs->nl_offset = cval;
                cs->nl_nextnm = 0;
                cs->nl_sparent = 0;
@@ -915,19 +917,22 @@ syntax:
 }
 
 struct tnode *xprtype() {
-       struct nmlist typer, absname;
+       struct nmlist /*typer,*/ absname;
        int sc;
        register struct node **scp;
+ struct type *dtype;
 
        scp = cp;
        sc = DEFXTRN;           /* will cause error if class mentioned */
-       getkeywords(&sc, &typer);
+ /*    getkeywords(&sc, &typer);*/
+ dtype = getkeywords(&sc);
        absname.nl_class = 0;
        absname.nl_blklev = blklev;
        absname.nl_subsp = NULL;
        absname.nl_strp = NULL;
        absname.nl_type = 0;
-       decl1(sc, &typer, 0, &absname);
+ absname.nl_dtype = NULL;
+       decl1(sc, /*&typer*/dtype, 0, &absname);
        cp = scp;
        return(block(ETYPE, absname.nl_type, absname.nl_subsp,
           absname.nl_strp, (struct node *)NULL, (struct node *)NULL));
diff --git a/c01.c b/c01.c
index b2c57f2..e4ce031 100644 (file)
--- a/c01.c
+++ b/c01.c
@@ -46,7 +46,7 @@ void build(op) int op; {
         * sizeof gets turned into a number here.
         */
        if (op==SIZEOF) {
-               struct cnode *p = cblock(length(p1));
+               struct cnode *p = cblock(length(/*p1*/p1->n_dtype));
                p->cn_type = UNSIGN;
                *cp++ = (struct node *)p;
                return;
@@ -581,6 +581,67 @@ void error0(s, va_alist) char *s; va_dcl
  * setting the operator, type, dimen/struct table ptrs,
  * and the operands.
  */
+/*static struct type *newtype(type, dimp, strp) int type; int **dimp; union str *strp; {
+ struct type *t;
+ static struct type basic_types[] = {
+  {INT},
+  {CHAR},
+  {FLOAT},
+  {DOUBLE},
+  {STRUCT},
+  {RSTRUCT},
+  {LONG},
+  {UNSIGN},
+  {UNCHAR},
+  {UNLONG},
+  {VOID}
+ };
+
+ switch (type & XTYPE) {
+ case PTR:
+  fprintf(stderr, "ptr(");
+#define pt (*(struct ptype **)&t)
+  pt = (struct ptype *)Tblock(sizeof(struct ptype));
+  pt->pt_id = PTR;
+  pt->pt_ptotype = newtype((type >> TYLEN & ~TYPE) | (type & TYPE), dimp, strp);
+  break;
+#undef pt
+ case FUNC:
+  fprintf(stderr, "func(");
+#define ft (*(struct ftype **)&t)
+  ft = (struct ftype *)Tblock(sizeof(struct ftype));
+  ft->ft_id = PTR;
+  ft->ft_rettype = newtype((type >> TYLEN & ~TYPE) | (type & TYPE), dimp, strp);
+  break;
+#undef ft
+ case ARRAY:
+  if (*dimp)
+   fprintf(stderr, "array(%d, ", *dimp);
+  else
+   fprintf(stderr, "array(?, ");
+#define at (*(struct atype **)&t)
+  at = (struct atype *)Tblock(sizeof(struct atype));
+  at->at_id = PTR;
+  at->at_nelt = *dimp ? *(*dimp)++ : 0;
+  at->at_elttype = newtype((type >> TYLEN & ~TYPE) | (type & TYPE), dimp, strp);
+  break;
+#undef at
+ default:
+  fprintf(stderr, "basic(%d", type);
+  if (type == STRUCT) {
+#define st (*(struct stype **)&t)
+   st = (struct stype *)Tblock(sizeof(struct stype));
+   st->st_id = STRUCT;
+   st->st_S = *(struct SS *)strp;
+#undef st
+  }
+  else
+   t = basic_types + type;
+  break;
+ }
+ fprintf(stderr, ")");
+ return t;
+}*/
 struct tnode *block(op, t, subs, str, p1, p2) int op; int t; int *subs; union str *str; struct node *p1; struct node *p2; {
        register struct tnode *p;
 
@@ -589,6 +650,9 @@ struct tnode *block(op, t, subs, str, p1, p2) int op; int t; int *subs; union st
        p->tn_type = t;
        p->tn_subsp = subs;
        p->tn_strp = str;
+ /*fprintf(stderr, "newtype ");
+ p->tn_dtype = newtype(t, &subs, str);
+ fprintf(stderr, "\n");*/
        p->tn_tr1 = p1;
        if (opdope0[op]&BINARY)
                p->tn_tr2 = p2;
@@ -619,6 +683,7 @@ struct nnode *nblock(ds) register struct nmlist *ds; {
        p->nn_type = ds->nl_type;
        p->nn_subsp = ds->nl_subsp;
        p->nn_strp = ds->nl_strp;
+ p->nn_dtype = ds->nl_dtype;
        p->nn_nmlist = ds;
        p->nn_class = ds->nl_class==0?STATIC:ds->nl_class;
        p->nn_regno = 0;
@@ -631,12 +696,14 @@ struct nnode *nblock(ds) register struct nmlist *ds; {
  */
 struct cnode *cblock(value) _INT value; {
        register struct cnode *p;
+ static struct type t_int = {INT};
 
        p = (struct cnode *)Tblock(sizeof(struct cnode));
        p->cn_op = CON;
        p->cn_type = INT;
        p->cn_subsp = NULL;
        p->cn_strp = NULL;
+ p->cn_dtype = &t_int;
        p->cn_value = value;
        return(p);
 }
@@ -646,12 +713,14 @@ struct cnode *cblock(value) _INT value; {
  */
 struct lnode *lblock(lvalue) _LONG lvalue; {
        register struct lnode *p;
+ static struct type t_long = {LONG};
 
        p = (struct lnode *)Tblock(sizeof(struct lnode));
        p->ln_op = LCON;
        p->ln_type = LONG;
        p->ln_subsp = NULL;
        p->ln_strp = NULL;
+ p->ln_dtype = &t_long;
        p->ln_lvalue = lvalue;
        return(p);
 }
@@ -661,12 +730,14 @@ struct lnode *lblock(lvalue) _LONG lvalue; {
  */
 struct fnode *fblock(value, fvalue) int value; _DOUBLE fvalue; {
        register struct fnode *p;
+ static struct type t_double = {DOUBLE};
 
        p = (struct fnode *)Tblock(sizeof(struct fnode));
        p->fn_op = FCON;
        p->fn_type = DOUBLE;
        p->fn_subsp = NULL;
        p->fn_strp = NULL;
+ p->fn_dtype = &t_double;
        p->fn_value = value;
        p->fn_fvalue = fvalue;
        return(p);
@@ -980,6 +1051,19 @@ void assignop(op, p1, p2) int op; register struct node *p1; register struct node
  */
 struct nmlist *gentemp(type) int type; {
        register struct nmlist *tp;
+ static struct type basic_types[] = {
+  {INT},
+  {CHAR},
+  {FLOAT},
+  {DOUBLE},
+  {STRUCT},
+  {RSTRUCT},
+  {LONG},
+  {UNSIGN},
+  {UNCHAR},
+  {UNLONG},
+  {VOID}
+ };
 
        tp = (struct nmlist *)Tblock(sizeof(struct nmlist));
        tp->nl_class = AUTO;
@@ -987,8 +1071,9 @@ struct nmlist *gentemp(type) int type; {
        tp->nl_flag = 0;
        tp->nl_subsp = NULL;
        tp->nl_strp = NULL;
+ tp->nl_dtype = basic_types + type;
        tp->nl_blklev = blklev;
-       autolen -= rlength((struct node *)tp);
+       autolen -= rlength(/*(struct node *)tp*/tp->nl_dtype);
        tp->nl_offset = autolen;
        if (autolen < maxauto)
                maxauto = autolen;
diff --git a/c02.c b/c02.c
index d140ed7..2578b6d 100644 (file)
--- a/c02.c
+++ b/c02.c
@@ -11,7 +11,8 @@
 void extdef() {
        register int o;
        int sclass, scflag;
-       struct nmlist typer;
+ /*    struct nmlist typer;*/
+ struct type *dtype;
        register struct nmlist *ds;
 
        if(((o=symbol())==EOFC) || o==SEMI)
@@ -19,7 +20,7 @@ void extdef() {
        peeksym = o;
        sclass = 0;
        blklev = 0;
-       if (getkeywords(&sclass, &typer)==0) {
+       if (/*getkeywords(&sclass, &typer)==0*/(dtype = getkeywords(&sclass)) == NULL) {
                sclass = EXTERN;
                if (peeksym!=NAME)
                        goto syntax;
@@ -36,19 +37,20 @@ void extdef() {
                paraml = NULL;
                parame = NULL;
                if (sclass==TYPEDEF) {
-                       decl1(TYPEDEF, &typer, 0, (struct nmlist *)NULL);
+                       decl1(TYPEDEF, /*&typer*/dtype, 0, (struct nmlist *)NULL);
                        continue;
                }
-               decl1(EXTERN, &typer, 0, (struct nmlist *)NULL);
+               decl1(EXTERN, /*&typer*/dtype, 0, (struct nmlist *)NULL);
                if ((ds=defsym)==0)
                        return;
                funcsym = ds;
-               if ((ds->nl_type&XTYPE)==FUNC) {
+               if (/*(ds->nl_type&XTYPE)*/ds->nl_dtype->t_id==FUNC) {
                        if ((peeksym=symbol())==LBRACE || peeksym==KEYW
                         || (peeksym==NAME && csym->nl_class==TYPEDEF)) {
  /* create a fake local variable of same type as function's return type */
                                funcblk.locnn_type = decref0(ds->nl_type);
                                funcblk.locnn_strp = ds->nl_strp;
+ funcblk.locnn_dtype = ds->nl_dtype;
                                setinit(ds);
                                outcode("BS", SYMDEF, sclass==EXTERN?ds->nl_name:"");
                                cfunc();
@@ -58,7 +60,7 @@ void extdef() {
                                error0("Inappropriate parameters");
                } else if ((o=symbol())==COMMA || o==SEMI) {
                        peeksym = o;
-                       o = (length((struct node *)ds)+ALIGN) & ~ALIGN;
+                       o = (length(/*(struct node *)ds*/ds->nl_dtype)+ALIGN) & ~ALIGN;
                        if (sclass==STATIC) {
                                setinit(ds);
                                outcode("BSBBSBN", SYMDEF, "", BSS, NLABEL, ds->nl_name, SSPACE, o);
@@ -142,7 +144,7 @@ int cinit(anp, flex, sclass) struct nmlist *anp; int flex; int sclass; {
                isarray++;
        else
                flex = 0;
-       width = length((struct node *)&np);
+       width = length(/*(struct node *)&np*/np.nl_dtype);
        nel = 1;
        /*
         * If it's an array, find the number of elements.
@@ -155,9 +157,10 @@ int cinit(anp, flex, sclass) struct nmlist *anp; int flex; int sclass; {
        if (isarray) {
                np.nl_type = decref0(realtype);
                np.nl_subsp++;
+ np.nl_dtype = ((struct atype *)np.nl_dtype)->at_elttype;
                if (width==0 && flex==0)
                        error0("0-length row: %s", anp->nl_name);
-               o = length((struct node *)&np);
+               o = length(/*(struct node *)&np*/np.nl_dtype);
                nel = (unsigned)width/o;
                width = o;
        }
@@ -704,7 +707,7 @@ void funchead() {
                        cs->nl_type -= (ARRAY-PTR);     /* set ptr */
                        cs->nl_subsp++;         /* pop dims */
                }
-               pl += rlength((struct node *)cs);
+               pl += rlength(/*(struct node *)cs*/cs->nl_dtype);
                if (cs->nl_class==AREG && (hreg.nl_offset=goodreg(cs))>=0) {
                        st = starttree();
                        *cp++ = (struct node *)&areg;
diff --git a/c03.c b/c03.c
index e4c4760..a417cf3 100644 (file)
--- a/c03.c
+++ b/c03.c
@@ -5,6 +5,7 @@
  * externals.
  */
 
+#include <stdlib.h>
 #include <string.h>
 #include "c0.h"
 
  */
 int declist(sclass) int sclass; {
        register int sc, offset;
-       struct nmlist typer;
+ /*    struct nmlist typer;*/
+ struct type *dtype;
+ static struct type t_int = {INT};
 
        offset = 0;
        sc = sclass;
-       while (getkeywords(&sclass, &typer)) {
-               offset = declare(sclass, &typer, offset);
+       while (/*getkeywords(&sclass, &typer)*/(dtype = getkeywords(&sclass)) != NULL) {
+               offset = declare(sclass, /*&typer*/dtype, offset);
                sclass = sc;
        }
-       return(offset+align(INT, offset, 0));
+       return(offset+align(/*INT*/&t_int, offset, 0));
 }
 
 /*
@@ -29,19 +32,34 @@ int declist(sclass) int sclass; {
  * Store back the storage class, and fill in the type
  * entry, which looks like a hash table entry.
  */
-int getkeywords(scptr, tptr) int *scptr; struct nmlist *tptr; {
+/*int*/struct type *getkeywords(scptr/*, tptr*/) int *scptr; /*struct nmlist *tptr;*/ {
        register int skw, tkw, longf;
        int o, isadecl, ismos, unsignf;
+ struct type *dtype;
+ static struct type basic_types[] = {
+  {INT},
+  {CHAR},
+  {FLOAT},
+  {DOUBLE},
+  {STRUCT},
+  {RSTRUCT},
+  {LONG},
+  {UNSIGN},
+  {UNCHAR},
+  {UNLONG},
+  {VOID}
+ };
 
        isadecl = 0;
        longf = 0;
        unsignf = 0;
      tptr->nl_type = INT;
/*    tptr->nl_type = INT;
        tptr->nl_strp = NULL;
-       tptr->nl_subsp = NULL;
+       tptr->nl_subsp = NULL;*/
        tkw = -1;
        skw = *scptr;
        ismos = skw==MOS||skw==MOU? FMOS: 0;
+ dtype = NULL;
        for (;;) {
                mosflg = isadecl? ismos: 0;
                o = symbol();
@@ -49,8 +67,9 @@ int getkeywords(scptr, tptr) int *scptr; struct nmlist *tptr; {
                        if (tkw >= 0)
                                error0("type clash");
                        tkw = csym->nl_type;
-                       tptr->nl_subsp = csym->nl_subsp;
-                       tptr->nl_strp = csym->nl_strp;
+ /*                    tptr->nl_subsp = csym->nl_subsp;
+                       tptr->nl_strp = csym->nl_strp;*/
+ dtype = csym->nl_dtype;
                        isadecl++;
                        continue;
                }
@@ -80,21 +99,31 @@ int getkeywords(scptr, tptr) int *scptr; struct nmlist *tptr; {
                case ENUM:
                        if (longf || unsignf)
                                error0("Perverse modifier on 'enum'");
-                       strdec(ismos, cval);
+ /*                    strdec(ismos, cval);*/
+ if (dtype)
+  error0("type clash");
+ dtype = (struct type *)strdec(ismos, cval);
                        cval = INT;
                        goto types;
 
                case UNION:
                case STRUCT:
-                       tptr->nl_strp = strdec(ismos, cval);
+ /*                    tptr->nl_strp = strdec(ismos, cval); */
+ if (dtype)
+  error0("type clash");
+ dtype = (struct type *)strdec(ismos, cval);
                        cval = STRUCT;
+ goto types;
                case INT:
                case CHAR:
                case FLOAT:
                case DOUBLE:
                case VOID:
+ if (dtype)
+  goto type_clash;
                types:
                        if (tkw>=0 && (tkw!=INT || cval!=INT))
+ type_clash:
                                error0("Type clash");
                        tkw = cval;
                        if (unscflg && cval==CHAR)
@@ -104,12 +133,14 @@ int getkeywords(scptr, tptr) int *scptr; struct nmlist *tptr; {
                default:
                        peeksym = o;
                        if (isadecl==0)
-                               return(0);
+                               return(/*0*/NULL);
                        if (tkw<0)
                                tkw = INT;
                        if (skw==0)
                                skw = blklev==0? DEFXTRN: AUTO;
                        if (unsignf) {
+ if (dtype)
+  goto misplaced_unsigned;
                                if (tkw==INT)
                                        tkw = UNSIGN;
                                else if (tkw==CHAR)
@@ -117,9 +148,12 @@ int getkeywords(scptr, tptr) int *scptr; struct nmlist *tptr; {
                                else if (tkw==LONG)
                                        tkw = UNLONG;
                                else
+ misplaced_unsigned:
                                        error0("Misplaced 'unsigned'");
                        }
                        if (longf) {
+ if (dtype)
+  goto misplaced_long;
                                if (tkw==FLOAT)
                                        tkw = DOUBLE;
                                else if (tkw==INT)
@@ -127,11 +161,13 @@ int getkeywords(scptr, tptr) int *scptr; struct nmlist *tptr; {
                                else if (tkw==UNSIGN)
                                        tkw = UNLONG;
                                else
+ misplaced_long:
                                        error0("Misplaced 'long'");
                        }
                        *scptr = skw;
-                       tptr->nl_type = tkw;
-                       return(1);
+ /*                    tptr->nl_type = tkw;
+                       return(1);*/
+ return dtype ? dtype : basic_types + tkw;
                }
                isadecl++;
        }
@@ -141,17 +177,18 @@ int getkeywords(scptr, tptr) int *scptr; struct nmlist *tptr; {
  * Process a structure, union, or enum declaration; a subroutine
  * of getkeywords.
  */
-union str *strdec(mosf, kind) int mosf; int kind; {
+/*union str*/struct stype *strdec(mosf, kind) int mosf; int kind; {
        register int elsize, o;
        register struct nmlist *ssym;
        int savebits;
        struct nmlist **savememlist;
        union str *savesparent;
        int savenmems;
-       union str *strp;
+ /*    union str *strp;*/
+ struct stype *stype;
        struct nmlist *ds;
        struct nmlist *mems[NMEMS];
-       struct nmlist typer;
+ /*    struct nmlist typer;*/
        int tagkind;
 
        if (kind!=ENUM) {
@@ -177,15 +214,23 @@ union str *strdec(mosf, kind) int mosf; int kind; {
                }
                if (ssym->nl_class==0) {
                        ssym->nl_class = tagkind;
-                       ssym->nl_strp = (union str *)Dblock(sizeof(struct SS));
-                       ssym->nl_strp->S.ssize = 0;
-                       ssym->nl_strp->S.memlist = NULL;
+ /*                    ssym->nl_strp = (union str *)Dblock(sizeof(struct SS));*/
+ stype = (struct stype *)Dblock(sizeof(struct stype));
+ stype->st_id = STRUCT;
+ ssym->nl_strp = (union str *)&stype->st_S;
+ ssym->nl_dtype = (struct type *)stype;
+                       /*ssym->nl_strp->S.ssize*/stype->st_ssize = 0;
+                       /*ssym->nl_strp->S.memlist*/stype->st_memlist = NULL;
                }
-               strp = ssym->nl_strp;
+ /*            strp = ssym->nl_strp;*/
+ else
+  stype = (struct stype *)ssym->nl_dtype;
        } else {
-               strp = (union str *)Dblock(sizeof(struct SS));
-               strp->S.ssize = 0;
-               strp->S.memlist = NULL;
+ /*            strp = (union str *)Dblock(sizeof(struct SS));*/
+ stype = (struct stype *)Dblock(sizeof(struct stype));
+ stype->st_id = STRUCT;
+               /*strp->S.ssize*/stype->st_ssize = 0;
+               /*strp->S.memlist*/stype->st_memlist = NULL;
        }
        mosflg = 0;
        if (o != LBRACE) {
@@ -202,18 +247,19 @@ union str *strdec(mosf, kind) int mosf; int kind; {
                savesparent = sparent;
                savenmems = nmems;
                memlist = mems;
-               sparent = strp;
+               sparent = /*strp*/(union str *)&stype->st_S;
                nmems = 2;
                bitoffs = 0;
                if (kind==ENUM) {
                      typer.nl_type = INT;
/*                    typer.nl_type = INT;
                        typer.nl_strp = strp;
-                       declare(ENUM, &typer, 0);
+                       declare(ENUM, &typer, 0);*/
+ abort();
                } else
                        elsize = declist(kind==UNION?MOU:MOS);
                bitoffs = savebits;
 #if 1 /* just save a bit of string space */
-               if (strp->S.ssize) {
+               if (/*strp->S.ssize*/stype->st_ssize) {
                        defsym = ssym;
                        redec();
                }
@@ -223,18 +269,18 @@ union str *strdec(mosf, kind) int mosf; int kind; {
                if (strp->S.ssize)
                        error0("%s redeclared", ssym->nl_name);
 #endif
-               strp->S.ssize = elsize;
+               /*strp->S.ssize*/stype->st_ssize = elsize;
                *memlist++ = NULL;
-               strp->S.memlist = (struct nmlist **)Dblock((memlist-mems)*sizeof(*memlist));
+               /*strp->S.memlist*/stype->st_memlist = (struct nmlist **)Dblock((memlist-mems)*sizeof(*memlist));
                for (o=0; &mems[o] != memlist; o++)
-                       strp->S.memlist[o] = mems[o];
+                       /*strp->S.memlist*/stype->st_memlist[o] = mems[o];
                memlist = savememlist;
                sparent = savesparent;
                nmems = savenmems;
                if ((o = symbol()) != RBRACE)
                        goto syntax;
        }
-       return(strp);
+       return(/*strp*/stype);
    syntax:
        decsyn(o);
        return(0);
@@ -243,10 +289,11 @@ union str *strdec(mosf, kind) int mosf; int kind; {
 /*
  * Process a comma-separated list of declarators
  */
-int declare(askw, tptr, offset) int askw; struct nmlist *tptr; int offset; {
+int declare(askw, tptr, offset) int askw; struct /*nmlist*/type *tptr; int offset; {
        register unsigned o;
        register int skw, isunion;
        struct nmlist abs, *aptr;
+ static struct type t_char = {CHAR};
 
        skw = askw;
        isunion = 0;
@@ -255,7 +302,7 @@ int declare(askw, tptr, offset) int askw; struct nmlist *tptr; int offset; {
                isunion++;
                mosflg = FMOS;
                if ((peeksym=symbol()) == SEMI) {
-                       o = length((struct node *)tptr);
+                       o = length(/*(struct node *)*/tptr);
                        if (o>offset)
                                offset = o;
                }
@@ -281,7 +328,7 @@ int declare(askw, tptr, offset) int askw; struct nmlist *tptr; int offset; {
                        aptr = NULL;
                o = decl1(skw, tptr, isunion?0:offset, aptr);
                if (isunion) {
-                       o += align(CHAR, o, 0);
+                       o += align(/*CHAR*/&t_char, o, 0);
                        if (o>offset)
                                offset = o;
                } else
@@ -299,20 +346,70 @@ int declare(askw, tptr, offset) int askw; struct nmlist *tptr; int offset; {
 /*
  * Process a single declarator
  */
-int decl1(askw, atptr, offset, absname) int askw; struct nmlist *atptr; int offset; struct nmlist *absname; {
+/* convert detailed type description to old type description */
+static int oldtype(dtype, dimp, strp) struct type *dtype; struct tdim *dimp; struct SS **strp; {
+ int type;
+ switch (dtype->t_id) {
+ case PTR:
+  /*fprintf(stderr, "ptr(");*/
+  type = oldtype(((struct ptype *)dtype)->pt_ptotype, dimp, strp);
+  if (type & BIGTYPE) {
+   typov();
+   type = 0;
+  }
+  type = (type & TYPE) | (type & ~TYPE) << TYLEN | PTR;
+  break;
+ case FUNC:
+  /*fprintf(stderr, "func(");*/
+  type = oldtype(((struct ftype *)dtype)->ft_rettype, dimp, strp);
+  if (type & BIGTYPE) {
+   typov();
+   type = 0;
+  }
+  type = (type & TYPE) | (type & ~TYPE) << TYLEN | FUNC;
+  break;
+ case ARRAY:
+  /*fprintf(stderr, "array(%d, ", ((struct atype *)dtype)->at_nelt);*/
+  if (dimp->rank>=5) {
+   error0("Rank too large");
+   dimp->rank = 4;
+  }
+  dimp->dimens[dimp->rank++] = ((struct atype *)dtype)->at_nelt;
+  type = oldtype(((struct atype *)dtype)->at_elttype, dimp, strp);
+  if (type & BIGTYPE) {
+   typov();
+   type = 0;
+  }
+  type = (type & TYPE) | (type & ~TYPE) << TYLEN | ARRAY;
+  break;
+ case STRUCT:
+  *strp = &((struct stype *)dtype)->st_S;
+  goto got_strp;
+ default:
+  *strp = NULL;
+ got_strp:
+  /*fprintf(stderr, "basic(%d", dtype->t_id);*/
+  type = dtype->t_id;
+ }
+ /*fprintf(stderr, ")", type);*/
+ return type;
+}
+int decl1(askw, atptr, offset, absname) int askw; struct /*nmlist*/type *atptr; int offset; struct nmlist *absname; {
        int t1, a, elsize;
        register int skw;
+ struct type *dtype;
        int type;
        register struct nmlist *dsym;
-       register struct nmlist *tptr;
+       register struct /*nmlist*/type *tptr;
        struct tdim dim;
+ struct SS *strp;
        int *dp;
        int isinit;
 
        skw = askw;
        tptr = atptr;
        mosflg = skw==MOS? FMOS: 0;
-       dim.rank = 0;
+ /*    dim.rank = 0;*/
        if (((peeksym=symbol())==SEMI || peeksym==RPARN) && absname==NULL)
                return(0);
        /*
@@ -325,16 +422,18 @@ int decl1(askw, atptr, offset, absname) int askw; struct nmlist *atptr; int offs
                        error0("Negative field width");
                        t1 = 0;
                }
-               elsize = align(tptr->nl_type, offset, t1);
+               elsize = align(tptr/*->nl_type*/, offset, t1);
                bitoffs += t1;
                return(elsize);
        }
      t1 = getype(&dim, absname);
/*    t1 = getype(&dim, absname);
        if (t1 == -1)
-               return(0);
+               return(0);*/
+ a = 1; /* nullok */
+ dtype = getype(tptr, &a, absname != NULL);
        if (defsym)
                absname = NULL;
      if (tptr->nl_subsp) {
/*    if (tptr->nl_subsp) {
                type = tptr->nl_type;
                for (a=0; type&XTYPE;) {
                        if ((type&XTYPE)==ARRAY)
@@ -351,8 +450,12 @@ int decl1(askw, atptr, offset, absname) int askw; struct nmlist *atptr; int offs
                type = type<<TYLEN | (t1 & XTYPE);
                t1 >>= TYLEN;
        }
-       type |= tptr->nl_type&TYPE;
-       if ((type&XTYPE) == FUNC) {
+       type |= tptr->nl_type&TYPE;*/
+ dim.rank = 0;
+ /*fprintf(stderr, "oldtype ");*/
+ type = oldtype(dtype, &dim, &strp);
+ /*fprintf(stderr, "\n");*/
+       if (/*(type&XTYPE)*/dtype->t_id == FUNC) {
                if (skw==AUTO)
                        skw = EXTERN;
                if ((skw!=EXTERN && skw!=TYPEDEF) && absname==NULL)
@@ -383,6 +486,7 @@ int decl1(askw, atptr, offset, absname) int askw; struct nmlist *atptr; int offs
                } else
                        defsym = dsym = pushdecl(dsym);
        }
+ /* XXX change all of this stuff to recursively compare types */
        if (dim.rank == 0)
                dsym->nl_subsp = NULL;
        else {
@@ -420,12 +524,20 @@ int decl1(askw, atptr, offset, absname) int askw; struct nmlist *atptr; int offs
                goto syntax;
        }
        if (dsym->nl_class && (dsym->nl_type&TYPE)==STRUCT && (type&TYPE)==STRUCT)
-               if (dsym->nl_strp != tptr->nl_strp) {
+               if (dsym->nl_strp != /*tptr->nl_strp*/(union str *)&((struct stype *)tptr)->st_S) {
                        error0("structure redeclaration");
                }
+ /* to here */
+ /*fprintf(stderr, "dsym %s class %08x type %08x\n", dsym->nl_name, skw, type);
+ fprintf(stderr, "rank %d", dim.rank);
+ for (a=0; a<dim.rank; a++)
+  fprintf(stderr, " %d", dim.dimens[a]);
+ fprintf(stderr, "\n");*/
        dsym->nl_type = type;
-       if (tptr->nl_strp)
-               dsym->nl_strp = tptr->nl_strp;
+ dsym->nl_dtype = dtype;
+ /*    if (tptr->nl_strp)
+               dsym->nl_strp = tptr->nl_strp;*/
+ dsym->nl_strp = (union str *)strp;
        if (skw==TYPEDEF) {
                dsym->nl_class = TYPEDEF;
                return(0);
@@ -441,12 +553,12 @@ int decl1(askw, atptr, offset, absname) int askw; struct nmlist *atptr; int offs
        }
        elsize = 0;
        if (skw==MOS) {
-               elsize = length((struct node *)dsym);
+               elsize = length(/*(struct node *)dsym*/dtype);
                if ((peeksym = symbol())==COLON) {
                        elsize = 0;
                        peeksym = -1;
                        t1 = conexp();
-                       a = align(type, offset, t1);
+                       a = align(/*type*/dtype, offset, t1);
                        if (dsym->nl_flag&FFIELD) {
                                if (dsym->nl_strp->F.bitoffs!=bitoffs
                                 || dsym->nl_strp->F.flen!=t1)
@@ -459,7 +571,7 @@ int decl1(askw, atptr, offset, absname) int askw; struct nmlist *atptr; int offs
                        dsym->nl_strp->F.flen = t1;
                        bitoffs += t1;
                } else
-                       a = align(type, offset, 0);
+                       a = align(/*type*/dtype, offset, 0);
                elsize += a;
                offset += a;
                if (++nmems >= NMEMS) {
@@ -485,14 +597,14 @@ int decl1(askw, atptr, offset, absname) int askw; struct nmlist *atptr; int offs
        if (skw==AUTO) {
        /*      if (STAUTO < 0) {       */
  /*fprintf(stderr, "%s autolen %d -> ", dsym->nl_name, autolen);*/
-                       autolen -= rlength((struct node *)dsym);
+                       autolen -= rlength(/*(struct node *)dsym*/dtype);
                        dsym->nl_offset = autolen;
                        if (autolen < maxauto)
                                maxauto = autolen;
  /*fprintf(stderr, "%d maxauto %d\n", autolen, maxauto);*/
        /*      } else {                        */
        /*              dsym->nl_offset = autolen;      */
-       /*              autolen += rlength(dsym);       */
+       /*              autolen += rlength(*//*(struct node *)dsym*//*dtype);   */
        /*              if (autolen > maxauto)          */
        /*                      maxauto = autolen;      */
        /*      }                       */
@@ -507,7 +619,7 @@ int decl1(askw, atptr, offset, absname) int askw; struct nmlist *atptr; int offs
                                outcode("B", EVEN);
                } else
                        outcode("BBNBN", BSS, LABEL, isn0++, SSPACE,
-                         rlength((struct node *)dsym));
+                         rlength(/*(struct node *)dsym*/dtype));
                outcode("B", PROG);
                isinit = 0;
        } else if (skw==REG && isinit) {
@@ -557,7 +669,7 @@ struct nmlist *pushdecl(sp) register struct nmlist *sp; {
 /*
  * Read a declarator and get the implied type
  */
-int getype(dimp, absname) register struct tdim *dimp; struct nmlist *absname; {
+/*int getype(dimp, absname) register struct tdim *dimp; struct nmlist *absname; {
        static struct nmlist argtype;
        int type;
        register int o;
@@ -646,6 +758,106 @@ int getype(dimp, absname) register struct tdim *dimp; struct nmlist *absname; {
 syntax:
        decsyn(o);
        return(-1);
+}*/
+static struct type *getail(dtype, nullok) struct type *dtype; int *nullok; {
+       static struct type argtype = {INT};
+       struct type *t;
+       register int o;
+       register struct nmlist *ds;
+
+       switch(o=symbol()) {
+
+       case LPARN:
+               if (blklev==0) {
+                       blklev++;
+                       ds = defsym;
+                       declare(ARG1, &argtype, 0);
+                       defsym = ds;
+                       blklev--;
+               } else
+                       if ((o=symbol()) != RPARN)
+                               goto syntax;
+#define ft (*(struct ftype **)&t)
+               ft = (struct ftype *)Dblock(sizeof(struct ftype));
+               ft->ft_id = FUNC;
+               ft->ft_rettype = getail(dtype, nullok);
+               ft->ft_arglist = NULL;
+               return (struct type *)ft;
+#undef ft
+
+       case LBRACK:
+               if ((o=symbol()) != RBRACK) {
+                       peeksym = o;
+                       ds = defsym;
+                       cval = conexp();
+                       defsym = ds;
+                       if ((o=symbol())!=RBRACK)
+                               goto syntax;
+               } else {
+ /* note: this was (and remains) incorrect, as fooled by complicated types */
+                       if (!*nullok)
+                               error0("Null dimension");
+                       cval = 0;
+               }
+               *nullok = 0;
+#define at (*(struct atype **)&t)
+               at = (struct atype *)Dblock(sizeof(struct atype));
+               at->at_id = ARRAY;
+               at->at_nelt = cval;
+               at->at_elttype = getail(dtype, nullok); /* destroys cval */
+               return (struct type *)at;
+#undef at
+
+       default:
+               peeksym = o;
+               return(dtype);
+       }
+syntax:
+       decsyn(o);
+       return(NULL);
+}
+
+struct type *getype(dtype, nullok, anonok) struct type *dtype; int *nullok; int anonok; {
+       struct type *t;
+       register int o;
+
+       defsym = 0;
+getp:
+       switch(o=symbol()) {
+
+       case TIMES:
+#define pt (*(struct ptype **)&t)
+               pt = (struct ptype *)Dblock(sizeof(struct ptype));
+               pt->pt_id = PTR;
+               pt->pt_ptotype = dtype;
+               dtype = (struct type *)pt;
+               goto getp;
+#undef pt
+
+       case LPARN:
+               if (!anonok || nextchar()!=')') {
+                       dtype = getype(dtype, nullok, anonok);
+                       if (dtype==NULL)
+                               return(NULL);
+                       if ((o=symbol()) != RPARN)
+                               goto syntax;
+                       goto getf;
+               }
+
+       default:
+               peeksym = o;
+               if (anonok)
+                       goto getf;
+               break;
+
+       case NAME:
+               defsym = csym;
+       getf:
+               return getail(dtype, nullok);
+       }
+syntax:
+       decsyn(o);
+       return(NULL);
 }
 
 /*
@@ -659,8 +871,9 @@ void typov() {
  * Enforce alignment restrictions in structures,
  * including bit-field considerations.
  */
-int align(type, offset, aflen) int type; int offset; int aflen; {
-       register int a, t, flen;
+int align(type, offset, aflen) /*int*/struct type *type; int offset; int aflen; {
+       register int a, /*t,*/ flen;
+ register struct type *t;
        char *ftl;
 
        flen = aflen;
@@ -671,22 +884,24 @@ int align(type, offset, aflen) int type; int offset; int aflen; {
                a += (NBPC+bitoffs-1) / NBPC;
                bitoffs = 0;
        }
-       while ((t&XTYPE)==ARRAY)
-               t = decref0(t);
-       if (t!=CHAR && t!=UNCHAR) {
+ /*    while ((t&XTYPE)==ARRAY)
+               t = decref0(t);*/
+ while (t->t_id == ARRAY)
+  t = ((struct atype *)t)->at_elttype;
+       if (/*t*/t->t_id!=CHAR && /*t*/t->t_id!=UNCHAR) {
                a = (a+ALIGN) & ~ALIGN;
                if (a>offset)
                        bitoffs = 0;
        }
        if (flen) {
-               if (type==INT || type==UNSIGN) {
+               if (/*type*/type->t_id==INT || /*type*/type->t_id==UNSIGN) {
                        if (flen > NBPW)
                                error0(ftl);
                        if (flen+bitoffs > NBPW) {
                                bitoffs = 0;
                                a += NCPW;
                        }
-               } else if (type==CHAR || type==UNCHAR) {
+               } else if (/*type*/type->t_id==CHAR || /*type*/type->t_id==UNCHAR) {
                        if (flen > NBPC)
                                error0(ftl);
                        if (flen+bitoffs > NBPC) {
diff --git a/c04.c b/c04.c
index 9decee6..a26c9d0 100644 (file)
--- a/c04.c
+++ b/c04.c
@@ -197,38 +197,113 @@ void label0(l) int l; {
  * is some kind of pointer; return the size of the object
  * to which the pointer points.
  */
+static int XXXlength(cs) struct node *cs; {
+       register int t, elsz;
+       long n;
+       int nd;
+
+       t = cs->n_type;
+       n = 1;
+       nd = 0;
+       while ((t&XTYPE) == ARRAY) {
+               t = decref0(t);
+               n *= cs->n_subsp[nd++];
+       }
+       if ((t&~TYPE)==FUNC)
+               return(0);
+       if (t>=PTR)
+               elsz = SZPTR;
+       else switch(t&TYPE) {
+
+       case VOID:
+               error0("Illegal use of void object");
+               return(2);
+
+       case INT:
+       case UNSIGN:
+               elsz = SZINT;
+               break;
+
+       case CHAR:
+       case UNCHAR:
+               elsz = 1;
+               break;
+
+       case FLOAT:
+               elsz = SZFLOAT;
+               break;
+
+       case UNLONG:
+       case LONG:
+               elsz = SZLONG;
+               break;
+
+       case DOUBLE:
+               elsz = SZDOUB;
+               break;
+
+       case STRUCT:
+               if ((elsz = cs->n_strp->S.ssize) == 0)
+                       error0("Undefined structure");
+               break;
+       default:
+               error0("Compiler error0 (length)");
+               return(0);
+       }
+ /*fprintf(stderr, "%d %d %d\n", (int)n, (int)elsz, (int)(n * elsz));*/
+       n *= elsz;
+       if (n >= (_UNSIGNED_INT)50000)
+               werror0("very large data structure");
+       return(n);
+}
 int plength(p) register struct node *p; {
        register int t, l;
 
        if (p==0 || ((t=p->n_type)&~TYPE) == 0)         /* not a reference */
                return(1);
        p->n_type = decref0(t);
-       l = length(p);
+       l = XXXlength(p);
        p->n_type = t;
        return(l);
+ /*switch (p->t_id) {
+ case PTR:
+  return length(((struct ptype *)p)->pt_ptotype);
+ case FUNC:
+  return length(((struct ftype *)p)->ft_rettype);
+ case ARRAY:
+  return length(((struct atype *)p)->at_elttype);
+ }
+ return 1;*/
 }
 
 /*
  * return the number of bytes in the object
  * whose tree node is acs.
  */
-int length(cs) struct node *cs; {
-       register int t, elsz;
+int length(cs) struct /*node*/type *cs; {
+       register int /*t,*/ elsz;
+ register struct type *t;
        long n;
-       int nd;
+ /*    int nd;*/
 
      t = cs->n_type;
/*    t = cs->n_type;
        n = 1;
        nd = 0;
        while ((t&XTYPE) == ARRAY) {
                t = decref0(t);
                n *= cs->n_subsp[nd++];
-       }
-       if ((t&~TYPE)==FUNC)
+       }*/
+ n = 1;
+ for (t = cs; t->t_id == ARRAY; t = ((struct atype *)t)->at_elttype)
+  n *= ((struct atype *)t)->at_nelt;
+       if (/*(t&~TYPE)*/t->t_id==FUNC)
                return(0);
      if (t>=PTR)
/*    if (t>=PTR)
                elsz = SZPTR;
-       else switch(t&TYPE) {
+       else*/ switch(/*t&TYPE*/t->t_id) {
+ case PTR:
+  elsz = SZPTR;
+  break;
 
        case VOID:
                error0("Illegal use of void object");
@@ -258,13 +333,14 @@ int length(cs) struct node *cs; {
                break;
 
        case STRUCT:
-               if ((elsz = cs->n_strp->S.ssize) == 0)
+               if ((elsz = /*cs->n_strp->S.ssize*/((struct stype *)t)->st_ssize) == 0)
                        error0("Undefined structure");
                break;
        default:
-               error0("Compiler error0 (length)");
+               error0("Compiler error (length)");
                return(0);
        }
+ /*fprintf(stderr, "%d %d %d\n", (int)n, (int)elsz, (int)(n * elsz));*/
        n *= elsz;
        if (n >= (_UNSIGNED_INT)50000)
                werror0("very large data structure");
@@ -274,7 +350,7 @@ int length(cs) struct node *cs; {
 /*
  * The number of bytes in an object, rounded up to a word.
  */
-int rlength(cs) struct node *cs; {
+int rlength(cs) struct /*node*/type *cs; {
        return((length(cs)+ALIGN) & ~ALIGN);
 }
 
diff --git a/ccom.h b/ccom.h
index 1cc3c98..393b73f 100644 (file)
--- a/ccom.h
+++ b/ccom.h
@@ -32,9 +32,12 @@ struct nmlist {
  /* nl_type, nl_subsp fields, because of length(), rlength() computations */
        char    nl_class;               /* storage class */
        char    nl_flag;                /* various flags */
+ /* note: these will be phased out in favour of nl_dtype: */
        int     nl_type;                /* type */
        int     *nl_subsp;              /* subscript list */
        union   str *nl_strp;           /* structure description */
+ /* to here */
+       struct  type *nl_dtype;         /* detailed type */
        int     nl_offset;              /* post-allocation location */
        struct  nmlist *nl_nextnm;      /* next name in chain */
        union   str *nl_sparent;        /* Structure of which this is member */
@@ -69,14 +72,63 @@ struct      tdim {
        int     dimens[5];
 };
 
+/*
+ * tree nodes for detailed type descriptions, t_id can be:
+ *   INT       0
+ *   CHAR      1
+ *   FLOAT     2
+ *   DOUBLE    3
+ *   STRUCT    4       (means it's a struct stype)
+ *   RSTRUCT   5       (not sure what this is; pass 1 only)
+ *   LONG      6
+ *   UNSIGN    7
+ *   UNION     8       (adjusted later to struct; pass 0 only)
+ *   UNCHAR    8
+ *   UNLONG    9
+ *   VOID      10
+ *   PTR       020     (means it's a struct ptype)
+ *   FUNC      040     (means it's a struct ftype)
+ *   ARRAY     060     (means it's a struct atype)
+ */
+struct type {
+       int     t_id;
+};
+struct stype {
+       struct type st_type;
+#define st_id st_type.t_id
+       struct SS st_S;
+#define st_ssize st_S.ssize
+#define st_memlist st_S.memlist
+};
+struct ptype {
+       struct type pt_type;
+#define pt_id pt_type.t_id
+       struct type *pt_ptotype;        /* pointed-to type */
+};
+struct ftype {
+       struct type ft_type;
+#define ft_id ft_type.t_id
+       struct type *ft_rettype;        /* return type */
+       struct nmlist **ft_arglist;     /* argument list */
+};
+struct atype {
+       struct type at_type;
+#define at_id at_type.t_id
+       int     at_nelt;                /* number of elements */
+       struct type *at_elttype;        /* element type */
+};
+
 /*
  *  Tree node for unary and binary
  */
 struct node {
        int     n_op;
+ /* note: these will be phased out in favour of n_dtype: */
        int     n_type;
        int     *n_subsp;       /* subscript list for arrays; pass 0 only */
        union   str *n_strp;    /* structure descr for structs; pass 0 only */
+ /* to here */
+       struct  type *n_dtype;          /* detailed type */
 };
 
 struct tnode {
@@ -85,6 +137,7 @@ struct       tnode {
 #define tn_type tn_node.n_type
 #define tn_subsp tn_node.n_subsp
 #define tn_strp tn_node.n_strp
+#define tn_dtype tn_node.n_dtype
        struct  node *tn_tr1;
        struct  node *tn_tr2;
        int     tn_degree;              /* pass 1 only */
@@ -99,6 +152,7 @@ struct       nnode {
 #define nn_type nn_node.n_type
 #define nn_subsp nn_node.n_subsp
 #define nn_strp nn_node.n_strp
+#define nn_dtype nn_node.n_dtype
        struct  nmlist *nn_nmlist;      /* pass 0 only */
        char    nn_class;               /* pass 1 only */
        char    nn_regno;               /* pass 1 only */
@@ -120,6 +174,7 @@ struct      locnnode {
 #define locnn_type locnn_nnode.nn_type
 #define locnn_subsp locnn_nnode.nn_subsp
 #define locnn_strp locnn_nnode.nn_strp
+#define locnn_dtype locnn_nnode.nn_dtype
 #define locnn_nmlist locnn_nnode.nn_nmlist
 #define locnn_class locnn_nnode.nn_class
 #define locnn_regno locnn_nnode.nn_regno
@@ -140,6 +195,7 @@ struct      extnnode {
 #define extnn_type extnn_nnode.nn_type
 #define extnn_subsp extnn_nnode.nn_subsp
 #define extnn_strp extnn_nnode.nn_strp
+#define extnn_dtype extnn_nnode.nn_dtype
 #define extnn_nmlist extnn_nnode.nn_nmlist
 #define extnn_class extnn_nnode.nn_class
 #define extnn_regno extnn_nnode.nn_regno
@@ -156,6 +212,7 @@ struct      cnode {
 #define cn_type cn_node.n_type
 #define cn_subsp cn_node.n_subsp
 #define cn_strp cn_node.n_strp
+#define cn_dtype cn_node.n_dtype
        _INT    cn_value;
 };
 
@@ -168,6 +225,7 @@ struct      lnode {
 #define ln_type ln_node.n_type
 #define ln_subsp ln_node.n_subsp
 #define ln_strp ln_node.n_strp
+#define ln_dtype ln_node.n_dtype
        _LONG   ln_lvalue;
 };
 
@@ -180,6 +238,7 @@ struct      fnode {
 #define fn_type fn_cnode.cn_type
 #define fn_subsp fn_cnode.cn_subsp
 #define fn_strp fn_cnode.cn_strp
+#define fn_dtype fn_cnode.cn_dtype
 #define fn_value fn_cnode.cn_value
        _DOUBLE fn_fvalue;
 };
@@ -193,6 +252,7 @@ struct      fasgn {
 #define fa_type fa_tnode.tn_type
 #define fa_subsp fa_tnode.tn_subsp
 #define fa_strp fa_tnode.tn_strp
+#define fa_dtype fa_tnode.tn_dtype
 #define fa_tr1 fa_tnode.tn_tr1
 #define fa_tr2 fa_tnode.tn_tr2
 #define fa_degree fa_tnode.tn_degree
@@ -393,10 +453,10 @@ struct swtab {
 #define        RSTRUCT 5               /* pass 1 only */
 #define        LONG    6
 #define        UNSIGN  7
+#define        UNION   8               /* adjusted later to struct; pass 0 only */
 #define        UNCHAR  8
 #define        UNLONG  9
 #define        VOID    10
-#define        UNION   8               /* adjusted later to struct; pass 0 only */
 
 #define        ALIGN   01              /* pass 0 only */
 #define        TYPE    017
diff --git a/test/arr0.c b/test/arr0.c
new file mode 100644 (file)
index 0000000..6974cd8
--- /dev/null
@@ -0,0 +1,4 @@
+int main() {
+ int a[5][10], i=2, j=3;
+ return a[i][j];
+}
diff --git a/test/arr0.dump b/test/arr0.dump
new file mode 100644 (file)
index 0000000..5858d6a
--- /dev/null
@@ -0,0 +1,41 @@
+SYMDEF main
+PROG
+RLABEL main
+SAVE
+SETREG 5
+BRANCH 1
+LABEL 2
+ANAME a -108
+NAME AUTO INT -110
+CON INT 2
+ASSIGN INT
+EXPR 2
+ANAME i -110
+NAME AUTO INT -112
+CON INT 3
+ASSIGN INT
+EXPR 2
+ANAME j -112
+NAME AUTO INT -108
+AMPER PTR,INT
+NAME AUTO INT -110
+CON INT 20
+ITOP PTR,ARRAY,INT
+PLUS PTR,INT
+STAR INT
+AMPER PTR,INT
+NAME AUTO INT -112
+CON INT 2
+ITOP PTR,INT
+PLUS PTR,INT
+STAR INT
+RFORCE INT
+EXPR 3
+BRANCH 3
+LABEL 3
+RETRN
+LABEL 1
+SETSTK 104
+BRANCH 2
+EOFC
+*EOFC
diff --git a/test/arr0.s b/test/arr0.s
new file mode 100644 (file)
index 0000000..3151cee
--- /dev/null
@@ -0,0 +1,24 @@
+.globl _main
+.text
+_main:
+~~main:
+jsr    r5,csv
+jbr    L1
+L2:~a=177624
+mov    $2,-156(r5)
+~i=177622
+mov    $3,-160(r5)
+~j=177620
+mov    -156(r5),r1
+mul    $12,r1
+add    -160(r5),r1
+asl    r1
+add    r5,r1
+mov    -154(r1),r1
+mov    r1,r0
+jbr    L3
+L3:jmp cret
+L1:sub $150,sp
+jbr    L2
+.globl
+.data
diff --git a/test/arr1.c b/test/arr1.c
new file mode 100644 (file)
index 0000000..ee666db
--- /dev/null
@@ -0,0 +1,8 @@
+int a[][3] = {
+ {1, 2, 3},
+ {4, 5, 6}
+};
+int main() {
+ int i=1, j=2;
+ return a[i][j];
+}
diff --git a/test/arr1.dump b/test/arr1.dump
new file mode 100644 (file)
index 0000000..dfc933c
--- /dev/null
@@ -0,0 +1,49 @@
+SYMDEF a
+DATA
+NLABEL a
+SINIT 1
+SINIT 2
+SINIT 3
+SINIT 4
+SINIT 5
+SINIT 6
+SYMDEF main
+PROG
+RLABEL main
+SAVE
+SETREG 5
+BRANCH 1
+LABEL 2
+NAME AUTO INT -10
+CON INT 1
+ASSIGN INT
+EXPR 6
+ANAME i -10
+NAME AUTO INT -12
+CON INT 2
+ASSIGN INT
+EXPR 6
+ANAME j -12
+NAME EXTERN INT a
+AMPER PTR,INT
+NAME AUTO INT -10
+CON INT 6
+ITOP PTR,ARRAY,INT
+PLUS PTR,INT
+STAR INT
+AMPER PTR,INT
+NAME AUTO INT -12
+CON INT 2
+ITOP PTR,INT
+PLUS PTR,INT
+STAR INT
+RFORCE INT
+EXPR 7
+BRANCH 3
+LABEL 3
+RETRN
+LABEL 1
+SETSTK 4
+BRANCH 2
+EOFC
+*EOFC
diff --git a/test/arr1.s b/test/arr1.s
new file mode 100644 (file)
index 0000000..33f67a9
--- /dev/null
@@ -0,0 +1,31 @@
+.globl _a
+.data
+_a:
+1
+2
+3
+4
+5
+6
+.globl _main
+.text
+_main:
+~~main:
+jsr    r5,csv
+jbr    L1
+L2:mov $1,-12(r5)
+~i=177766
+mov    $2,-14(r5)
+~j=177764
+mov    -12(r5),r1
+mul    $3,r1
+add    -14(r5),r1
+asl    r1
+mov    _a(r1),r1
+mov    r1,r0
+jbr    L3
+L3:jmp cret
+L1:sub $4,sp
+jbr    L2
+.globl
+.data
diff --git a/test/arr2.c b/test/arr2.c
new file mode 100644 (file)
index 0000000..d5ae1cc
--- /dev/null
@@ -0,0 +1,9 @@
+typedef int t[3];
+t a[] = {
+ {1, 2, 3},
+ {4, 5, 6}
+};
+int main() {
+ int i=1, j=2;
+ return a[i][j];
+}
diff --git a/test/arr2.dump b/test/arr2.dump
new file mode 100644 (file)
index 0000000..73e7d77
--- /dev/null
@@ -0,0 +1,49 @@
+SYMDEF a
+DATA
+NLABEL a
+SINIT 1
+SINIT 2
+SINIT 3
+SINIT 4
+SINIT 5
+SINIT 6
+SYMDEF main
+PROG
+RLABEL main
+SAVE
+SETREG 5
+BRANCH 1
+LABEL 2
+NAME AUTO INT -10
+CON INT 1
+ASSIGN INT
+EXPR 7
+ANAME i -10
+NAME AUTO INT -12
+CON INT 2
+ASSIGN INT
+EXPR 7
+ANAME j -12
+NAME EXTERN INT a
+AMPER PTR,INT
+NAME AUTO INT -10
+CON INT 6
+ITOP PTR,ARRAY,INT
+PLUS PTR,INT
+STAR INT
+AMPER PTR,INT
+NAME AUTO INT -12
+CON INT 2
+ITOP PTR,INT
+PLUS PTR,INT
+STAR INT
+RFORCE INT
+EXPR 8
+BRANCH 3
+LABEL 3
+RETRN
+LABEL 1
+SETSTK 4
+BRANCH 2
+EOFC
+*EOFC
diff --git a/test/arr2.s b/test/arr2.s
new file mode 100644 (file)
index 0000000..33f67a9
--- /dev/null
@@ -0,0 +1,31 @@
+.globl _a
+.data
+_a:
+1
+2
+3
+4
+5
+6
+.globl _main
+.text
+_main:
+~~main:
+jsr    r5,csv
+jbr    L1
+L2:mov $1,-12(r5)
+~i=177766
+mov    $2,-14(r5)
+~j=177764
+mov    -12(r5),r1
+mul    $3,r1
+add    -14(r5),r1
+asl    r1
+mov    _a(r1),r1
+mov    r1,r0
+jbr    L3
+L3:jmp cret
+L1:sub $4,sp
+jbr    L2
+.globl
+.data