|| exactmatch && lval3.sym->dim.array.length > val)
|| (exactmatch && lval3.sym->dim.array.length > val))
hier14(value * lval1){   int                 lvalue;   value               lval2 = { 0 }, lval3 =   {   0};   void                (*oper) (void);   int                 tok, level, i;   cell                val;   char               *st;   int                 bwcount;   cell                arrayidx1[sDIMEN_MAX], arrayidx2[sDIMEN_MAX];	/* last used array indices */   cell               *org_arrayidx;   bwcount = bitwise_opercount;   bitwise_opercount = 0;   for (i = 0; i < sDIMEN_MAX; i++)      arrayidx1[i] = arrayidx2[i] = 0;   org_arrayidx = lval1->arrayidx;	/* save current pointer, to reset later */   if (lval1->arrayidx == NULL)      lval1->arrayidx = arrayidx1;   lvalue = plnge1(hier13, lval1);   if (lval1->ident != iARRAYCELL && lval1->ident != iARRAYCHAR)      lval1->arrayidx = NULL;   if (lval1->ident == iCONSTEXPR)	/* load constant here */      const1(lval1->constval);   tok = lex(&val, &st);   switch (tok)     {     case taOR:	oper = ob_or;	break;     case taXOR:	oper = ob_xor;	break;     case taAND:	oper = ob_and;	break;     case taADD:	oper = ob_add;	break;     case taSUB:	oper = ob_sub;	break;     case taMULT:	oper = os_mult;	break;     case taDIV:	oper = os_div;	break;     case taMOD:	oper = os_mod;	break;     case taSHRU:	oper = ou_sar;	break;     case taSHR:	oper = os_sar;	break;     case taSHL:	oper = ob_sal;	break;     case '=':			/* simple assignment */	oper = NULL;	if (intest)	   error(211);		/* possibly unintended assignment */	break;     default:	lexpush();	bitwise_opercount = bwcount;	lval1->arrayidx = org_arrayidx;	/* restore array index pointer */	return lvalue;     }				/* switch */   /* if we get here, it was an assignment; first check a few special cases    * and then the general */   if (lval1->ident == iARRAYCHAR)     {	/* special case, assignment to packed character in a cell is permitted */	lvalue = TRUE;     }   else if (lval1->ident == iARRAY || lval1->ident == iREFARRAY)     {	/* array assignment is permitted too (with restrictions) */	if (oper)	   return error(23);	/* array assignment must be simple assigment */	assert(lval1->sym != NULL);	if (array_totalsize(lval1->sym) == 0)	   return error(46, lval1->sym->name);	/* unknown array size */	lvalue = TRUE;     }				/* if */   /* operand on left side of assignment must be lvalue */   if (!lvalue)      return error(22);		/* must be lvalue */   /* may not change "constant" parameters */   assert(lval1->sym != NULL);   if ((lval1->sym->usage & uCONST) != 0)      return error(22);		/* assignment to const argument */   lval3 = *lval1;		/* save symbol to enable storage of expresion result */   lval1->arrayidx = org_arrayidx;	/* restore array index pointer */   if (lval1->ident == iARRAYCELL || lval1->ident == iARRAYCHAR       || lval1->ident == iARRAY || lval1->ident == iREFARRAY)     {	/* if indirect fetch: save PRI (cell address) */	if (oper)	  {	     push1();	     rvalue(lval1);	  }			/* if */	lval2.arrayidx = arrayidx2;	plnge2(oper, hier14, lval1, &lval2);	if (lval2.ident != iARRAYCELL && lval2.ident != iARRAYCHAR)	   lval2.arrayidx = NULL;	if (oper)	   pop2();	if (!oper && lval3.arrayidx != NULL && lval2.arrayidx != NULL	    && lval3.ident == lval2.ident && lval3.sym == lval2.sym)	  {	     int                 same = TRUE;	     assert(lval3.arrayidx == arrayidx1);	     assert(lval2.arrayidx == arrayidx2);	     for (i = 0; i < sDIMEN_MAX; i++)		same = same && (lval3.arrayidx[i] == lval2.arrayidx[i]);	     if (same)		error(226, lval3.sym->name);	/* self-assignment */	  }			/* if */     }   else     {	if (oper)	  {	     rvalue(lval1);	     plnge2(oper, hier14, lval1, &lval2);	  }	else	  {	     /* if direct fetch and simple assignment: no "push"	      * and "pop" needed -> call hier14() directly, */	     if (hier14(&lval2))		rvalue(&lval2);	/* instead of plnge2(). */	     checkfunction(&lval2);	     /* check whether lval2 and lval3 (old lval1) refer to the same variable */	     if (lval2.ident == iVARIABLE && lval3.ident == lval2.ident		 && lval3.sym == lval2.sym)	       {		  assert(lval3.sym != NULL);		  error(226, lval3.sym->name);	/* self-assignment */	       }		/* if */	  }			/* if */     }				/* if */   if (lval3.ident == iARRAY || lval3.ident == iREFARRAY)     {	/* left operand is an array, right operand should be an array variable	 * of the same size and the same dimension, an array literal (of the	 * same size) or a literal string.	 */	int                 exactmatch = TRUE;	if (lval2.ident != iARRAY && lval2.ident != iREFARRAY)	   error(33, lval3.sym->name);	/* array must be indexed */	if (lval2.sym != NULL)	  {	     val = lval2.sym->dim.array.length;	/* array variable */	     level = lval2.sym->dim.array.level;	  }	else	  {	     val = lval2.constval;	/* literal array */	     level = 0;	     /* If val is negative, it means that lval2 is a	      * literal string. The string array size may be	      * smaller than the destination array.	      */	     if (val < 0)	       {		  val = -val;		  exactmatch = FALSE;	       }		/* if */	  }			/* if */	if (lval3.sym->dim.array.level != level)	   return error(48);	/* array dimensions must match */	else if (lval3.sym->dim.array.length < val		 || exactmatch && lval3.sym->dim.array.length > val)	   return error(47);	/* array sizes must match */	if (level > 0)	  {	     /* check the sizes of all sublevels too */	     symbol             *sym1 = lval3.sym;	     symbol             *sym2 = lval2.sym;	     int                 i;	     assert(sym1 != NULL && sym2 != NULL);	     /* ^^^ sym2 must be valid, because only variables can be	      *     multi-dimensional (there are no multi-dimensional arrays),	      *     sym1 must be valid because it must be an lvalue	      */	     assert(exactmatch);	     for (i = 0; i < level; i++)	       {		  sym1 = finddepend(sym1);		  sym2 = finddepend(sym2);		  assert(sym1 != NULL && sym2 != NULL);		  /* ^^^ both arrays have the same dimensions (this was checked		   *     earlier) so the dependend should always be found		   */		  if (sym1->dim.array.length != sym2->dim.array.length)		     error(47);	/* array sizes must match */	       }		/* for */	     /* get the total size in cells of the multi-dimensional array */	     val = array_totalsize(lval3.sym);	     assert(val > 0);	/* already checked */	  }			/* if */     }   else     {	/* left operand is not an array, right operand should then not be either */	if (lval2.ident == iARRAY || lval2.ident == iREFARRAY)	   error(6);		/* must be assigned to an array */     }				/* if */   if (lval3.ident == iARRAY || lval3.ident == iREFARRAY)     {	memcopy(val * sizeof(cell));     }   else     {	check_userop(NULL, lval2.tag, lval3.tag, 2, &lval3, &lval2.tag);	store(&lval3);		/* now, store the expression result */     }				/* if */   if (!oper && !matchtag(lval3.tag, lval2.tag, TRUE))      error(213);		/* tagname mismatch (if "oper", warning already given in plunge2()) */   if (lval3.sym)      markusage(lval3.sym, uWRITTEN);   sideeffect = TRUE;   bitwise_opercount = bwcount;   return FALSE;		/* expression result is never an lvalue */}