/* data.c -- Implementation File (module.c template V1.0)
   Copyright (C) 1995, 1996 Free Software Foundation, Inc.
   Contributed by James Craig Burley (burley@gnu.ai.mit.edu).

This file is part of GNU Fortran.

GNU Fortran is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Fortran is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Fortran; see the file COPYING.  If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.

   Related Modules:

   Description:
      Do the tough things for DATA statement (and INTEGER FOO/.../-style
      initializations), like implied-DO and suchlike.

   Modifications:
*/

/* Include files. */

#include "proj.h"
#include "data.h"
#include "bit.h"
#include "bld.h"
#include "com.h"
#include "expr.h"
#include "global.h"
#include "malloc.h"
#include "st.h"
#include "storag.h"
#include "top.h"

/* Externals defined here. */


/* Simple definitions and enumerations. */

/* I picked this value as one that, when plugged into a couple of small
   but nearly identical test cases I have called BIG-0.f and BIG-1.f,
   causes BIG-1.f to take about 10 times as long (elapsed) to compile
   (in f771 only) as BIG-0.f.  These test cases differ in that BIG-0.f
   doesn't put the one initialized variable in a common area that has
   a large uninitialized array in it, while BIG-1.f does.  The size of
   the array is this many elements, as long as they all are INTEGER
   type.  Note that, as of 0.5.18, sparse cases are better handled,
   so BIG-2.f now is used; it provides nonzero initial
   values for all elements of the same array BIG-0 has.  */
#ifndef FFEDATA_sizeTOO_BIG_INIT_
#define FFEDATA_sizeTOO_BIG_INIT_ 75*1024
#endif

/* Internal typedefs. */

typedef struct _ffedata_convert_cache_ *ffedataConvertCache_;
typedef struct _ffedata_impdo_ *ffedataImpdo_;

/* Private include files. */


/* Internal structure definitions. */

struct _ffedata_convert_cache_
  {
    ffebld converted;		/* Results of converting expr to following
				   type. */
    ffeinfoBasictype basic_type;
    ffeinfoKindtype kind_type;
    ffetargetCharacterSize size;
    ffeinfoRank rank;
  };

struct _ffedata_impdo_
  {
    ffedataImpdo_ outer;	/* Enclosing IMPDO construct. */
    ffebld outer_list;		/* Item after my IMPDO on the outer list. */
    ffebld my_list;		/* Beginning of list in my IMPDO. */
    ffesymbol itervar;		/* Iteration variable. */
    ffetargetIntegerDefault increment;
    ffetargetIntegerDefault final;
  };

/* Static objects accessed by functions in this module. */

static ffedataImpdo_ ffedata_stack_ = NULL;
static ffebld ffedata_list_ = NULL;
static bool ffedata_reinit_;	/* value_ should report REINIT error. */
static bool ffedata_reported_error_;	/* Error has been reported. */
static ffesymbol ffedata_symbol_ = NULL;	/* Symbol being initialized. */
static ffeinfoBasictype ffedata_basictype_;	/* Info on symbol. */
static ffeinfoKindtype ffedata_kindtype_;
static ffestorag ffedata_storage_;	/* If non-NULL, inits go into this parent. */
static ffeinfoBasictype ffedata_storage_bt_;	/* Info on storage. */
static ffeinfoKindtype ffedata_storage_kt_;
static ffetargetOffset ffedata_storage_size_;	/* Size of entire storage. */
static ffetargetAlign ffedata_storage_units_;	/* #units per storage unit. */
static ffetargetOffset ffedata_arraysize_;	/* Size of array being
						   inited. */
static ffetargetOffset ffedata_expected_;	/* Number of elements to
						   init. */
static ffetargetOffset ffedata_number_;	/* #elements inited so far. */
static ffetargetOffset ffedata_offset_;	/* Offset of next element. */
static ffetargetOffset ffedata_symbolsize_;	/* Size of entire sym. */
static ffetargetCharacterSize ffedata_size_;	/* Size of an element. */
static ffetargetCharacterSize ffedata_charexpected_;	/* #char to init. */
static ffetargetCharacterSize ffedata_charnumber_;	/* #chars inited. */
static ffetargetCharacterSize ffedata_charoffset_;	/* Offset of next char. */
static ffedataConvertCache_ ffedata_convert_cache_;	/* Fewer conversions. */
static int ffedata_convert_cache_max_ = 0;	/* #entries available. */
static int ffedata_convert_cache_use_ = 0;	/* #entries in use. */

/* Static functions (internal). */

static bool ffedata_advance_ (void);
static ffebld ffedata_convert_ (ffebld source, ffelexToken source_token,
	    ffelexToken dest_token, ffeinfoBasictype bt, ffeinfoKindtype kt,
				ffeinfoRank rk, ffetargetCharacterSize sz);
static ffetargetInteger1 ffedata_eval_integer1_ (ffebld expr);
static ffetargetOffset ffedata_eval_offset_ (ffebld subscripts,
					     ffebld dims);
static ffetargetCharacterSize ffedata_eval_substr_begin_ (ffebld expr);
static ffetargetCharacterSize ffedata_eval_substr_end_ (ffebld expr,
		    ffetargetCharacterSize min, ffetargetCharacterSize max);
static void ffedata_gather_ (ffestorag mst, ffestorag st);
static void ffedata_pop_ (void);
static void ffedata_push_ (void);
static bool ffedata_value_ (ffebld value, ffelexToken token);

/* Internal macros. */


/* ffedata_begin -- Initialize with list of targets

   ffebld list;
   ffedata_begin(list);	 // ITEM... list of SYMTERs, ARRAYs, SUBSTRs, ...

   Remember the list.  After this call, 0...n calls to ffedata_value must
   follow, and then a single call to ffedata_end.  */

void
ffedata_begin (ffebld list)
{
  assert (ffedata_list_ == NULL);
  ffedata_list_ = list;
  ffedata_symbol_ = NULL;
  ffedata_reported_error_ = FALSE;
  ffedata_reinit_ = FALSE;
  ffedata_advance_ ();
}

/* ffedata_end -- End of initialization sequence

   if (ffedata_end(FALSE))
       // everything's ok

   Make sure the end of the list is valid here.	 */

bool
ffedata_end (bool reported_error, ffelexToken t)
{
  reported_error |= ffedata_reported_error_;

  /* If still targets to initialize, too few initializers, so complain. */

  if ((ffedata_symbol_ != NULL) && !reported_error)
    {
      reported_error = TRUE;
      ffebad_start (FFEBAD_DATA_TOOFEW);
      ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t));
      ffebad_string (ffesymbol_text (ffedata_symbol_));
      ffebad_finish ();
    }

  /* Pop off any impdo stacks (present only if ffedata_symbol_ != NULL). */

  while (ffedata_stack_ != NULL)
    ffedata_pop_ ();

  if (ffedata_list_ != NULL)
    {
      assert (reported_error);
      ffedata_list_ = NULL;
    }

  return TRUE;
}

/* ffedata_gather -- Gather previously disparate initializations into one place

   ffestorag st;  // A typeCBLOCK or typeLOCAL aggregate.
   ffedata_gather(st);

   Prior to this call, st has no init or accretion info, but (presumably
   at least one of) its subordinate storage areas has init or accretion
   info.  After this call, none of the subordinate storage areas has inits,
   because they've all been moved into the newly created init/accretion
   info for st.	 During this call, conflicting inits produce only one
   error message.  */

void
ffedata_gather (ffestorag st)
{
  ffesymbol s;
  ffebld b;

  /* Prepare info on the storage area we're putting init info into. */

  ffetarget_aggregate_info (&ffedata_storage_bt_, &ffedata_storage_kt_,
			    &ffedata_storage_units_, ffestorag_basictype (st),
			    ffestorag_kindtype (st));
  ffedata_storage_size_ = ffestorag_size (st) / ffedata_storage_units_;
  assert (ffestorag_size (st) % ffedata_storage_units_ == 0);

  /* If a CBLOCK, gather all the init info for its explicit members. */

  if ((ffestorag_type (st) == FFESTORAG_typeCBLOCK)
      && (ffestorag_symbol (st) != NULL))
    {
      s = ffestorag_symbol (st);
      for (b = ffesymbol_commonlist (s); b != NULL; b = ffebld_trail (b))
	ffedata_gather_ (st,
			 ffesymbol_storage (ffebld_symter (ffebld_head (b))));
    }

  /* For CBLOCK or LOCAL, gather all the init info for equivalenced members. */

  ffestorag_drive (ffestorag_list_equivs (st), ffedata_gather_, st);
}

