/*
  Var
*/

#include "var.h"

#include "head.h"
#include "jump.h"
#include "mem.h"
#include "pc.h"
#include "stack.h"

static long_word address(word var)
{
  return hd_global() + (((long_word) var - LOCAL_VARS) << 1);
}

void get_var(word var)
{
  store(load_var(var));
}

word load_var(word var)
{
  if(var == 0)
    return stk_get_top();
  else if(var < LOCAL_VARS)
    return stk_get_var(var);
  else
    return rd_word_addr(address(var));
}

void put_var(word var, word value)
{
  if(var == 0)
    stk_set_top(value);
  else if(var < LOCAL_VARS)
    stk_set_var(var, value);
  else
    wr_word_addr(address(var), value);
}

void push(word value)
{
  stk_push(value);
}

void pop(word var)
{
  put_var(var, stk_pop());
}

void inc_var(word var)
{
  put_var(var, load_var(var) + 1);
}

void dec_var(word var)
{
  put_var(var, load_var(var) - 1);
}

void inc_chk(word var, word threshold)
{
  word value = load_var(var) + 1;
  put_var(var, value);
  ret_value((signed_word) value > (signed_word) threshold);
}

void dec_chk(word var, word threshold)
{
  word value = load_var(var) - 1;
  put_var(var, value);
  ret_value((signed_word) value < (signed_word) threshold);
}

word load(int mode)
{
  if(mode <= 0)
  {
    return next_word();
  }
  else if(mode == 1)
  {
    return next_byte();
  }
  else
  {
    word var = next_byte();
    if(var == 0)
      return stk_pop();
    else
      return load_var(var);
  }
}

void store(word value)
{
  word var = next_byte();
  if(var == 0)
    stk_push(value);
  else
    put_var(var, value);
}
