(ucell) lval2.constval)
(ucell) lval2.constval))
hier1(value * lval1){   int                 lvalue, index, tok, symtok;   cell                val, cidx;   value               lval2 = { 0 };   char               *st;   char                close;   symbol             *sym;   lvalue = primary(lval1);   symtok = tokeninfo(&val, &st);	/* get token read by primary() */ restart:   sym = lval1->sym;   if (matchtoken('[') || matchtoken('{') || matchtoken('('))     {	tok = tokeninfo(&val, &st);	/* get token read by matchtoken() */	if (sym == NULL && symtok != tSYMBOL)	  {	     /* we do not have a valid symbol and we appear not to have read a valid	      * symbol name (so it is unlikely that we would have read a name of an	      * undefined symbol) */	     error(29);		/* expression error, assumed 0 */	     lexpush();		/* analyse '(', '{' or '[' again later */	     return FALSE;	  }			/* if */	if (tok == '[' || tok == '{')	  {			/* subscript */	     close = (char)((tok == '[') ? ']' : '}');	     if (sym == NULL)	       {		/* sym==NULL if lval is a constant or a literal */		  error(28);	/* cannot subscript */		  needtoken(close);		  return FALSE;	       }	     else if (sym->ident != iARRAY && sym->ident != iREFARRAY)	       {		  error(28);	/* cannot subscript, variable is not an array */		  needtoken(close);		  return FALSE;	       }	     else if (sym->dim.array.level > 0 && close != ']')	       {		  error(51);	/* invalid subscript, must use [ ] */		  needtoken(close);		  return FALSE;	       }		/* if */	     stgget(&index, &cidx);	/* mark position in code generator */	     push1();		/* save base address of the array */	     if (hier14(&lval2))	/* create expression for the array index */		rvalue(&lval2);	     if (lval2.ident == iARRAY || lval2.ident == iREFARRAY)		error(33, lval2.sym->name);	/* array must be indexed */	     needtoken(close);	     if (!matchtag(sym->x.idxtag, lval2.tag, TRUE))		error(213);	     if (lval2.ident == iCONSTEXPR)	       {		/* constant expression */		  stgdel(index, cidx);	/* scratch generated code */		  if (lval1->arrayidx != NULL)		    {		/* keep constant index, for checking */		       assert(sym->dim.array.level >= 0			      && sym->dim.array.level < sDIMEN_MAX);		       lval1->arrayidx[sym->dim.array.level] = lval2.constval;		    }		/* if */		  if (close == ']')		    {		       /* normal array index */		       if (lval2.constval < 0 || sym->dim.array.length != 0			   && sym->dim.array.length <= lval2.constval)			  error(32, sym->name);	/* array index out of bounds */		       if (lval2.constval != 0)			 {			    /* don't add offsets for zero subscripts */#if defined(BIT16)			    const2(lval2.constval << 1);#else			    const2(lval2.constval << 2);#endif			    ob_add();			 }	/* if */		    }		  else		    {		       /* character index */		       if (lval2.constval < 0 || sym->dim.array.length != 0			   && sym->dim.array.length * ((8 * sizeof(cell)) /						       charbits) <=			   (ucell) lval2.constval)			  error(32, sym->name);	/* array index out of bounds */		       if (lval2.constval != 0)			 {			    /* don't add offsets for zero subscripts */			    if (charbits == 16)			       const2(lval2.constval << 1);	/* 16-bit character */			    else			       const2(lval2.constval);	/* 8-bit character */			    ob_add();			 }	/* if */		       charalign();	/* align character index into array */		    }		/* if */	       }	     else	       {		  /* array index is not constant */		  lval1->arrayidx = NULL;	/* reset, so won't be checked */		  if (close == ']')		    {		       if (sym->dim.array.length != 0)			  ffbounds(sym->dim.array.length - 1);	/* run time check for array bounds */		       cell2addr();	/* normal array index */		    }		  else		    {		       if (sym->dim.array.length != 0)			  ffbounds(sym->dim.array.length * (32 / charbits) - 1);		       char2addr();	/* character array index */		    }		/* if */		  pop2();		  ob_add();	/* base address was popped into secondary register */		  if (close != ']')		     charalign();	/* align character index into array */	       }		/* if */	     /* the indexed item may be another array (multi-dimensional arrays) */	     assert(lval1->sym == sym && sym != NULL);	/* should still be set */	     if (sym->dim.array.level > 0)	       {		  assert(close == ']');	/* checked earlier */		  /* read the offset to the subarray and add it to the current address */		  lval1->ident = iARRAYCELL;		  push1();	/* the optimizer makes this to a MOVE.alt */		  rvalue(lval1);		  pop2();		  ob_add();		  /* adjust the "value" structure and find the referenced array */		  lval1->ident = iREFARRAY;		  lval1->sym = finddepend(sym);		  assert(lval1->sym != NULL);		  assert(lval1->sym->dim.array.level ==			 sym->dim.array.level - 1);		  /* try to parse subsequent array indices */		  lvalue = FALSE;	/* for now, a iREFARRAY is no lvalue */		  goto restart;	       }		/* if */	     assert(sym->dim.array.level == 0);	     /* set type to fetch... INDIRECTLY */	     lval1->ident = (char)((close == ']') ? iARRAYCELL : iARRAYCHAR);	     lval1->tag = sym->tag;	     /* a cell in an array is an lvalue, a character in an array is not	      * always a *valid* lvalue */	     return TRUE;	  }	else	  {			/* tok=='(' -> function(...) */	     if (sym == NULL		 || (sym->ident != iFUNCTN && sym->ident != iREFFUNC))	       {		  if (sym == NULL && sc_status == statFIRST)		    {		       /* could be a "use before declaration"; in that case, create a stub		        * function so that the usage can be marked.		        */		       sym = fetchfunc(lastsymbol, 0);		       if (sym != NULL)			  markusage(sym, uREAD);		    }		/* if */		  return error(12);	/* invalid function call */	       }	     else if ((sym->usage & uMISSING) != 0)	       {		  char                symname[2 * sNAMEMAX + 16];	/* allow space for user defined operators */		  funcdisplayname(symname, sym->name);		  error(4, symname);	/* function not defined */	       }		/* if */	     callfunction(sym);	     lval1->ident = iEXPRESSION;	     lval1->constval = 0;	     lval1->tag = sym->tag;	     return FALSE;	/* result of function call is no lvalue */	  }			/* if */     }				/* if */   if (sym != NULL && lval1->ident == iFUNCTN)     {	assert(sym->ident == iFUNCTN);	address(sym);	lval1->sym = NULL;	lval1->ident = iREFFUNC;	/* ??? however... function pointers (or function references are not (yet) allowed */	error(29);		/* expression error, assumed 0 */	return FALSE;     }				/* if */   return lvalue;}