#include "forth.h"
/* Branching. */

/* In the following branching primitives, remember that
 * address_interpreter wants to increment pc too, so compensate when
 * generating branch addresses.
 */

PRIMITIVE ("branch", Fbranch, Sbranch, NON_IMMEDIATE, ( n -- ) )
{
  /* Branch unconditionally to the address in the next PF. */
  pc = (funcptr **) (*(++pc));
}


PRIMITIVE ("beq", Fbeq, Sbeq, NON_IMMEDIATE, ( n1 n2 -- ) )
{
  /* Branch If Eq. */

  if (POP == POP)
    {
      /* Jump to the address stored in the next PF. */
      pc = (funcptr **) (*(++pc));
    }
  else
    {
      /* Ignore the address stored in the next PF. */ 
      ++pc;
    }
}


PRIMITIVE ("bze", Fbze, Sbze, NON_IMMEDIATE, ( n -- ) )
{
  /* Branch if Zero. */

  if (POP == 0)
    {
      /* Jump to the address stored in the next PF. */
      pc = (funcptr **) (*(++pc));
    }
  else
    {
      /* Ignore the address stored in the next PF. */ 
      ++pc;
    }
}


PRIMITIVE ("bnz", Fbnz, Sbnz, NON_IMMEDIATE, ( n -- ) )
{
  /* Branch if NonZero. */

  if (POP)
    {
      /* Jump to the address stored in the next PF. */
      pc = (funcptr **) (*(++pc));
    }
  else
    {
      /* Ignore the address stored in the next PF. */ 
      ++pc;
    }
}


PRIMITIVE ("(", Frparen, Srparen, IMMEDIATE, ( -- ) )
{
  /* Eat input until a close paren.
   * Don't check for EOF -- it's up to the programmer to make sure the
   * close paren comes along.
   */
  char c;

  while (c = (char) getc (infile))
    {
      if (c == '(')
        Frparen ();
      else if (c == ')')
        return;
    }
}


PRIMITIVE ("\\", Fskip_line, Sskip_line, IMMEDIATE, ( -- ) )
{
  /* Eat input until a newline.
   * Don't check for EOF -- it's up to the programmer to make sure the
   * file doesn't end too soon.
   */
  while ((char) getc (infile) != '\n');
}


PRIMITIVE ("rbeq", Frbeq, Srbeq, NON_IMMEDIATE, ( -- ) )
{
  /* BEQ for the two numbers on the return stack.  Pops them if
   * equal.  Return stack effect is: ( n1 n2 -- n1 ) on no branch, (
   * (n1 n2 -- ) on branch.
   */

  /* Hmm.  Do nothing right now.  Think about this some more. */
}