/* ffedata_value -- Provide some number of initial values

   ffebld value;
   ffelexToken t;  // Points to the value.
   if (ffedata_value(1,value,t))
       // Everything's ok

   Makes sure the value is ok, then remembers it according to the list
   provided to ffedata_begin.  As many instances of the value may be
   supplied as desired, as indicated by the first argument.  */

bool
ffedata_value (ffetargetIntegerDefault rpt, ffebld value, ffelexToken token)
{
  ffetargetIntegerDefault i;

  /* Maybe ignore zero values, to speed up compiling, even though we lose
     checking for multiple initializations for now.  */

  if (!ffe_is_zeros ()
      && (value != NULL)
      && (ffebld_op (value) == FFEBLD_opCONTER)
      && ffebld_constant_is_zero (ffebld_conter (value)))
    value = NULL;
  else if ((value != NULL)
	   && (ffebld_op (value) == FFEBLD_opANY))
    value = NULL;
  else
    {
      /* Must be a constant. */
      assert (value != NULL);
      assert (ffebld_op (value) == FFEBLD_opCONTER);
    }

  /* Later we can optimize certain cases by seeing that the target array can
     take some number of values, and provide this number to _value_. */

  if (rpt == 1)
    ffedata_convert_cache_use_ = -1;	/* Don't bother caching. */
  else
    ffedata_convert_cache_use_ = 0;	/* Maybe use the cache. */

  for (i = 0; i < rpt; ++i)
    {
      if ((ffedata_symbol_ != NULL)
	  && !ffesymbol_is_init (ffedata_symbol_))
	{
	  ffesymbol_signal_change (ffedata_symbol_);
	  ffesymbol_update_init (ffedata_symbol_);
	  if (1 || ffe_is_90 ())
	    ffesymbol_update_save (ffedata_symbol_);
#if FFEGLOBAL_ENABLED
	  if (ffesymbol_common (ffedata_symbol_) != NULL)
	    ffeglobal_init_common (ffesymbol_common (ffedata_symbol_),
				   token);
#endif
	  ffesymbol_signal_unreported (ffedata_symbol_);
	}
      if (!ffedata_value_ (value, token))
	return FALSE;
    }

  return TRUE;
}

/* ffedata_advance_ -- Advance initialization target to next item in list

   if (ffedata_advance_())
       // everything's ok

   Sets common info to characterize the next item in the list.	Handles
   IMPDO constructs accordingly.  Does not handle advances within a single
   item, as in the common extension "DATA CHARTYPE/33,34,35/", where
   CHARTYPE is CHARACTER*3, for example.  */

