/*
**  This file is part of Zterp, and is
**  Copyright 1992, 1993 Charles Hannum
*/

#include <sys/types.h>
#include <stdio.h>
#include <assert.h>
#include "main.h"
#include "variable.h"
#include "jump.h"

uword
fetch (uword n)
{
  uword x;

  assert (n <= 2);

  switch (n)
  {
    case 0:
      x = get_word_pc ();
      break;
    case 1:
      x = get_byte_pc ();
      break;
    default:
      x = fetch_variable_pop (get_byte_pc ());
      break;
  }
  return x;
}

uword
fetch_variable_pop (uword n)
{
  if (!n)
    return *(--sp);
  else
    return fetch_variable_nopop (n);
}

uword
fetch_variable_nopop (uword n)
{
  if (!n)
    return *sp;
  else if (n < LOCAL_VARS)
    return fp[n];
  else
    return get_word (variable + (n << 1));
}


void
store_variable_push (uword x)
{
  uword n = get_byte_pc ();
  if (!n)
    *(sp++) = x;
  else
    store_variable_nopush (n, x);
}

void
store_variable_push_byte (zbyte x)
{
  store_variable_push ((uword) x);
}

void
store_variable_nopush (uword n, uword x)
{
  if (!n)
    *sp = x;
  else if (n < LOCAL_VARS)
    fp[n] = x;
  else
    set_word (variable + (n << 1), x);
}

void
store (n, b)
  uword n, b;
{
  store_variable_nopush (n, b);
}

void
push (x)
  uword x;
{
  *(sp++) = x;
}

void
pop_and_store (n)
  uword n;
{
  store_variable_nopush (n, *(--sp));
}

void
fetch_and_store (n)
  uword n;
{
  store_variable_push (fetch_variable_nopop (n));
}

void
pop_and_return ()
{
  ret (*(--sp));
}

void
pop ()
{
  if (zil_version < 5)
    --sp;
  else
    store_variable_push ((sizeof (stack) / sizeof (stack[0])) - (fp - stack));
}
