
/*	Level 0 parsing		*/

#include <stdio.h>
#include "cc65.h"
#include "cclex.h"

int hie1();


/*
  parseinit()
*/
parseinit(tptr)
char * tptr;
{
  int count;
  int i;
  struct expent lval;
  struct hashent * p;
  struct hashent * q;
  char * str;
  int sz;

  switch (tptr[0])
    {
    case T_INT:
    case T_UINT:
    case T_CHAR:
    case T_UCHAR:
    case T_PTR:
      constexp(&lval);

/*      if (tptr[0] == T_CHAR) */
      if (char_t_p(tptr))
	bytepref();
      else
	wordpref();

/*      outconst(lval.e_flags, lval.e_const, tptr[0] == T_CHAR); */
      outconst(lval.e_flags, lval.e_const, char_t_p(tptr));
      break;
    case T_ARRAY:
      sz = decode(tptr + 1);
      if ((tptr[4] == T_CHAR) && (curtok == SCONST))
	{
	  str = &litq[curval];
	  count = strlen(str) + 1;
	  /*
	    outdat(count);
	    i = 0;
	    while (++i <= count) outbyte(*str++);
	    */
	  outbv(str, count);

	  litptr -= count;
	  gettok();
	}
      else
	{
	  needbrack(LCURLY);
	  count = 0;
	  while (curtok != RCURLY)
	    {
	      parseinit(tptr + 4);
	      ++count;
	      if (curtok != COMMA)
		break;
	      gettok();
	    }
	  needbrack(RCURLY);
	}
      if (sz == 0)
	{
	  encode(tptr + 1, count);
	}
      else if (count < sz)
	{
	  outzero((sz - count) * SizeOf(tptr + 4));
	}
      else if (count > sz)
	{
	  toomany();
	}
      break;
    default:
      if (tptr[0] & T_STRUCT)
	{
	  needbrack(LCURLY);

	  /* jrd hacked this */
#ifdef M6502
	  q = (struct hashent *) decode(tptr); /* old way */
#else
	  q = (struct hashent *) (((int) decode(tptr)) + (int) gblspace);
	  /* decode offset from glbspace*/
#endif

	  p = q->h_link;
	  while (curtok != RCURLY)
	    {
	      if (p == NULL)
		{
		  toomany();
		  return;
		}
	      parseinit(p->h_gtptr);
	      p = p->h_link;
	      if (curtok != COMMA)
		break;
	      gettok();
	    }
	  needbrack(RCURLY);
	  while (p != NULL)
	    {
	      outzero(SizeOf(p->h_gtptr));
	      p = p->h_link;
	    }
	}
#ifndef M6502
      else
	{
	  fprintf(stderr, "unknown type: %02x\n", tptr[0]);
	}
#endif
    }
}

outzero(n)
int n;
{
/*
    outdat(n);
    while (--n >= 0)
	{
	outbyte(0);
	}
*/
  ot("\t.blkb\t");
  outdec(n);
  nl();
}

constexp(lval)
struct expent * lval;
{
  expr(hie1, lval);
  if ((lval->e_flags & E_MCONST) == 0)
    {
      Need("constant expression");
    }
}

toomany()
{
  Error("too many initializers");
}
