// joycub - an interpeter for the programming language Joy
// 
// (c) 2004-2006 Sergey Zubkov 
// $Id: builtins_shufflers.cc,v 1.2 2006/02/27 18:44:01 cubbi Exp $
#include <vector>
#include <sstream>
#include "program.h"
#include "builtins.h"
#include "exceptions.h"
#include "int.h"
#include "float.h"
#include "set.h"
#include "char.h"
#include "string.h"
#include "list.h"
#include "bool.h"

static char RCSID[] ="$Id: builtins_shufflers.cc,v 1.2 2006/02/27 18:44:01 cubbi Exp $";

// Identity function, does nothing.
// Any program of the form  P id Q  is equivalent to just  P Q.
void op_id(JC_Stack & STACK) {
	// Do nothing
}

// OPERATOR
// pop      :   X  ->
// Removes X from top of the stack.
void op_pop(JC_Stack & STACK) {
	STACK.assert_depth(1,"pop");
	delete STACK.pop();
}

// OPERATOR
// swap      :   X Y  ->   Y X
// Interchanges X and Y on top of the stack.
void op_swap(JC_Stack & STACK) {
	STACK.assert_depth(2,"swap");
	int i = STACK.size()-1; // last element's index
	JC_objref* ref_x = STACK[i-1];
	JC_objref* ref_y = STACK[i];
	STACK[i-1]=ref_y;
	STACK[i]  =ref_x;
}
// OPERATOR
// rollup      :  X Y Z  ->  Z X Y
// Moves X and Y up, moves Z down
void op_rollup(JC_Stack & STACK) {
	STACK.assert_depth(3,"rollup");
	int i = STACK.size()-1; // last element's index
	JC_objref* ref_x = STACK[i-2];
	JC_objref* ref_y = STACK[i-1];
	JC_objref* ref_z = STACK[i];
	STACK[i-2]=ref_z;
	STACK[i-1]=ref_x;
	STACK[i]  =ref_y;
}
// OPERATOR
// rolldown      :  X Y Z  ->  Y Z X
// Moves Y and Z down, moves X up
void op_rolldown(JC_Stack & STACK) {
	STACK.assert_depth(3,"rolldown");
	int i = STACK.size()-1; // last element's index
	JC_objref* ref_x = STACK[i-2];
	JC_objref* ref_y = STACK[i-1];
	JC_objref* ref_z = STACK[i];
	STACK[i-2]=ref_y;
	STACK[i-1]=ref_z;
	STACK[i]  =ref_x;
}
// OPERATOR
// rotate      :  X Y Z  ->  Z Y X
// Interchanges X and Z
void op_rotate(JC_Stack & STACK) {
	STACK.assert_depth(3,"rotate");
	int i = STACK.size()-1; // last element's index
	JC_objref* ref_x = STACK[i-2];
	JC_objref* ref_z = STACK[i];
	STACK[i-2]=ref_z;
	STACK[i]  =ref_x;
}

// OPERATOR
// dup      :   X  ->   X X
// Pushes an extra copy of X onto stack.
void op_dup(JC_Stack & STACK) {
	STACK.assert_depth(1,"dup");
	STACK.push_back(new JC_objref(*STACK.back()));
}

