// © Copyright1995, Joseph Bergin.  All rights reserved. 

#ifndef __CPU__
#define __CPU__

#include "Stacks.h"
#include "Dictionary.h"
#include "Boolean.h"
#include <iostream.h>

//	CPU defines a stack oriented simulated cpu.  Variables have names that are a 
//	single char.  Variables must be declared before they can be used. 
//	All operations are done on the run time stack.  We may push an integer literal
// 	or the current value of a variable.  We may pop a value to a variable.
//	The arithmetic operations always pop the stack enough times to get the required
//	number of operands.  The values are used in the computation.  Note that the first 
//	value popped is the rightmost operand for the operation. Thus
//		aCpu.push(3);
//		aCpu.push(5);
//		aCpu.sub();
//	will leave -2 at the top of the stack and the 3 and 5 will have been previously 
//	popped, so will no longer be in the stack.  
//	The machine will halt on stack errors or on encountering an undeclared variable.
//	Operations pos and zero may be used in conditional jumps such as
//		if(aCpu.pos()) goto end;
//		. . .
//		end:
//		. . .
//	This may be used to program conditionals and loops.  
  
class CPU
{	public:
		CPU();
		void declare(unsigned int);// declare a variable // initialized to zero
		void pushv(unsigned int);	// push the current value of a variable
		void pushi(int);				// push a literal
		void pop(unsigned int);		// pop a value to a declared variable
		void add();		// add two top values(popping) and push the result
		void sub();		// top value is RIGHT operand
		void mult();
		void div();		// integer division (top value is RIGHT operand)
		void negate();	// negate the top of the stack (in place)
		void output();	// copy top of run time stack to output
		void input();	// push a value from the input
		void toss();	// discard top of run time stack
		void swap();	// swap two top values on run time stack
		void dup();		// duplicate top of run time stack
		Boolean pos();		// true if top of stack is positive
		Boolean zero();		// true if top of stack is zero
		void outputAscii();	// Interpret top of stack as ascii char and output it
		void inputAscii();  // Read in an ascii char and push it.  
		void halt();		// Halts your program (with a message).
	private:
		Dictionary<unsigned int, int> _storage;
		Stack<int> _runStack;
};

#endif
