
/*
   Statement parsing, part 2
*/


#include <stdio.h>
#include "cc65.h"
#include "cclex.h"

struct swent
{
  int sw_const;
  int sw_lab;
};

/*
   Handle 'switch' statement here
*/
doswitch()
{
int dlabel;		/* for default */
int lab;		/* exit label */
int label;		/* label for case */
int lcase;		/* label for compares */
struct expent lval;
struct swent * p;
struct swent * q;
struct swent swtab[100];

  gettok();
  dlabel = 0;			/* init */
  lab = getlabel();		/* get exit */
  p = swtab;
  addwhile(oursp, 0, lab, 0, 0);
  needbrack(LPAREN);
  expression();
  needbrack(RPAREN);
  /*
   * result of expr is in P
   */
  needbrack(LCURLY);
  jump(lcase = getlabel());
  while (curtok != RCURLY)
    {
      if ((curtok == CASE) || (curtok == DEFAULT))
	{
	  label = getlabel();
	  do
	    {
	      if (curtok == CASE)
	        {
	          gettok();
		  constexp(&lval);
		  p->sw_const = lval.e_const;
		  p->sw_lab = label;
		  ++p;
		}
	      else
		{
		  gettok();
		  dlabel = label;
	  	}
	      needcol();
	    } while ((curtok == CASE) || (curtok == DEFAULT));
          outcdf(label);
	}

    if (curtok != RCURLY)
      statement();
  }

 /* end of case */

  gettok();
  jump(lab);
  outcdf(lcase);
  casejump();
  q = swtab;
  while (q != p)
    {
      wordpref();			/* want word constants */
      outlab(q->sw_lab);		/* output labl to jump to */
      outchar(',');
      outdecnl(q->sw_const);	/* output the corresponding value */
      ++q;
    }

  wordpref();
  outdecnl(0);		/* terminate list */

  if (dlabel)
    jump(dlabel);
  outcdf(lab);
  delwhile();
}

/*
   Handle 'for' statement here
*/
dofor()
{
int loop;
int lab;
int linc;
int lstat;

  gettok();
  loop = getlabel();
  lab = getlabel();
  linc = getlabel();
  lstat = getlabel();
  addwhile(oursp, loop, lab, linc, lstat);
  needbrack(LPAREN);
  if (curtok != SEMI)
    {				/* exp1 */
      expression();
    }
  ns();
  outcdf(loop);
  if (curtok != SEMI)
    {				/* exp2 */
      expression();
      falsejump(lab, 0);
    }
  ns();
  jump(lstat);
  outcdf(linc);
  if (curtok != RPAREN)
    {				/* exp3 */
      expression();
    }
  needbrack(RPAREN);
  jump(loop);
  outcdf(lstat);
  statement();
  jump(linc);
  outcdf(lab);
  delwhile();
}