static bool
ffedata_advance_ ()
{
  ffebld next;

  /* Come here after handling an IMPDO. */

tail_recurse:			/* :::::::::::::::::::: */

  /* Assume we're not going to find a new target for now. */

  ffedata_symbol_ = NULL;

  /* If at the end of the list, we're done. */

  if (ffedata_list_ == NULL)
    {
      ffetargetIntegerDefault newval;

      if (ffedata_stack_ == NULL)
	return TRUE;		/* No IMPDO in progress, we is done! */

      /* Iterate the IMPDO. */

      newval = ffesymbol_value (ffedata_stack_->itervar)
	+ ffedata_stack_->increment;

      /* See if we're still in the loop. */

      if (((ffedata_stack_->increment > 0)
	   ? newval > ffedata_stack_->final
	   : newval < ffedata_stack_->final)
	  || (((ffesymbol_value (ffedata_stack_->itervar) < 0)
	       == (ffedata_stack_->increment < 0))
	      && ((ffesymbol_value (ffedata_stack_->itervar) < 0)
		  != (newval < 0))))	/* Overflow/underflow? */
	{			/* Done with the loop. */
	  ffedata_list_ = ffedata_stack_->outer_list;	/* Restore list. */
	  ffedata_pop_ ();	/* Pop me off the impdo stack. */
	}
      else
	{			/* Still in the loop, reset the list and
				   update the iter var. */
	  ffedata_list_ = ffedata_stack_->my_list;	/* Reset list. */
	  ffesymbol_set_value (ffedata_stack_->itervar, newval);
	}
      goto tail_recurse;	/* :::::::::::::::::::: */
    }

  /* Move to the next item in the list. */

  next = ffebld_head (ffedata_list_);
  ffedata_list_ = ffebld_trail (ffedata_list_);

  /* Really shouldn't happen. */

  if (next == NULL)
    return TRUE;

  /* See what kind of target this is. */

  switch (ffebld_op (next))
    {
    case FFEBLD_opSYMTER:	/* Simple reference to scalar or array. */
      ffedata_symbol_ = ffebld_symter (next);
      ffedata_storage_ = (ffesymbol_storage (ffedata_symbol_) == NULL) ? NULL
	: ffestorag_parent (ffesymbol_storage (ffedata_symbol_));
      if (ffedata_storage_ != NULL)
	{
	  ffetarget_aggregate_info (&ffedata_storage_bt_, &ffedata_storage_kt_,
				    &ffedata_storage_units_,
				    ffestorag_basictype (ffedata_storage_),
				    ffestorag_kindtype (ffedata_storage_));
	  ffedata_storage_size_ = ffestorag_size (ffedata_storage_)
	    / ffedata_storage_units_;
	  assert (ffestorag_size (ffedata_storage_) % ffedata_storage_units_ == 0);
	}

      if ((ffesymbol_init (ffedata_symbol_) != NULL)
	  || (ffesymbol_accretion (ffedata_symbol_) != NULL)
	  || ((ffedata_storage_ != NULL)
	      && (ffestorag_init (ffedata_storage_) != NULL)))
	{
#if 0
	  ffebad_start (FFEBAD_DATA_REINIT);
	  ffest_ffebad_here_current_stmt (0);
	  ffebad_string (ffesymbol_text (ffedata_symbol_));
	  ffebad_finish ();
	  ffedata_reported_error_ = TRUE;
	  return FALSE;
#else
	  ffedata_reinit_ = TRUE;
	  return TRUE;
#endif
	}
      ffedata_basictype_ = ffesymbol_basictype (ffedata_symbol_);
      ffedata_kindtype_ = ffesymbol_kindtype (ffedata_symbol_);
      if (ffesymbol_rank (ffedata_symbol_) == 0)
	ffedata_arraysize_ = 1;
      else
	{
	  ffebld size = ffesymbol_arraysize (ffedata_symbol_);

	  assert (size != NULL);
	  assert (ffebld_op (size) == FFEBLD_opCONTER);
	  assert (ffeinfo_basictype (ffebld_info (size))
		  == FFEINFO_basictypeINTEGER);
	  assert (ffeinfo_kindtype (ffebld_info (size))
		  == FFEINFO_kindtypeINTEGERDEFAULT);
	  ffedata_arraysize_ = ffebld_constant_integerdefault (ffebld_conter
							       (size));
	}
      ffedata_expected_ = ffedata_arraysize_;
      ffedata_number_ = 0;
      ffedata_offset_ = 0;
      ffedata_size_ = (ffedata_basictype_ == FFEINFO_basictypeCHARACTER)
	? ffesymbol_size (ffedata_symbol_) : 1;
      ffedata_symbolsize_ = ffedata_size_ * ffedata_arraysize_;
      ffedata_charexpected_ = ffedata_size_;
      ffedata_charnumber_ = 0;
      ffedata_charoffset_ = 0;
      break;

    case FFEBLD_opARRAYREF:	/* Reference to element of array. */
      ffedata_symbol_ = ffebld_symter (ffebld_left (next));
      ffedata_storage_ = (ffesymbol_storage (ffedata_symbol_) == NULL) ? NULL
	: ffestorag_parent (ffesymbol_storage (ffedata_symbol_));
      if (ffedata_storage_ != NULL)
	{
	  ffetarget_aggregate_info (&ffedata_storage_bt_, &ffedata_storage_kt_,
				    &ffedata_storage_units_,
				    ffestorag_basictype (ffedata_storage_),
				    ffestorag_kindtype (ffedata_storage_));
	  ffedata_storage_size_ = ffestorag_size (ffedata_storage_)
	    / ffedata_storage_units_;
	  assert (ffestorag_size (ffedata_storage_) % ffedata_storage_units_ == 0);
	}

      if ((ffesymbol_init (ffedata_symbol_) != NULL)
	  || ((ffedata_storage_ != NULL)
	      && (ffestorag_init (ffedata_storage_) != NULL)))
	{
#if 0
	  ffebad_start (FFEBAD_DATA_REINIT);
	  ffest_ffebad_here_current_stmt (0);
	  ffebad_string (ffesymbol_text (ffedata_symbol_));
	  ffebad_finish ();
	  ffedata_reported_error_ = TRUE;
	  return FALSE;
#else
	  ffedata_reinit_ = TRUE;
	  return TRUE;
#endif
	}
      ffedata_basictype_ = ffesymbol_basictype (ffedata_symbol_);
      ffedata_kindtype_ = ffesymbol_kindtype (ffedata_symbol_);
      if (ffesymbol_rank (ffedata_symbol_) == 0)
	ffedata_arraysize_ = 1;	/* Shouldn't happen in this case... */
      else
	{
	  ffebld size = ffesymbol_arraysize (ffedata_symbol_);

	  assert (size != NULL);
	  assert (ffebld_op (size) == FFEBLD_opCONTER);
	  assert (ffeinfo_basictype (ffebld_info (size))
		  == FFEINFO_basictypeINTEGER);
	  assert (ffeinfo_kindtype (ffebld_info (size))
		  == FFEINFO_kindtypeINTEGERDEFAULT);
	  ffedata_arraysize_ = ffebld_constant_integerdefault (ffebld_conter
							       (size));
	}
      ffedata_expected_ = 1;
      ffedata_number_ = 0;
      ffedata_offset_ = ffedata_eval_offset_ (ffebld_right (next),
					  ffesymbol_dims (ffedata_symbol_));
      ffedata_size_ = (ffedata_basictype_ == FFEINFO_basictypeCHARACTER)
	? ffesymbol_size (ffedata_symbol_) : 1;
      ffedata_symbolsize_ = ffedata_size_ * ffedata_arraysize_;
      ffedata_charexpected_ = ffedata_size_;
      ffedata_charnumber_ = 0;
      ffedata_charoffset_ = 0;
      break;

    case FFEBLD_opSUBSTR:	/* Substring reference to scalar or array
				   element. */
      {
	bool arrayref = ffebld_op (ffebld_left (next)) == FFEBLD_opARRAYREF;
	ffebld colon = ffebld_right (next);

	assert (colon != NULL);

	ffedata_symbol_ = ffebld_symter (ffebld_left (arrayref
					      ? ffebld_left (next) : next));
	ffedata_storage_ = (ffesymbol_storage (ffedata_symbol_) == NULL) ? NULL
	  : ffestorag_parent (ffesymbol_storage (ffedata_symbol_));
	if (ffedata_storage_ != NULL)
	  {
	    ffetarget_aggregate_info (&ffedata_storage_bt_, &ffedata_storage_kt_,
				      &ffedata_storage_units_,
				      ffestorag_basictype (ffedata_storage_),
				      ffestorag_kindtype (ffedata_storage_));
	    ffedata_storage_size_ = ffestorag_size (ffedata_storage_)
	      / ffedata_storage_units_;
	    assert (ffestorag_size (ffedata_storage_) % ffedata_storage_units_ == 0);
	  }

	if ((ffesymbol_init (ffedata_symbol_) != NULL)
	    || ((ffedata_storage_ != NULL)
		&& (ffestorag_init (ffedata_storage_) != NULL)))
	  {
#if 0
	    ffebad_start (FFEBAD_DATA_REINIT);
	    ffest_ffebad_here_current_stmt (0);
	    ffebad_string (ffesymbol_text (ffedata_symbol_));
	    ffebad_finish ();
	    ffedata_reported_error_ = TRUE;
	    return FALSE;
#else
	    ffedata_reinit_ = TRUE;
	    return TRUE;
#endif
	  }
	ffedata_basictype_ = ffesymbol_basictype (ffedata_symbol_);
	ffedata_kindtype_ = ffesymbol_kindtype (ffedata_symbol_);
	if (ffesymbol_rank (ffedata_symbol_) == 0)
	  ffedata_arraysize_ = 1;
	else
	  {
	    ffebld size = ffesymbol_arraysize (ffedata_symbol_);

	    assert (size != NULL);
	    assert (ffebld_op (size) == FFEBLD_opCONTER);
	    assert (ffeinfo_basictype (ffebld_info (size))
		    == FFEINFO_basictypeINTEGER);
	    assert (ffeinfo_kindtype (ffebld_info (size))
		    == FFEINFO_kindtypeINTEGERDEFAULT);
	    ffedata_arraysize_ = ffebld_constant_integerdefault (ffebld_conter
								 (size));
	  }
	ffedata_expected_ = arrayref ? 1 : ffedata_arraysize_;
	ffedata_number_ = 0;
	ffedata_offset_ = arrayref ? ffedata_eval_offset_ (ffebld_right
		(ffebld_left (next)), ffesymbol_dims (ffedata_symbol_)) : 0;
	ffedata_size_ = ffesymbol_size (ffedata_symbol_);
	ffedata_symbolsize_ = ffedata_size_ * ffedata_arraysize_;
	ffedata_charnumber_ = 0;
	ffedata_charoffset_ = ffedata_eval_substr_begin_ (ffebld_head (colon));
	ffedata_charexpected_ = ffedata_eval_substr_end_ (ffebld_head
				(ffebld_trail (colon)), ffedata_charoffset_,
				   ffedata_size_) - ffedata_charoffset_ + 1;
      }
      break;

    case FFEBLD_opIMPDO:	/* Implied-DO construct. */
      {
	ffebld itervar;
	ffebld start;
	ffebld end;
	ffebld incr;
	ffebld item = ffebld_right (next);

	itervar = ffebld_head (item);
	item = ffebld_trail (item);
	start = ffebld_head (item);
	item = ffebld_trail (item);
	end = ffebld_head (item);
	item = ffebld_trail (item);
	incr = ffebld_head (item);

	ffedata_push_ ();
	ffedata_stack_->outer_list = ffedata_list_;
	ffedata_stack_->my_list = ffedata_list_ = ffebld_left (next);

	assert (ffeinfo_basictype (ffebld_info (itervar))
		== FFEINFO_basictypeINTEGER);
	assert (ffeinfo_kindtype (ffebld_info (itervar))
		== FFEINFO_kindtypeINTEGERDEFAULT);
	ffedata_stack_->itervar = ffebld_symter (itervar);

	assert (ffeinfo_basictype (ffebld_info (start))
		== FFEINFO_basictypeINTEGER);
	assert (ffeinfo_kindtype (ffebld_info (start))
		== FFEINFO_kindtypeINTEGERDEFAULT);
	ffesymbol_set_value (ffedata_stack_->itervar, ffedata_eval_integer1_ (start));

	assert (ffeinfo_basictype (ffebld_info (end))
		== FFEINFO_basictypeINTEGER);
	assert (ffeinfo_kindtype (ffebld_info (end))
		== FFEINFO_kindtypeINTEGERDEFAULT);
	ffedata_stack_->final = ffedata_eval_integer1_ (end);

	if (incr == NULL)
	  ffedata_stack_->increment = 1;
	else
	  {
	    assert (ffeinfo_basictype (ffebld_info (incr))
		    == FFEINFO_basictypeINTEGER);
	    assert (ffeinfo_kindtype (ffebld_info (incr))
		    == FFEINFO_kindtypeINTEGERDEFAULT);
	    ffedata_stack_->increment = ffedata_eval_integer1_ (incr);
	    if (ffedata_stack_->increment == 0)
	      {
		ffebad_start (FFEBAD_DATA_ZERO);
		ffest_ffebad_here_current_stmt (0);
		ffebad_string (ffesymbol_text (ffedata_stack_->itervar));
		ffebad_finish ();
		ffedata_pop_ ();
		ffedata_reported_error_ = TRUE;
		return FALSE;
	      }
	  }

	if ((ffedata_stack_->increment > 0)
	    ? ffesymbol_value (ffedata_stack_->itervar)
	    > ffedata_stack_->final
	    : ffesymbol_value (ffedata_stack_->itervar)
	    < ffedata_stack_->final)
	  {
	    ffedata_reported_error_ = TRUE;
	    ffebad_start (FFEBAD_DATA_EMPTY);
	    ffest_ffebad_here_current_stmt (0);
	    ffebad_string (ffesymbol_text (ffedata_stack_->itervar));
	    ffebad_finish ();
	    ffedata_pop_ ();
	    return FALSE;
	  }
      }
      goto tail_recurse;	/* :::::::::::::::::::: */

    case FFEBLD_opANY:
      ffedata_reported_error_ = TRUE;
      return FALSE;

    default:
      assert ("bad op" == NULL);
      break;
    }

  return TRUE;
}

