Add tests, fixes for tests, reinstate and type-convert stuff marked "bitrot"
[ccom.git] / c02.c
diff --git a/c02.c b/c02.c
index 6104c06..cfe89a6 100644 (file)
--- a/c02.c
+++ b/c02.c
@@ -4,25 +4,30 @@
 
 #include <string.h>
 #include "c0.h"
-
+#include "c1.h" /* pswitch0() one-pass version */
 /*
  * Process a single external definition
  */
 void extdef() {
        register int o;
        int sclass, scflag;
-       struct nmlist typer;
+ /*    struct nmlist typer;*/
+ struct type *dtype;
+ static struct type t_int = {INT};
        register struct nmlist *ds;
+ struct tdim dim;
+ int a;
 
        if(((o=symbol())==EOFC) || o==SEMI)
                return;
        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;
+ dtype = &t_int;
        }
        scflag = 0;
        if (sclass==DEFXTRN) {
@@ -36,20 +41,26 @@ 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->htype&XTYPE)==FUNC) {
+               if (/*(ds->nl_type&XTYPE)==FUNC*/ds->nl_dtype->t_id==(REF|FUNC)) {
                        if ((peeksym=symbol())==LBRACE || peeksym==KEYW
-                        || (peeksym==NAME && csym->hclass==TYPEDEF)) {
-                               funcblk0.type = decref0(ds->htype);
-                               funcblk0.strp = ds->hstrp;
+                        || (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;*/
+ dim.rank = 0;
+ funcblk.locnn_type = XXXoldtype(((struct ftype *)ds->nl_dtype)->ft_reftype, &dim, (struct SS **)&funcblk.locnn_strp);
+ funcblk.locnn_subsp = dim.rank ? (int *)Tblock(dim.rank*sizeof(dim.rank)) : NULL;
+ for (a=0; a<dim.rank; a++)
+  funcblk.locnn_subsp[a] = dim.dimens[a];
                                setinit(ds);
-                               outcode("BS", SYMDEF, sclass==EXTERN?ds->name:"");
+                               outcode("BS", SYMDEF, sclass==EXTERN?ds->nl_name:"");
                                cfunc();
                                return;
                        }
@@ -57,12 +68,12 @@ void extdef() {
                                error0("Inappropriate parameters");
                } else if ((o=symbol())==COMMA || o==SEMI) {
                        peeksym = o;
-                       o = (length((union tree0 *)ds)+ALIGN) & ~ALIGN;
+                       o = (length(/*(struct node *)ds*/ds->nl_dtype)+ALIGN) & ~ALIGN;
                        if (sclass==STATIC) {
                                setinit(ds);
-                               outcode("BSBBSBN", SYMDEF, "", BSS, NLABEL, ds->name, SSPACE, o);
+                               outcode("BSBBSBN", SYMDEF, "", BSS, NLABEL, ds->nl_name, SSPACE, o);
                        } else if (scflag)
-                               outcode("BSN", CSPACE, ds->name, o);
+                               outcode("BSN", CSPACE, ds->nl_name, o);
                } else {
                        if (o!=ASSIGN) {
                                error0("Declaration syntax");
@@ -70,8 +81,8 @@ void extdef() {
                        }
                        setinit(ds);
                        if (sclass==EXTERN)
-                               outcode("BS", SYMDEF, ds->name);
-                       outcode("BBS", DATA, NLABEL, ds->name);
+                               outcode("BS", SYMDEF, ds->nl_name);
+                       outcode("BBS", DATA, NLABEL, ds->nl_name);
                        if (cinit(ds, 1, sclass) & ALIGN)
                                outcode("B", EVEN);
                }
@@ -98,7 +109,7 @@ void cfunc() {
 
        sloc = isn0;
        isn0 += 2;
-       outcode("BBS", PROG, RLABEL, funcsym->name);
+       outcode("BBS", PROG, RLABEL, funcsym->nl_name);
        regvar = 5;
        autolen = STAUTO;
        maxauto = STAUTO;
@@ -107,7 +118,7 @@ void cfunc() {
        declist(ARG);
        outcode("B", SAVE);
        if (proflg)
-               outcode("BNS", PROFIL, isn0++, funcsym->name);
+               outcode("BNS", PROFIL, isn0++, funcsym->nl_name);
        funchead();
        branch0(sloc);
        label0(sloc+1);
@@ -121,7 +132,7 @@ void cfunc() {
 /* add STAUTO; overlay bug fix, coupled with section in c11.c */
        outcode("BN", SETSTK, -maxauto+STAUTO);
        branch0(sloc+1);
- /*fprintf(stderr, "cb=%p\n", cp0);*/
+ /*fprintf(stderr, "cb=%p\n", cp);*/
        locbase = cb;
 }
 
@@ -131,17 +142,22 @@ void cfunc() {
 int cinit(anp, flex, sclass) struct nmlist *anp; int flex; int sclass; {
        struct nmlist np;
        register int nel, ninit;
-       int width, isarray, o, brace, realtype;
-       union tree0 *s;
+       int width, isarray, o, brace/*, realtype*/;
+ struct type *realtype;
+       struct node *s;
+ struct tdim dim;
+ int type;
+ union str *strp;
+ int *subsp, a;
 
        np = *anp;
-       realtype = np.htype;
+       realtype = /*np.nl_type*/np.nl_dtype;
        isarray = 0;
-       if ((realtype&XTYPE) == ARRAY)
+       if (/*(realtype&XTYPE) == ARRAY*/realtype->t_id == (REF | ARRAY))
                isarray++;
        else
                flex = 0;
-       width = length((union tree0 *)&np);
+       width = length(/*(struct node *)&np*/np.nl_dtype);
        nel = 1;
        /*
         * If it's an array, find the number of elements.
@@ -149,19 +165,20 @@ int cinit(anp, flex, sclass) struct nmlist *anp; int flex; int sclass; {
         * an array of.
         */
        if (sclass==AUTO)
-               if (isarray || realtype==STRUCT)
+               if (isarray || /*realtype*/realtype->t_id==STRUCT)
                        error0("No auto. aggregate initialization");
        if (isarray) {
-               np.htype = decref0(realtype);
-               np.hsubsp++;
+ /*            np.nl_type = decref0(realtype);
+               np.nl_subsp++;*/
+ np.nl_dtype = ((struct atype *)realtype)->at_reftype;
                if (width==0 && flex==0)
-                       error0("0-length row: %s", anp->name);
-               o = length((union tree0 *)&np);
+                       error0("0-length row: %s", anp->nl_name);
+               o = length(/*(struct node *)&np*/np.nl_dtype);
                nel = (unsigned)width/o;
                width = o;
        }
        brace = 0;
-       if ((peeksym=symbol())==LBRACE && (isarray || np.htype!=STRUCT)) {
+       if ((peeksym=symbol())==LBRACE && (isarray || /*np.nl_type*/np.nl_dtype->t_id!=STRUCT)) {
                peeksym = -1;
                brace++;
        }
@@ -170,7 +187,7 @@ int cinit(anp, flex, sclass) struct nmlist *anp; int flex; int sclass; {
                if ((o=symbol())==RBRACE)
                        break;
                peeksym = o;
-               if (o==STRING && (realtype==ARRAY+CHAR || realtype==ARRAY+UNCHAR)) {
+               if (o==STRING && /*(realtype==ARRAY+CHAR || realtype==ARRAY+UNCHAR)*/realtype->t_id == (REF | ARRAY) && (((struct atype *)realtype)->at_reftype->t_id == CHAR || ((struct atype *)realtype)->at_reftype->t_id == UNCHAR)) {
                        if (sclass==AUTO)
                                error0("No strings in automatic");
                        peeksym = -1;
@@ -178,30 +195,37 @@ int cinit(anp, flex, sclass) struct nmlist *anp; int flex; int sclass; {
                        ninit += nchstr;
                        o = symbol();
                        break;
-               } else if (np.htype==STRUCT) {
+               } else if (/*np.nl_type*/np.nl_dtype->t_id==STRUCT) {
                        strinit(&np, sclass);
-               } else if ((np.htype&ARRAY)==ARRAY || peeksym==LBRACE)
+               } else if (/*(np.nl_type&ARRAY)==ARRAY*/np.nl_dtype->t_id==(REF|ARRAY) || peeksym==LBRACE)
                        cinit(&np, 0, sclass);
                else {
                        char *st;
                        initflg++;
                        st = starttree();
-                       s = tree0(0);
+                       s = tree(/*0*/);
                        initflg = 0;
-                       if (np.hflag&FFIELD)
+                       if (np./*nl_flag&FFIELD*/nl_dtype->t_id==BITFLD)
                                error0("No field initialization");
-                       *cp0++ = nblock(&np);
-                       *cp0++ = s;
+                       *cp++ = (struct node *)nblock(&np);
+                       *cp++ = s;
                        build(ASSIGN);
                        if (sclass==AUTO||sclass==REG)
-                               rcexpr0(*--cp0);
+                               rcexpr0(*--cp);
                        else if (sclass==ENUMCON) {
-                               if (s->t.op!=CON)
-                                       error0("Illegal enum constant for %s", anp->name);
-                               anp->hoffset = s->c.value;
+                               if (s->n_op!=CON)
+                                       error0("Illegal enum constant for %s", anp->nl_name);
+                               anp->nl_offset = ((struct cnode *)s)->cn_value;
                        } else
-                               rcexpr0(block(INIT,np.htype,(int *)NULL,
-                                 (union str *)NULL, (*--cp0)->t.tr2, TNULL0));
+ {
+  dim.rank = 0;
+  type = XXXoldtype(np.nl_dtype, &dim, (struct SS **)&strp);
+  subsp = dim.rank ? (int *)Tblock(dim.rank*sizeof(dim.rank)) : NULL;
+  for (a=0; a<dim.rank; a++)
+   subsp[a] = dim.dimens[a];
+                               rcexpr0((struct node *)block(INIT,/*np.nl_type*/type,/*(int *)NULL*/subsp,
+                                 /*(union str *)NULL*/strp, ((struct tnode *)(*--cp))->tn_tr2, (struct node *)NULL));
+ }
                        endtree(st);
                }
                ninit++;
@@ -220,9 +244,17 @@ int cinit(anp, flex, sclass) struct nmlist *anp; int flex; int sclass; {
                outcode("BN", SSPACE, (nel-ninit)*width);
        else if (ninit>nel) {
                if (flex && nel==0) {
-                       np.hsubsp[-1] = ninit;
+ /* note: nel==0 implies isarray, since otherwise nel must be 1 */
+ /*                    np.nl_subsp[-1] = ninit;*/
+#define arealtype (*(struct atype **)&realtype)
+ arealtype = (struct atype *)Dblock(sizeof(struct atype));
+ arealtype->at_id = REF | ARRAY;
+ arealtype->at_reftype = np.nl_dtype;
+ arealtype->at_nelt = ninit;
+ anp->nl_dtype = (struct type *)arealtype;
+#undef arealtype
                } else
-                       error0("Too many initializers: %s", anp->name);
+                       error0("Too many initializers: %s", anp->nl_name);
                nel = ninit;
        }
        return(nel*width);
@@ -232,12 +264,13 @@ int cinit(anp, flex, sclass) struct nmlist *anp; int flex; int sclass; {
  * Initialize a structure
  */
 void strinit(np, sclass) struct nmlist *np; int sclass; {
-       static struct nmlist junk;
+ /*    static*/ struct nmlist junk;
+ static struct type t_int = {INT};
        register struct nmlist **mlp;
        static struct nmlist *zerloc = NULL;
        register int o, brace;
 
-       if ((mlp = np->hstrp->S.memlist)==NULL) {
+       if ((mlp = /*np->nl_strp->S.memlist*/((struct stype *)np->nl_dtype)->st_memlist)==NULL) {
                mlp = &zerloc;
                error0("Undefined structure initialization");
        }
@@ -251,6 +284,9 @@ void strinit(np, sclass) struct nmlist *np; int sclass; {
                        break;
                peeksym = o;
                if (*mlp==0) {
+ /* change this to a static struct nmlist later when nmlist has stabilized */
+ bzero(&junk, sizeof(struct nmlist));
+ junk.nl_dtype = &t_int;
                        error0("Too many structure initializers");
                        cinit(&junk, 0, sclass);
                } else
@@ -260,7 +296,7 @@ void strinit(np, sclass) struct nmlist *np; int sclass; {
                        mlp++;
                }
                                /* DAG -- union initialization bug fix */
-               if (*mlp && mlp[-1]->hoffset == (*mlp)->hoffset) {
+               if (*mlp && mlp[-1]->nl_offset == (*mlp)->nl_offset) {
                        werror0("union initialization non-portable");
                        while (*mlp)    /* will NOT be &structhole */
                                mlp++;  /* skip other members of union */
@@ -268,7 +304,7 @@ void strinit(np, sclass) struct nmlist *np; int sclass; {
        } while ((o=symbol())==COMMA && (*mlp || brace));
        if (sclass!=AUTO && sclass!=REG) {
                if (*mlp)
-                       outcode("BN", SSPACE, np->hstrp->S.ssize - (*mlp)->hoffset);
+                       outcode("BN", SSPACE, /*np->nl_strp->S.ssize*/((struct stype *)np->nl_dtype)->st_ssize - (*mlp)->nl_offset);
                outcode("B", EVEN);
        }
        if (o!=RBRACE || brace==0)
@@ -280,14 +316,15 @@ void strinit(np, sclass) struct nmlist *np; int sclass; {
  */
 void setinit(np) register struct nmlist *np; {
 
-       if (np->hflag&FINIT)
-               error0("%s multiply defined", np->name);
-       np->hflag |= FINIT;
+       if (np->nl_flag&FINIT)
+               error0("%s multiply defined", np->nl_name);
+       np->nl_flag |= FINIT;
 }
 
 /*
  * Process one statement in a function.
  */
+struct type gototype = {0}; /* dummy type distinguished by its address */
 void statement() {
        register int o, o1;
        int sauto, sreg;
@@ -351,9 +388,10 @@ stmt:
 
                case IF: {
                        register int o2;
-                       register union tree0 *np;
+                       register struct node *np;
 
-                       np = pexpr(1);
+ char *st = starttree();
+                       np = pexpr(/*1*/);
                        o2 = 0;
                        if ((o1=symbol())==KEYW) switch (cval) {
                        case GOTO:
@@ -385,6 +423,7 @@ stmt:
                                chconbrk(o2);
                                cbranch0(np, o2, 1);
                        hardif:
+ endtree(st);
                                if ((o=symbol())!=SEMI)
                                        goto syntax;
                                if ((o1=symbol())==KEYW && cval==ELSE) 
@@ -394,6 +433,7 @@ stmt:
                        }
                        peeksym = o1;
                        cbranch0(np, o1=isn0++, 0);
+ endtree(st);
                        statement();
                        if ((o=symbol())==KEYW && cval==ELSE) {
                                o2 = isn0++;
@@ -409,11 +449,14 @@ stmt:
                }
 
                case WHILE: {
+ char *st;
                        register int o2;
                        o1 = contlab;
                        o2 = brklab;
                        label0(contlab = isn0++);
-                       cbranch0(pexpr(1), brklab=isn0++, 0);
+ st = starttree();
+                       cbranch0(pexpr(/*1*/), brklab=isn0++, 0);
+ endtree(st);
                        statement();
                        branch0(contlab);
                        label0(brklab);
@@ -443,7 +486,9 @@ stmt:
                        label0(contlab);
                        contlab = o1;
                        if ((o=symbol())==KEYW && cval==WHILE) {
-                               cbranch0(tree0(1), o3, 1);
+ char *st = starttree();
+                               cbranch0(tree(/*1*/), o3, 1);
+ endtree(st);
                                label0(brklab);
                                brklab = o2;
                                goto semi;
@@ -469,15 +514,15 @@ stmt:
                        goto stmt;
 
                case SWITCH: {
-                       register union tree0 *np;
+                       register struct node *np;
                        register char *st;
 
                        o1 = brklab;
                        brklab = isn0++;
                        st = starttree();
-                       np = pexpr(0);
+                       np = pexpr(/*0*/);
                        chkw(np, -1);
-                       rcexpr0(block(RFORCE,0,(int *)NULL,(union str *)NULL,np,TNULL0));
+                       rcexpr0((struct node *)block(RFORCE,0,(int *)NULL,(union str *)NULL,np,(struct node *)NULL));
                        endtree(st);
                        pswitch0();
                        brklab = o1;
@@ -520,28 +565,33 @@ stmt:
                if (nextchar()==':') {
                        peekc = 0;
                        np = csym;
-                       if (np->hclass>0) {
-                               if (np->hblklev==0) {
+                       if (np->nl_class>0) {
+                               if (np->nl_blklev==0) {
                                        np = pushdecl(np);
-                                       np->hoffset = 0;
+                                       np->nl_offset = 0;
                                } else {
                                        defsym = np;
                                        redec();
                                        goto stmt;
                                }
                        }
-                       np->hclass = STATIC;
-                       np->htype = ARRAY;
-                       np->hflag |= FLABL;
-                       if (np->hoffset==0)
-                               np->hoffset = isn0++;
-                       label0(np->hoffset);
+                       np->nl_class = STATIC;
+ /*                    np->nl_type = ARRAY;*/
+ np->nl_dtype = &gototype;
+                       np->nl_flag |= FLABL;
+                       if (np->nl_offset==0)
+                               np->nl_offset = isn0++;
+                       label0(np->nl_offset);
                        goto stmt;
                }
        }
        }
        peeksym = o;
-       rcexpr0(tree0(1));
+ {
+  char *st = starttree();
+       rcexpr0(tree(/*1*/));
+  endtree(st);
+ }
 
 semi:
        if ((o=symbol())==SEMI)
@@ -556,17 +606,21 @@ syntax:
  */
 int forstmt() {
        register int o;
-       register union tree0 *st;
+       register struct node *st;
        register int l;
        char *ss;
 
        if ((o=symbol()) != LPARN)
                return(o);
+ ss = starttree();
        if ((o=symbol()) != SEMI) {             /* init part */
                peeksym = o;
-               rcexpr0(tree0(1));
+               rcexpr0(tree(/*1*/));
                if ((o=symbol()) != SEMI)
+ {
+  endtree(ss);
                        return(o);
+ }
        }
        l = isn0;
        isn0 += 3;
@@ -577,8 +631,8 @@ int forstmt() {
        st = NULL;
        if ((o=symbol()) != SEMI) {             /* test part */
                peeksym = o;
-               ss = starttree();
-               st = tree0(0);
+ /*            ss = starttree();*/
+               st = tree(0);
                if ((o=symbol()) != SEMI) {
                        endtree(ss);
                        return(o);
@@ -586,9 +640,9 @@ int forstmt() {
        }
        if ((o=symbol()) != RPARN) {    /* incr part */
                peeksym = o;
-               rcexpr0(tree0(1));
+               rcexpr0(tree(/*1*/));
                if ((o=symbol()) != RPARN) {
-                       if (st)
+ /*                    if (st)*/
                                endtree(ss);
                        return(o);
                }
@@ -596,9 +650,10 @@ int forstmt() {
        label0(l+0);
        if (st) {
                cbranch0(st, l+1, 1);
-               endtree(ss);
+ /*            endtree(ss);*/
        } else
                branch0(l+1);
+ endtree(ss);
        branch0(brklab);
        label0(l+2);
        statement();
@@ -611,16 +666,16 @@ int forstmt() {
  * A parenthesized expression,
  * as after "if".
  */
-union tree0 *pexpr(eflag) int eflag; {
+struct node *pexpr(/*eflag*/) /*int eflag;*/ {
        register int o;
-       register union tree0 *t;
+       register struct node *t;
 
        if ((o=symbol())!=LPARN)
                goto syntax;
-       t = tree0(eflag);
+       t = tree(/*eflag*/);
        if ((o=symbol())!=RPARN)
                goto syntax;
-       if (t->t.type==VOID)
+       if (t->n_type==VOID)
                error0("Illegal use of void");
        return(t);
 syntax:
@@ -636,6 +691,9 @@ syntax:
 void pswitch0() {
        register struct swtab *cswp, *sswp;
        int dl, swlab;
+#if 1 /* one-pass version */
+       char *svtree;
+#endif
 
        cswp = sswp = swp;
        if (swp==0)
@@ -648,10 +706,16 @@ void pswitch0() {
        label0(swlab);
        if (deflab==0)
                deflab = brklab;
+#if 1 /* one-pass version */
+       svtree = starttree();
+       pswitch1(cswp, swp, deflab);
+       endtree(svtree);
+#else
        outcode("BNN", SWIT, deflab, line);
        for (; cswp < swp; cswp++)
                outcode("NN", cswp->swlab, cswp->swval);
        outcode("0");
+#endif
        label0(brklab);
        deflab = dl;
        swp = sswp;
@@ -667,46 +731,76 @@ void pswitch0() {
 /*
  * Structure resembling a block for a register variable.
  */
-struct nmlist  hreg    = { REG, 0, 0, NULL, NULL, 0 };
-struct tnode0  areg    = { NAME, 0, NULL, NULL, (union tree0 *)&hreg};
+struct nmlist  hreg    = { REG, 0, /*0, (int *)NULL, (union str *)NULL,*/ (struct type *)NULL, 0/*nl_offset*/ }; /* note: remaining fields not initialized */
+struct locnnode areg   = { { { NAME, 0, (int *)NULL, (union str *)NULL }, &hreg/*nn_nmlist*/, REG/*nn_class*/, 0/*nn_regno*/, 0/*nn_offset*/}, 0/*locnn_nloc*/ };
 void funchead() {
        register int pl;
        register struct nmlist *cs;
        register char *st;
+ static struct type t_double = {DOUBLE};
+ struct tdim dim;
+ int a;
 
        pl = STARG;
        while(paraml) {
-               parame->sparent = NULL;
+               parame->nl_sparent = NULL;
                cs = paraml;
-               paraml = &paraml->sparent->P;
-               if (cs->htype==FLOAT)
-                       cs->htype = DOUBLE;
-               cs->hoffset = pl;
-               if ((cs->htype&XTYPE) == ARRAY) {
-                       cs->htype -= (ARRAY-PTR);       /* set ptr */
-                       cs->hsubsp++;           /* pop dims */
+               paraml = &paraml->nl_sparent->P;
+               if (cs->/*nl_type*/nl_dtype->t_id==FLOAT)
+                       cs->/*nl_type*/nl_dtype = /*DOUBLE*/&t_double;
+               cs->nl_offset = pl;
+               if (/*(cs->nl_type&XTYPE) == ARRAY*/cs->nl_dtype->t_id == (REF | ARRAY)) {
+/*                     cs->nl_type -= (ARRAY-PTR);     *//* set ptr *//*
+                       cs->nl_subsp++;*/               /* pop dims */
+ struct rtype *rt = (struct rtype *)Dblock(sizeof(struct rtype));
+ rt->rt_id = REF | PTR;
+ rt->rt_reftype = ((struct rtype *)cs->nl_dtype)->rt_reftype;
+ cs->nl_dtype = (struct type *)rt;
                }
-               pl += rlength((union tree0 *)cs);
-               if (cs->hclass==AREG && (hreg.hoffset=goodreg(cs))>=0) {
+               pl += rlength(/*(struct node *)cs*/cs->nl_dtype);
+               if (cs->nl_class==AREG && (hreg.nl_offset=goodreg(cs))>=0) {
+ /* make hreg = *cs but in the chosen register */
+ /*hreg.nl_type = cs->nl_type;
+ hreg.nl_subsp = cs->nl_subsp;
+ hreg.nl_strp = cs->nl_strp;*/
+ hreg.nl_dtype = cs->nl_dtype;
                        st = starttree();
-                       *cp0++ = (union tree0 *)&areg;
-                       *cp0++ = nblock(cs);
-                       areg.type = cs->htype;
-                       areg.strp = cs->hstrp;
-                       cs->hclass = AUTO;
+ /* make areg look like result of nblock(&hreg) */
+ areg.locnn_nloc = hreg.nl_offset;
+ /*areg.locnn_op = NAME;
+ areg.locnn_type = hreg.nl_type;
+ areg.locnn_subsp = hreg.nl_subsp;
+ areg.nocnn_strp = hreg.nl_strp;*/
+ dim.rank = 0;
+ areg.locnn_type = XXXoldtype(cs->nl_dtype, &dim, (struct SS **)&areg.locnn_strp);
+ areg.locnn_subsp = dim.rank ? (int *)Tblock(dim.rank*sizeof(dim.rank)) : NULL;
+ for (a=0; a<dim.rank; a++)
+  areg.locnn_subsp[a] = dim.dimens[a];
+ /*areg.locnn_nmlist = &hreg;
+ areg.locnn_class = hreg.nl_class==0?STATIC:hreg.nl_class;
+ areg.locnn_regno = 0;
+ areg.locnn_offset = 0;*/
+                       *cp++ = (struct node *)&areg;
+ /* formerly rcexpr0() would have translated struct nmlist * to class, regno, */
+ /* offset, but now this happens in nblock, so we have to set class earlier */
+ cs->nl_class = AUTO;
+                       *cp++ = (struct node *)nblock(cs);
+ /*                    areg.locnn_type = cs->nl_type;
+                       areg.locnn_strp = cs->nl_strp;*/
+ /*                    cs->nl_class = AUTO;*/
                        build(ASSIGN);
-                       rcexpr0(*--cp0);
-                       cs->hoffset = hreg.hoffset;
-                       cs->hclass = REG;
+                       rcexpr0(*--cp);
+                       cs->nl_offset = hreg.nl_offset;
+                       cs->nl_class = REG;
                        endtree(st);
                } else
-                       cs->hclass = AUTO;
+                       cs->nl_class = AUTO;
                prste(cs);
        }
        for (pl=0; pl<HSHSIZ; pl++) {
-               for (cs = hshtab[pl]; cs!=NULL; cs = cs->nextnm) {
-                       if (cs->hclass == ARG || cs->hclass==AREG)
-                               error0("Not an argument: %s", cs->name);
+               for (cs = hshtab[pl]; cs!=NULL; cs = cs->nl_nextnm) {
+                       if (cs->nl_class == ARG || cs->nl_class==AREG)
+                               error0("Not an argument: %s", cs->nl_name);
                }
        }
        outcode("BN", SETREG, regvar);
@@ -736,26 +830,26 @@ void blkend() {
                lcs = &hshtab[i];
                cs = *lcs;
                while (cs) {
-                       if (cs->hblklev > blklev
-                        && (((cs->hflag&FLABL)==0 && cs->hclass!=EXTERN) || blklev<=0)) {
-                               if (cs->hclass==0)
-                                       error0("%s undefined", cs->name);
-                               if (cs->hclass==EXTERN)
+                       if (cs->nl_blklev > blklev
+                        && (((cs->nl_flag&FLABL)==0 && cs->nl_class!=EXTERN) || blklev<=0)) {
+                               if (cs->nl_class==0)
+                                       error0("%s undefined", cs->nl_name);
+                               if (cs->nl_class==EXTERN)
                                        nameconflict(hshtab[i], cs);
-                               *lcs = cs->nextnm;
+                               *lcs = cs->nl_nextnm;
                        } else
-                               lcs = &cs->nextnm;
-                       cs = cs->nextnm;
+                               lcs = &cs->nl_nextnm;
+                       cs = cs->nl_nextnm;
                }
        }
 }
 
 void nameconflict(ocs, cs) register struct nmlist *ocs; register struct nmlist *cs; {
 
-       for (; ocs!=NULL; ocs = ocs->nextnm) 
-               if (ocs!=cs && ocs->hclass==EXTERN && 
-                   strncmp(cs->name, ocs->name, MAXCPS-1) == 0)
-                       error0("names %s and %s conflict", cs->name, ocs->name);
+       for (; ocs!=NULL; ocs = ocs->nl_nextnm) 
+               if (ocs!=cs && ocs->nl_class==EXTERN && 
+                   strncmp(cs->nl_name, ocs->nl_name, MAXCPS-1) == 0)
+                       error0("names %s and %s conflict", cs->nl_name, ocs->nl_name);
 }
 
 /*
@@ -766,7 +860,7 @@ void nameconflict(ocs, cs) register struct nmlist *ocs; register struct nmlist *
 void prste(cs) struct nmlist *cs; {
        register int nkind;
 
-       switch (cs->hclass) {
+       switch (cs->nl_class) {
        case REG:
                nkind = RNAME;
                break;
@@ -783,11 +877,11 @@ void prste(cs) struct nmlist *cs; {
                return;
 
        }
-       outcode("BSN", nkind, cs->name, cs->hoffset);
+       outcode("BSN", nkind, cs->nl_name, cs->nl_offset);
 }
 
 /*
- * In case of error0, skip to the next
+ * In case of error, skip to the next
  * statement delimiter.
  */
 void errflush(ao) int ao; {