/* ffedata_convert_ -- Convert source expression to given type using cache

   ffebld source;
   ffelexToken source_token;
   ffelexToken dest_token;  // Any appropriate token for "destination".
   ffeinfoBasictype bt;
   ffeinfoKindtype kt;
   ffetargetCharactersize sz;
   source = ffedata_convert_(source,source_token,dest_token,bt,kt,sz);

   Like ffeexpr_convert, but calls it only if necessary (if the converted
   expression doesn't already exist in the cache) and then puts the result
   in the cache.  */

ffebld
ffedata_convert_ (ffebld source, ffelexToken source_token,
		  ffelexToken dest_token, ffeinfoBasictype bt,
		  ffeinfoKindtype kt, ffeinfoRank rk,
		  ffetargetCharacterSize sz)
{
  ffebld converted;
  int i;
  int max;
  ffedataConvertCache_ cache;

  for (i = 0; i < ffedata_convert_cache_use_; ++i)
    if ((bt == ffedata_convert_cache_[i].basic_type)
	&& (kt == ffedata_convert_cache_[i].kind_type)
	&& (sz == ffedata_convert_cache_[i].size)
	&& (rk == ffedata_convert_cache_[i].rank))
      return ffedata_convert_cache_[i].converted;

  converted = ffeexpr_convert (source, source_token, dest_token, bt, kt, rk,
			       sz, FFEEXPR_contextDATA);

  if (ffedata_convert_cache_use_ >= ffedata_convert_cache_max_)
    {
      if (ffedata_convert_cache_max_ == 0)
	max = 4;
      else
	max = ffedata_convert_cache_max_ << 1;

      if (max > ffedata_convert_cache_max_)
	{
	  cache = (ffedataConvertCache_) malloc_new_ks (malloc_pool_image (),
				    "FFEDATA cache", max * sizeof (*cache));
	  if (ffedata_convert_cache_max_ != 0)
	    {
	      memcpy (cache, ffedata_convert_cache_,
		      ffedata_convert_cache_max_ * sizeof (*cache));
	      malloc_kill_ks (malloc_pool_image (), ffedata_convert_cache_,
			      ffedata_convert_cache_max_ * sizeof (*cache));
	    }
	  ffedata_convert_cache_ = cache;
	  ffedata_convert_cache_max_ = max;
	}
      else
	return converted;	/* In case int overflows! */
    }

  i = ffedata_convert_cache_use_++;

  ffedata_convert_cache_[i].converted = converted;
  ffedata_convert_cache_[i].basic_type = bt;
  ffedata_convert_cache_[i].kind_type = kt;
  ffedata_convert_cache_[i].size = sz;
  ffedata_convert_cache_[i].rank = rk;

  return converted;
}

/* ffedata_eval_integer1_ -- Evaluate expression

   ffetargetIntegerDefault result;
   ffebld expr;	 // must be kindtypeINTEGER1.

   result = ffedata_eval_integer1_(expr);

   Evalues the expression (which yields a kindtypeINTEGER1 result) and
   returns the result.	*/

static ffetargetIntegerDefault
ffedata_eval_integer1_ (ffebld expr)
{
  ffetargetInteger1 result;
  ffebad error;

  assert (expr != NULL);

  switch (ffebld_op (expr))
    {
    case FFEBLD_opCONTER:
      return ffebld_constant_integer1 (ffebld_conter (expr));

    case FFEBLD_opSYMTER:
      return ffesymbol_value (ffebld_symter (expr));

    case FFEBLD_opUPLUS:
      return ffedata_eval_integer1_ (ffebld_left (expr));

    case FFEBLD_opUMINUS:
      error = ffetarget_uminus_integer1 (&result,
			       ffedata_eval_integer1_ (ffebld_left (expr)));
      break;

    case FFEBLD_opADD:
      error = ffetarget_add_integer1 (&result,
				ffedata_eval_integer1_ (ffebld_left (expr)),
			      ffedata_eval_integer1_ (ffebld_right (expr)));
      break;

    case FFEBLD_opSUBTRACT:
      error = ffetarget_subtract_integer1 (&result,
				ffedata_eval_integer1_ (ffebld_left (expr)),
			      ffedata_eval_integer1_ (ffebld_right (expr)));
      break;

    case FFEBLD_opMULTIPLY:
      error = ffetarget_multiply_integer1 (&result,
				ffedata_eval_integer1_ (ffebld_left (expr)),
			      ffedata_eval_integer1_ (ffebld_right (expr)));
      break;

    case FFEBLD_opDIVIDE:
      error = ffetarget_divide_integer1 (&result,
				ffedata_eval_integer1_ (ffebld_left (expr)),
			      ffedata_eval_integer1_ (ffebld_right (expr)));
      break;

    case FFEBLD_opPOWER:
      {
	ffebld r = ffebld_right (expr);

	if ((ffeinfo_basictype (ffebld_info (r)) != FFEINFO_basictypeINTEGER)
	    || (ffeinfo_kindtype (ffebld_info (r)) != FFEINFO_kindtypeINTEGERDEFAULT))
	  error = FFEBAD_DATA_EVAL;
	else
	  error = ffetarget_power_integerdefault_integerdefault (&result,
				ffedata_eval_integer1_ (ffebld_left (expr)),
						ffedata_eval_integer1_ (r));
      }
      break;

#if 0				/* Only for character basictype. */
    case FFEBLD_opCONCATENATE:
      error =;
      break;
#endif

    case FFEBLD_opNOT:
      error = ffetarget_not_integer1 (&result,
			       ffedata_eval_integer1_ (ffebld_left (expr)));
      break;

#if 0				/* Only for logical basictype. */
    case FFEBLD_opLT:
      error =;
      break;

    case FFEBLD_opLE:
      error =;
      break;

    case FFEBLD_opEQ:
      error =;
      break;

    case FFEBLD_opNE:
      error =;
      break;

    case FFEBLD_opGT:
      error =;
      break;

    case FFEBLD_opGE:
      error =;
      break;
#endif

    case FFEBLD_opAND:
      error = ffetarget_and_integer1 (&result,
				ffedata_eval_integer1_ (ffebld_left (expr)),
			      ffedata_eval_integer1_ (ffebld_right (expr)));
      break;

    case FFEBLD_opOR:
      error = ffetarget_or_integer1 (&result,
				ffedata_eval_integer1_ (ffebld_left (expr)),
			      ffedata_eval_integer1_ (ffebld_right (expr)));
      break;

    case FFEBLD_opXOR:
      error = ffetarget_xor_integer1 (&result,
				ffedata_eval_integer1_ (ffebld_left (expr)),
			      ffedata_eval_integer1_ (ffebld_right (expr)));
      break;

    case FFEBLD_opEQV:
      error = ffetarget_eqv_integer1 (&result,
				ffedata_eval_integer1_ (ffebld_left (expr)),
			      ffedata_eval_integer1_ (ffebld_right (expr)));
      break;

    case FFEBLD_opNEQV:
      error = ffetarget_neqv_integer1 (&result,
				ffedata_eval_integer1_ (ffebld_left (expr)),
			      ffedata_eval_integer1_ (ffebld_right (expr)));
      break;

    case FFEBLD_opPAREN:
      return ffedata_eval_integer1_ (ffebld_left (expr));

#if 0				/* ~~ no idea how to do this */
    case FFEBLD_opPERCENT_LOC:
      error =;
      break;
#endif

#if 0				/* not allowed by ANSI, but perhaps as an
				   extension someday? */
    case FFEBLD_opCONVERT:
      switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr))))
	{
	case FFEINFO_basictypeINTEGER:
	  switch (ffeinfo_kindtype (ffebld_info (ffebld_left (expr))))
	    {
	    default:
	      error = FFEBAD_DATA_EVAL;
	      break;
	    }
	  break;

	case FFEINFO_basictypeREAL:
	  switch (ffeinfo_kindtype (ffebld_info (ffebld_left (expr))))
	    {
	    default:
	      error = FFEBAD_DATA_EVAL;
	      break;
	    }
	  break;
	}
      break;
#endif

#if 0				/* not valid ops */
    case FFEBLD_opREPEAT:
      error =;
      break;

    case FFEBLD_opBOUNDS:
      error =;
      break;
#endif

#if 0				/* not allowed by ANSI, but perhaps as an
				   extension someday? */
    case FFEBLD_opFUNCREF:
      error =;
      break;
#endif

#if 0				/* not valid ops */
    case FFEBLD_opSUBRREF:
      error =;
      break;

    case FFEBLD_opARRAYREF:
      error =;
      break;
#endif

#if 0				/* not valid for integer1 */
    case FFEBLD_opSUBSTR:
      error =;
      break;
#endif

    default:
      error = FFEBAD_DATA_EVAL;
      break;
    }

  if (error != FFEBAD)
    {
      ffebad_start (error);
      ffest_ffebad_here_current_stmt (0);
      ffebad_finish ();
      result = 0;
    }

  return result;
}

/* ffedata_eval_offset_ -- Evaluate offset info array

   ffetargetOffset offset;  // 0...max-1.
   ffebld subscripts;  // an opITEM list of subscript exprs.
   ffebld dims;	 // an opITEM list of opBOUNDS exprs.

   result = ffedata_eval_offset_(expr);

   Evalues the expression (which yields a kindtypeINTEGER1 result) and
   returns the result.	*/

static ffetargetOffset
ffedata_eval_offset_ (ffebld subscripts, ffebld dims)
{
  ffetargetIntegerDefault offset = 0;
  ffetargetIntegerDefault width = 1;
  ffetargetIntegerDefault value;
  ffetargetIntegerDefault lowbound;
  ffetargetIntegerDefault highbound;
  ffetargetOffset final;
  ffebld subscript;
  ffebld dim;
  ffebld low;
  ffebld high;
  int rank = 0;
  bool ok;

  while (subscripts != NULL)
    {
      ++rank;
      assert (dims != NULL);

      subscript = ffebld_head (subscripts);
      dim = ffebld_head (dims);

      assert (ffeinfo_basictype (ffebld_info (subscript)) == FFEINFO_basictypeINTEGER);
      assert (ffeinfo_kindtype (ffebld_info (subscript)) == FFEINFO_kindtypeINTEGER1);
      value = ffedata_eval_integer1_ (subscript);

      assert (ffebld_op (dim) == FFEBLD_opBOUNDS);
      low = ffebld_left (dim);
      high = ffebld_right (dim);

      if (low == NULL)
	lowbound = 1;
      else
	{
	  assert (ffeinfo_basictype (ffebld_info (low)) == FFEINFO_basictypeINTEGER);
	  assert (ffeinfo_kindtype (ffebld_info (low)) == FFEINFO_kindtypeINTEGERDEFAULT);
	  lowbound = ffedata_eval_integer1_ (low);
	}

      assert (ffeinfo_basictype (ffebld_info (high)) == FFEINFO_basictypeINTEGER);
      assert (ffeinfo_kindtype (ffebld_info (high)) == FFEINFO_kindtypeINTEGERDEFAULT);
      highbound = ffedata_eval_integer1_ (high);

      if ((value < lowbound) || (value > highbound))
	{
	  char rankstr[10];

	  sprintf (rankstr, "%d", rank);
	  value = lowbound;
	  ffebad_start (FFEBAD_DATA_SUBSCRIPT);
	  ffebad_string (ffesymbol_text (ffedata_symbol_));
	  ffebad_string (rankstr);
	  ffebad_finish ();
	}

      subscripts = ffebld_trail (subscripts);
      dims = ffebld_trail (dims);

      offset += width * (value - lowbound);
      if (subscripts != NULL)
	width *= highbound - lowbound + 1;
    }

  assert (dims == NULL);

  ok = ffetarget_offset (&final, offset);
  assert (ok);

  return final;
}

/* ffedata_eval_substr_begin_ -- Evaluate begin-point of substr reference

   ffetargetCharacterSize beginpoint;
   ffebld endval;  // head(colon).

   beginpoint = ffedata_eval_substr_end_(endval);

   If beginval is NULL, returns 0.  Otherwise makes sure beginval is
   kindtypeINTEGERDEFAULT, makes sure its value is > 0,
   and returns its value minus one, or issues an error message.	 */

static ffetargetCharacterSize
ffedata_eval_substr_begin_ (ffebld expr)
{
  ffetargetIntegerDefault val;

  if (expr == NULL)
    return 0;

  assert (ffeinfo_basictype (ffebld_info (expr)) == FFEINFO_basictypeINTEGER);
  assert (ffeinfo_kindtype (ffebld_info (expr)) == FFEINFO_kindtypeINTEGERDEFAULT);

  val = ffedata_eval_integer1_ (expr);

  if (val < 1)
    {
      val = 1;
      ffebad_start (FFEBAD_DATA_RANGE);
      ffest_ffebad_here_current_stmt (0);
      ffebad_string (ffesymbol_text (ffedata_symbol_));
      ffebad_finish ();
      ffedata_reported_error_ = TRUE;
    }

  return val - 1;
}

/* ffedata_eval_substr_end_ -- Evaluate end-point of substr reference

   ffetargetCharacterSize endpoint;
   ffebld endval;  // head(trail(colon)).
   ffetargetCharacterSize min;	// beginpoint of substr reference.
   ffetargetCharacterSize max;	// size of entity.

   endpoint = ffedata_eval_substr_end_(endval,dflt);

   If endval is NULL, returns max.  Otherwise makes sure endval is
   kindtypeINTEGERDEFAULT, makes sure its value is > min and <= max,
   and returns its value minus one, or issues an error message.	 */

static ffetargetCharacterSize
ffedata_eval_substr_end_ (ffebld expr, ffetargetCharacterSize min,
			  ffetargetCharacterSize max)
{
  ffetargetIntegerDefault val;

  if (expr == NULL)
    return max - 1;

  assert (ffeinfo_basictype (ffebld_info (expr)) == FFEINFO_basictypeINTEGER);
  assert (ffeinfo_kindtype (ffebld_info (expr)) == FFEINFO_kindtypeINTEGER1);

  val = ffedata_eval_integer1_ (expr);

  if ((val < (ffetargetIntegerDefault) min)
      || (val > (ffetargetIntegerDefault) max))
    {
      val = 1;
      ffebad_start (FFEBAD_DATA_RANGE);
      ffest_ffebad_here_current_stmt (0);
      ffebad_string (ffesymbol_text (ffedata_symbol_));
      ffebad_finish ();
      ffedata_reported_error_ = TRUE;
    }

  return val - 1;
}

/* ffedata_gather_ -- Gather initial values for sym into master sym inits

   ffestorag mst;  // A typeCBLOCK or typeLOCAL aggregate.
   ffestorag st;  // A typeCOMMON or typeEQUIV member.
   ffedata_gather_(mst,st);

   If st has any initialization info, transfer that info into mst and
   clear st's info.  */

void
ffedata_gather_ (ffestorag mst, ffestorag st)
{
  ffesymbol s;
  ffesymbol s_whine;		/* Symbol to complain about in diagnostics. */
  ffebld b;
  ffetargetOffset offset;
  ffetargetOffset units_expected;
  ffebitCount actual;
  ffebldConstantArray array;
  ffebld accter;
  ffetargetCopyfunc fn;
  void *ptr1;
  void *ptr2;
  size_t size;
  ffeinfoBasictype bt;
  ffeinfoKindtype kt;
  ffeinfoBasictype ign_bt;
  ffeinfoKindtype ign_kt;
  ffetargetAlign units;
  ffebit bits;
  ffetargetOffset source_offset;
  bool whine = FALSE;

  if (st == NULL)
    return;			/* Nothing to do. */

  s = ffestorag_symbol (st);

  assert (s != NULL);		/* Must have a corresponding symbol (else how
				   inited?). */
  assert (ffestorag_init (st) == NULL);	/* No init info on storage itself. */
  assert (ffestorag_accretion (st) == NULL);

  if ((((b = ffesymbol_init (s)) == NULL)
       && ((b = ffesymbol_accretion (s)) == NULL))
      || (ffebld_op (b) == FFEBLD_opANY)
      || ((ffebld_op (b) == FFEBLD_opCONVERT)
	  && (ffebld_op (ffebld_left (b)) == FFEBLD_opANY)))
    return;			/* Nothing to do. */

  /* b now holds the init/accretion expr. */

  ffesymbol_set_init (s, NULL);
  ffesymbol_set_accretion (s, NULL);
  ffesymbol_set_accretes (s, 0);

  s_whine = ffestorag_symbol (mst);
  if (s_whine == NULL)
    s_whine = s;

  /* Make sure we haven't fully accreted during an array init. */

  if (ffestorag_init (mst) != NULL)
    {
      ffebad_start (FFEBAD_DATA_MULTIPLE);
      ffebad_here (0, ffewhere_line_unknown (), ffewhere_column_unknown ());
      ffebad_string (ffesymbol_text (s_whine));
      ffebad_finish ();
      return;
    }

  bt = ffeinfo_basictype (ffebld_info (b));
  kt = ffeinfo_kindtype (ffebld_info (b));

  /* Calculate offset for aggregate area. */

  ffedata_charexpected_ = (bt == FFEINFO_basictypeCHARACTER)
    ? ffebld_size (b) : 1;
  ffetarget_aggregate_info (&ign_bt, &ign_kt, &units, bt,
			    kt);/* Find out unit size of source datum. */
  assert (units % ffedata_storage_units_ == 0);
  units_expected = ffedata_charexpected_ * units / ffedata_storage_units_;
  offset = (ffestorag_offset (st) - ffestorag_offset (mst))
    / ffedata_storage_units_;

  /* Does an accretion array exist?  If not, create it. */

  if (ffestorag_accretion (mst) == NULL)
    {
#if FFEDATA_sizeTOO_BIG_INIT_ != 0
      if (ffedata_storage_size_ >= FFEDATA_sizeTOO_BIG_INIT_)
	{
	  char bignum[40];

	  sprintf (&bignum[0], "%ld", (long) ffedata_storage_size_);
	  ffebad_start (FFEBAD_TOO_BIG_INIT);
	  ffebad_here (0, ffesymbol_where_line (s_whine),
		       ffesymbol_where_column (s_whine));
	  ffebad_string (ffesymbol_text (s_whine));
	  ffebad_string (bignum);
	  ffebad_finish ();
	}
#endif
      array = ffebld_constantarray_new (ffedata_storage_bt_,
				ffedata_storage_kt_, ffedata_storage_size_);
      accter = ffebld_new_accter (array, ffebit_new (ffe_pool_program_unit (),
						     ffedata_storage_size_));
      ffebld_set_info (accter, ffeinfo_new
		       (ffedata_storage_bt_,
			ffedata_storage_kt_,
			1,
			FFEINFO_kindENTITY,
			FFEINFO_whereCONSTANT,
			(ffedata_basictype_ == FFEINFO_basictypeCHARACTER)
			? 1 : FFETARGET_charactersizeNONE));
      ffestorag_set_accretion (mst, accter);
      ffestorag_set_accretes (mst, ffedata_storage_size_);
    }
  else
    {
      accter = ffestorag_accretion (mst);
      assert (ffedata_storage_size_ == (ffetargetOffset) ffebld_accter_size (accter));
      array = ffebld_accter (accter);
    }

  /* Put value in accretion array at desired offset. */

  fn = ffetarget_aggregate_ptr_memcpy (ffedata_storage_bt_, ffedata_storage_kt_,
				       bt, kt);

  switch (ffebld_op (b))
    {
    case FFEBLD_opCONTER:
      ffebld_constantarray_prepare (&ptr1, &ptr2, &size, array, ffedata_storage_bt_,
				    ffedata_storage_kt_, offset,
			   ffebld_constant_ptr_to_union (ffebld_conter (b)),
				    bt, kt);
      (*fn) (ptr1, ptr2, size);	/* Does the appropriate memcpy-like
				   operation. */
      ffebit_count (ffebld_accter_bits (accter),
		    offset, FALSE, units_expected, &actual);	/* How many FALSE? */
      if (units_expected != (ffetargetOffset) actual)
	{
	  ffebad_start (FFEBAD_DATA_MULTIPLE);
	  ffebad_here (0, ffewhere_line_unknown (), ffewhere_column_unknown ());
	  ffebad_string (ffesymbol_text (s));
	  ffebad_finish ();
	}
      ffestorag_set_accretes (mst,
			      ffestorag_accretes (mst)
			      - actual);	/* Decrement # of values
						   actually accreted. */
      ffebit_set (ffebld_accter_bits (accter), offset, 1, units_expected);

      /* If done accreting for this storage area, establish as initialized. */

      if (ffestorag_accretes (mst) == 0)
	{
	  ffestorag_set_init (mst, accter);
	  ffestorag_set_accretion (mst, NULL);
	  ffebit_kill (ffebld_accter_bits (ffestorag_init (mst)));
	  ffebld_set_op (ffestorag_init (mst), FFEBLD_opARRTER);
	  ffebld_set_arrter (ffestorag_init (mst),
			     ffebld_accter (ffestorag_init (mst)));
	  ffebld_arrter_set_size (ffestorag_init (mst),
				  ffedata_storage_size_);
	  ffecom_notify_init_storage (mst);
	}

      return;

    case FFEBLD_opARRTER:
      ffebld_constantarray_preparray (&ptr1, &ptr2, &size, array, ffedata_storage_bt_,
			     ffedata_storage_kt_, offset, ffebld_arrter (b),
				      bt, kt);
      size *= ffebld_arrter_size (b);
      units_expected *= ffebld_arrter_size (b);
      (*fn) (ptr1, ptr2, size);	/* Does the appropriate memcpy-like
				   operation. */
      ffebit_count (ffebld_accter_bits (accter),
		    offset, FALSE, units_expected, &actual);	/* How many FALSE? */
      if (units_expected != (ffetargetOffset) actual)
	{
	  ffebad_start (FFEBAD_DATA_MULTIPLE);
	  ffebad_here (0, ffewhere_line_unknown (), ffewhere_column_unknown ());
	  ffebad_string (ffesymbol_text (s));
	  ffebad_finish ();
	}
      ffestorag_set_accretes (mst,
			      ffestorag_accretes (mst)
			      - actual);	/* Decrement # of values
						   actually accreted. */
      ffebit_set (ffebld_accter_bits (accter), offset, 1, units_expected);

      /* If done accreting for this storage area, establish as initialized. */

      if (ffestorag_accretes (mst) == 0)
	{
	  ffestorag_set_init (mst, accter);
	  ffestorag_set_accretion (mst, NULL);
	  ffebit_kill (ffebld_accter_bits (ffestorag_init (mst)));
	  ffebld_set_op (ffestorag_init (mst), FFEBLD_opARRTER);
	  ffebld_set_arrter (ffestorag_init (mst),
			     ffebld_accter (ffestorag_init (mst)));
	  ffebld_arrter_set_size (ffestorag_init (mst),
				  ffedata_storage_size_);
	  ffecom_notify_init_storage (mst);
	}

      return;

    case FFEBLD_opACCTER:
      ffebld_constantarray_preparray (&ptr1, &ptr2, &size, array, ffedata_storage_bt_,
			     ffedata_storage_kt_, offset, ffebld_accter (b),
				      bt, kt);
      bits = ffebld_accter_bits (b);
      source_offset = 0;

      for (;;)
	{
	  ffetargetOffset unexp;
	  ffetargetOffset siz;
	  ffebitCount length;
	  bool value;

	  ffebit_test (bits, source_offset, &value, &length);
	  if (length == 0)
	    break;		/* Exit the loop early. */
	  siz = size * length;
	  unexp = units_expected * length;
	  if (value)
	    {
	      (*fn) (ptr1, ptr2, siz);	/* Does memcpy-like operation. */
	      ffebit_count (ffebld_accter_bits (accter),	/* How many FALSE? */
			    offset, FALSE, unexp, &actual);
	      if (!whine && (unexp != (ffetargetOffset) actual))
		{
		  whine = TRUE;	/* Don't whine more than once for one gather. */
		  ffebad_start (FFEBAD_DATA_MULTIPLE);
		  ffebad_here (0, ffewhere_line_unknown (), ffewhere_column_unknown ());
		  ffebad_string (ffesymbol_text (s));
		  ffebad_finish ();
		}
	      ffestorag_set_accretes (mst,
				      ffestorag_accretes (mst)
				      - actual);	/* Decrement # of values
							   actually accreted. */
	      ffebit_set (ffebld_accter_bits (accter), offset, 1, unexp);
	    }
	  source_offset += length;
	  offset += unexp;
	  ptr1 = ((char *) ptr1) + siz;
	  ptr2 = ((char *) ptr2) + siz;
	}

      /* If done accreting for this storage area, establish as initialized. */

      if (ffestorag_accretes (mst) == 0)
	{
	  ffestorag_set_init (mst, accter);
	  ffestorag_set_accretion (mst, NULL);
	  ffebit_kill (ffebld_accter_bits (ffestorag_init (mst)));
	  ffebld_set_op (ffestorag_init (mst), FFEBLD_opARRTER);
	  ffebld_set_arrter (ffestorag_init (mst),
			     ffebld_accter (ffestorag_init (mst)));
	  ffebld_arrter_set_size (ffestorag_init (mst),
				  ffedata_storage_size_);
	  ffecom_notify_init_storage (mst);
	}

      return;

    default:
      assert ("bad init op in gather_" == NULL);
      return;
    }
}

/* ffedata_pop_ -- Pop an impdo stack entry

   ffedata_pop_();  */

static void
ffedata_pop_ ()
{
  ffedataImpdo_ victim = ffedata_stack_;

  assert (victim != NULL);

  ffedata_stack_ = ffedata_stack_->outer;

  malloc_kill_ks (ffe_pool_program_unit (), victim, sizeof (*victim));
}

/* ffedata_push_ -- Push an impdo stack entry

   ffedata_push_();  */

static void
ffedata_push_ ()
{
  ffedataImpdo_ baby;

  baby = malloc_new_ks (ffe_pool_program_unit (), "ffedataImpdo_", sizeof (*baby));

  baby->outer = ffedata_stack_;
  ffedata_stack_ = baby;
}

/* ffedata_value_ -- Provide an initial value

   ffebld value;
   ffelexToken t;  // Points to the value.
   if (ffedata_value(value,t))
       // Everything's ok

   Makes sure the value is ok, then remembers it according to the list
   provided to ffedata_begin.  */

static bool
ffedata_value_ (ffebld value, ffelexToken token)
{

  /* If already reported an error, don't do anything. */

  if (ffedata_reported_error_)
    return FALSE;

  /* If the value is an error marker, remember we've seen one and do nothing
     else. */

  if ((value != NULL)
      && (ffebld_op (value) == FFEBLD_opANY))
    {
      ffedata_reported_error_ = TRUE;
      return FALSE;
    }

  /* If too many values (no more targets), complain. */

  if (ffedata_symbol_ == NULL)
    {
      ffebad_start (FFEBAD_DATA_TOOMANY);
      ffebad_here (0, ffelex_token_where_line (token),
		   ffelex_token_where_column (token));
      ffebad_finish ();
      ffedata_reported_error_ = TRUE;
      return FALSE;
    }

  /* If ffedata_advance_ wanted to register a complaint, do it now
     that we have the token to point at instead of just the start
     of the whole statement.  */

  if (ffedata_reinit_)
    {
      ffebad_start (FFEBAD_DATA_REINIT);
      ffebad_here (0, ffelex_token_where_line (token),
		   ffelex_token_where_column (token));
      ffebad_string (ffesymbol_text (ffedata_symbol_));
      ffebad_finish ();
      ffedata_reported_error_ = TRUE;
      return FALSE;
    }

#if FFEGLOBAL_ENABLED
  if (ffesymbol_common (ffedata_symbol_) != NULL)
    ffeglobal_init_common (ffesymbol_common (ffedata_symbol_), token);
#endif

  /* Convert value to desired type. */

  if (value != NULL)
    {
      if (ffedata_convert_cache_use_ == -1)
	value = ffeexpr_convert
	  (value, token, NULL, ffedata_basictype_,
	   ffedata_kindtype_, 0,
	   (ffedata_basictype_ == FFEINFO_basictypeCHARACTER)
	   ? ffedata_charexpected_ : FFETARGET_charactersizeNONE,
	   FFEEXPR_contextDATA);
      else				/* Use the cache. */
	value = ffedata_convert_
	  (value, token, NULL, ffedata_basictype_,
	   ffedata_kindtype_, 0,
	   (ffedata_basictype_ == FFEINFO_basictypeCHARACTER)
	   ? ffedata_charexpected_ : FFETARGET_charactersizeNONE);
    }

  /* If we couldn't, bug out. */

  if ((value != NULL) && (ffebld_op (value) == FFEBLD_opANY))
    {
      ffedata_reported_error_ = TRUE;
      return FALSE;
    }

  /* Handle the case where initializes go to a parent's storage area. */

  if (ffedata_storage_ != NULL)
    {
      ffetargetOffset offset;
      ffetargetOffset units_expected;
      ffebitCount actual;
      ffebldConstantArray array;
      ffebld accter;
      ffetargetCopyfunc fn;
      void *ptr1;
      void *ptr2;
      size_t size;
      ffeinfoBasictype ign_bt;
      ffeinfoKindtype ign_kt;
      ffetargetAlign units;

      /* Make sure we haven't fully accreted during an array init. */

      if (ffestorag_init (ffedata_storage_) != NULL)
	{
	  ffebad_start (FFEBAD_DATA_MULTIPLE);
	  ffebad_here (0, ffelex_token_where_line (token),
		       ffelex_token_where_column (token));
	  ffebad_string (ffesymbol_text (ffedata_symbol_));
	  ffebad_finish ();
	  ffedata_reported_error_ = TRUE;
	  return FALSE;
	}

      /* Calculate offset. */

      offset = ffedata_offset_ * ffedata_size_ + ffedata_charoffset_;

      /* Is offset within range?  If not, whine, but don't do anything else. */

      if (offset + ffedata_charexpected_ - 1 > ffedata_symbolsize_)
	{
	  ffebad_start (FFEBAD_DATA_RANGE);
	  ffest_ffebad_here_current_stmt (0);
	  ffebad_string (ffesymbol_text (ffedata_symbol_));
	  ffebad_finish ();
	  ffedata_reported_error_ = TRUE;
	  return FALSE;
	}

      /* Now calculate offset for aggregate area. */

      ffetarget_aggregate_info (&ign_bt, &ign_kt, &units, ffedata_basictype_,
				ffedata_kindtype_);	/* Find out unit size of
							   source datum. */
      assert (units % ffedata_storage_units_ == 0);
      units_expected = ffedata_charexpected_ * units / ffedata_storage_units_;
      offset *= units / ffedata_storage_units_;
      offset += (ffestorag_offset (ffesymbol_storage (ffedata_symbol_))
		 - ffestorag_offset (ffedata_storage_))
	/ ffedata_storage_units_;

      assert (offset + units_expected - 1 <= ffedata_storage_size_);

      /* Does an accretion array exist?	 If not, create it. */

      if (value != NULL)
	{
	  if (ffestorag_accretion (ffedata_storage_) == NULL)
	    {
#if FFEDATA_sizeTOO_BIG_INIT_ != 0
	      if (ffedata_storage_size_ >= FFEDATA_sizeTOO_BIG_INIT_)
		{
		  char bignum[40];

		  sprintf (&bignum[0], "%ld", (long) ffedata_storage_size_);
		  ffebad_start (FFEBAD_TOO_BIG_INIT);
		  ffebad_here (0, ffelex_token_where_line (token),
			       ffelex_token_where_column (token));
		  ffebad_string (ffesymbol_text (ffedata_symbol_));
		  ffebad_string (bignum);
		  ffebad_finish ();
		}
#endif
	      array = ffebld_constantarray_new
		(ffedata_storage_bt_, ffedata_storage_kt_,
		 ffedata_storage_size_);
	      accter = ffebld_new_accter (array,
					  ffebit_new (ffe_pool_program_unit (),
						      ffedata_storage_size_));
	      ffebld_set_info (accter, ffeinfo_new
			       (ffedata_storage_bt_,
				ffedata_storage_kt_,
				1,
				FFEINFO_kindENTITY,
				FFEINFO_whereCONSTANT,
				(ffedata_basictype_
				 == FFEINFO_basictypeCHARACTER)
				? 1 : FFETARGET_charactersizeNONE));
	      ffestorag_set_accretion (ffedata_storage_, accter);
	      ffestorag_set_accretes (ffedata_storage_, ffedata_storage_size_);
	    }
	  else
	    {
	      accter = ffestorag_accretion (ffedata_storage_);
	      assert (ffedata_storage_size_ == (ffetargetOffset) ffebld_accter_size (accter));
	      array = ffebld_accter (accter);
	    }

	  /* Put value in accretion array at desired offset. */

	  fn = ffetarget_aggregate_ptr_memcpy
	    (ffedata_storage_bt_, ffedata_storage_kt_,
	     ffedata_basictype_, ffedata_kindtype_);
	  ffebld_constantarray_prepare
	    (&ptr1, &ptr2, &size, array, ffedata_storage_bt_,
	     ffedata_storage_kt_, offset,
	     ffebld_constant_ptr_to_union (ffebld_conter (value)),
	     ffedata_basictype_, ffedata_kindtype_);
	  (*fn) (ptr1, ptr2, size);	/* Does the appropriate memcpy-like
					   operation. */
	  ffebit_count (ffebld_accter_bits (accter),
			offset, FALSE, units_expected,
			&actual);	/* How many FALSE? */
	  if (units_expected != (ffetargetOffset) actual)
	    {
	      ffebad_start (FFEBAD_DATA_MULTIPLE);
	      ffebad_here (0, ffelex_token_where_line (token),
			   ffelex_token_where_column (token));
	      ffebad_string (ffesymbol_text (ffedata_symbol_));
	      ffebad_finish ();
	    }
	  ffestorag_set_accretes (ffedata_storage_,
				  ffestorag_accretes (ffedata_storage_)
				  - actual);	/* Decrement # of values
						   actually accreted. */
	  ffebit_set (ffebld_accter_bits (accter), offset,
		      1, units_expected);

	  /* If done accreting for this storage area, establish as
	     initialized. */

	  if (ffestorag_accretes (ffedata_storage_) == 0)
	    {
	      ffestorag_set_init (ffedata_storage_, accter);
	      ffestorag_set_accretion (ffedata_storage_, NULL);
	      ffebit_kill (ffebld_accter_bits
			   (ffestorag_init (ffedata_storage_)));
	      ffebld_set_op (ffestorag_init (ffedata_storage_),
			     FFEBLD_opARRTER);
	      ffebld_set_arrter
		(ffestorag_init (ffedata_storage_),
		 ffebld_accter (ffestorag_init (ffedata_storage_)));
	      ffebld_arrter_set_size (ffestorag_init (ffedata_storage_),
				      ffedata_storage_size_);
	      ffecom_notify_init_storage (ffedata_storage_);
	    }
	}

      /* If still accreting, adjust specs accordingly and return. */

      if (++ffedata_number_ < ffedata_expected_)
	{
	  ++ffedata_offset_;
	  return TRUE;
	}

      return ffedata_advance_ ();
    }

  /* Figure out where the value goes -- in an accretion array or directly
     into the final initial-value slot for the symbol. */

  if ((ffedata_number_ != 0)
      || (ffedata_arraysize_ > 1)
      || (ffedata_charnumber_ != 0)
      || (ffedata_size_ > ffedata_charexpected_))
    {				/* Accrete this value. */
      ffetargetOffset offset;
      ffebitCount actual;
      ffebldConstantArray array;
      ffebld accter = NULL;

      /* Calculate offset. */

      offset = ffedata_offset_ * ffedata_size_ + ffedata_charoffset_;

      /* Is offset within range?  If not, whine, but don't do anything else. */

      if (offset + ffedata_charexpected_ - 1 > ffedata_symbolsize_)
	{
	  ffebad_start (FFEBAD_DATA_RANGE);
	  ffest_ffebad_here_current_stmt (0);
	  ffebad_string (ffesymbol_text (ffedata_symbol_));
	  ffebad_finish ();
	  ffedata_reported_error_ = TRUE;
	  return FALSE;
	}

      /* Does an accretion array exist?	 If not, create it. */

      if (value != NULL)
	{
	  if (ffesymbol_accretion (ffedata_symbol_) == NULL)
	    {
#if FFEDATA_sizeTOO_BIG_INIT_ != 0
	      if (ffedata_symbolsize_ >= FFEDATA_sizeTOO_BIG_INIT_ )
		{
		  char bignum[40];

		  sprintf (&bignum[0], "%ld", (long) ffedata_symbolsize_);
		  ffebad_start (FFEBAD_TOO_BIG_INIT);
		  ffebad_here (0, ffelex_token_where_line (token),
			       ffelex_token_where_column (token));
		  ffebad_string (ffesymbol_text (ffedata_symbol_));
		  ffebad_string (bignum);
		  ffebad_finish ();
		}
#endif
	      array = ffebld_constantarray_new
		(ffedata_basictype_, ffedata_kindtype_,
		 ffedata_symbolsize_);
	      accter = ffebld_new_accter (array,
					  ffebit_new (ffe_pool_program_unit (),
						      ffedata_symbolsize_));
	      ffebld_set_info (accter, ffeinfo_new
			       (ffedata_basictype_,
				ffedata_kindtype_,
				1,
				FFEINFO_kindENTITY,
				FFEINFO_whereCONSTANT,
				(ffedata_basictype_
				 == FFEINFO_basictypeCHARACTER)
				? 1 : FFETARGET_charactersizeNONE));
	      ffesymbol_set_accretion (ffedata_symbol_, accter);
	      ffesymbol_set_accretes (ffedata_symbol_, ffedata_symbolsize_);
	    }
	  else
	    {
	      accter = ffesymbol_accretion (ffedata_symbol_);
	      assert (ffedata_symbolsize_
		      == (ffetargetOffset) ffebld_accter_size (accter));
	      array = ffebld_accter (accter);
	    }

	  /* Put value in accretion array at desired offset. */

	  ffebld_constantarray_put
	    (array, ffedata_basictype_, ffedata_kindtype_,
	     offset, ffebld_constant_union (ffebld_conter (value)));
	  ffebit_count (ffebld_accter_bits (accter), offset, FALSE,
			ffedata_charexpected_,
			&actual);	/* How many FALSE? */
	  if (actual != (unsigned long int) ffedata_charexpected_)
	    {
	      ffebad_start (FFEBAD_DATA_MULTIPLE);
	      ffebad_here (0, ffelex_token_where_line (token),
			   ffelex_token_where_column (token));
	      ffebad_string (ffesymbol_text (ffedata_symbol_));
	      ffebad_finish ();
	    }
	  ffesymbol_set_accretes (ffedata_symbol_,
				  ffesymbol_accretes (ffedata_symbol_)
				  - actual);	/* Decrement # of values
						   actually accreted. */
	  ffebit_set (ffebld_accter_bits (accter), offset,
		      1, ffedata_charexpected_);
	  ffesymbol_signal_unreported (ffedata_symbol_);
	}

      /* If still accreting, adjust specs accordingly and return. */

      if (++ffedata_number_ < ffedata_expected_)
	{
	  ++ffedata_offset_;
	  return TRUE;
	}

      /* Else, if done accreting for this symbol, establish as initialized. */

      if ((value != NULL)
	  && (ffesymbol_accretes (ffedata_symbol_) == 0))
	{
	  ffesymbol_set_init (ffedata_symbol_, accter);
	  ffesymbol_set_accretion (ffedata_symbol_, NULL);
	  ffebit_kill (ffebld_accter_bits (ffesymbol_init (ffedata_symbol_)));
	  ffebld_set_op (ffesymbol_init (ffedata_symbol_), FFEBLD_opARRTER);
	  ffebld_set_arrter (ffesymbol_init (ffedata_symbol_),
			  ffebld_accter (ffesymbol_init (ffedata_symbol_)));
	  ffebld_arrter_set_size (ffesymbol_init (ffedata_symbol_),
				  ffedata_symbolsize_);
	  ffecom_notify_init_symbol (ffedata_symbol_);
	}
    }
  else if (value != NULL)
    {
      /* Simple, direct, one-shot assignment. */
      ffesymbol_set_init (ffedata_symbol_, value);
      ffecom_notify_init_symbol (ffedata_symbol_);
    }

  /* Call on advance function to get next target in list. */

  return ffedata_advance_ ();
}
