package edu.uchicago.cs.cspp51035;
/*
 * Created on Jun 26, 2005
 *
 */

/**
 * @author yuhu
 *
 */
import java.lang.*;
import java.util.Stack;


public abstract class Operator 
{
	public int		type; // 1: add; 2: minus; 3: time; 4: div

	public abstract void execute(Stack myStack);
	
}



class addOp extends Operator implements StackElement
{
	
	public addOp()
	{
		type = 1; 
	}
	
	public void execute(Stack myStack)
	{
		addOp			oneaddOp;
		minusOp			oneminusOp ;
		timeOp			onetimeOp ;
		divOp			onedivOp; 
		RPNInteger		oneInteger = new RPNInteger(0);
		RPNInteger		twoInteger = new RPNInteger(0);
		RPNDouble		oneDouble = new RPNDouble(0.0);
		RPNDouble		twoDouble = new RPNDouble(0.0);
		RPNFloat		oneFloat = new RPNFloat(0);
		RPNFloat		twoFloat = new RPNFloat(0);
		RPNLong			oneLong = new RPNLong(0);
		RPNLong			twoLong = new RPNLong(0) ;
		int				testsum; 
		int				grosstype; // 1: operator ; 2: operand
		int				operatortype, operandtype; 
		Object			oneOb; 
		String			oneInfo;
		String			operatorstring = "I am an Operator";
		String			operandstring = "I am an Operand";
		String			onetext;
		String			addex = "+";
		String			minusex ="-";
		String			mulex = "*";
		String			divex = "/";
		String			equalex = "=";
		int				oneintvalue;
		long			onelongvalue;
		float			onefloatvalue;
		double			onedoublevalue;
		int				firstnumbertype =0;
		int				secondnumbertype=0;
		
		
		
		// Get the first number
		oneOb = myStack.pop(); 
		oneInfo = ((StackElement)(oneOb)).getInfo();
		
		if (oneInfo.equalsIgnoreCase(operatorstring))
		{
			grosstype = 1; 
		}
		else 
		{
			if (oneInfo.equalsIgnoreCase(operandstring))
			{
				grosstype = 2; 
			}
			else
			{
				grosstype = -1;
			}
		}
		
		// If it is an operator, caculate it.
		if (grosstype == 1)
		{
			operatortype = ((Operator)(oneOb)).type;
			
			if (operatortype == 1)
			{
				oneaddOp = new addOp();
				oneaddOp.execute(myStack);
			}
			
			if (operatortype == 2)
			{
				oneminusOp = new minusOp();
				oneminusOp.execute(myStack);
			} 
			
			if (operatortype == 3)
			{
				onetimeOp = new timeOp();
				onetimeOp.execute(myStack);
			}
			
			if (operatortype == 4)
			{
				onedivOp = new divOp();
				onedivOp.execute(myStack);
			}

			//			 Pop out the first number
			oneOb = myStack.pop(); 
			oneInfo = ((StackElement)(oneOb)).getInfo(); // this must be an operand
			
		}
		
		
		operandtype = ((Operand)(oneOb)).type;
			
		if (operandtype == 1)
		{
			oneInteger = (RPNInteger)(oneOb);
			firstnumbertype = 1; 
		}
		
		if (operandtype == 2)
		{
			oneLong = (RPNLong)(oneOb);
			firstnumbertype = 2; 
		}
		
		if (operandtype == 3)
		{
			oneFloat = (RPNFloat)(oneOb);
			firstnumbertype = 3; 
		}
		
		if (operandtype == 4)
		{
			oneDouble = (RPNDouble)(oneOb);
			firstnumbertype = 4; 
		}
		

		//	Get the second number
		oneOb = myStack.pop(); 
		oneInfo = ((StackElement)(oneOb)).getInfo();
		
		if (oneInfo.equalsIgnoreCase(operatorstring))
		{
			grosstype = 1; 
		}
		else 
		{
			if (oneInfo.equalsIgnoreCase(operandstring))
			{
				grosstype = 2; 
			}
			else
			{
				grosstype = -1;
			}
		}
		
		// If it is an operator, caculate it.
		if (grosstype == 1)
		{
			operatortype = ((Operator)(oneOb)).type;
			
			if (operatortype == 1)
			{
				oneaddOp = new addOp();
				oneaddOp.execute(myStack);
			}
			
			if (operatortype == 2)
			{
				oneminusOp = new minusOp();
				oneminusOp.execute(myStack);
			} 
			
			if (operatortype == 3)
			{
				onetimeOp = new timeOp();
				onetimeOp.execute(myStack);
			}
			
			if (operatortype == 4)
			{
				onedivOp = new divOp();
				onedivOp.execute(myStack);
			}
			
			// Pop out the second number
			oneOb = myStack.pop(); 
			oneInfo = ((StackElement)(oneOb)).getInfo(); // this must be an operand
		
		}
	
	
		
		operandtype = ((Operand)(oneOb)).type;
			
		if (operandtype == 1)
		{
			twoInteger = (RPNInteger)(oneOb);
			secondnumbertype = 1; 
		}
		
		if (operandtype == 2)
		{
			twoLong = (RPNLong)(oneOb);
			secondnumbertype = 2; 
		}
		
		if (operandtype == 3)
		{
			twoFloat = (RPNFloat)(oneOb);
			secondnumbertype = 3; 
		}
		
		if (operandtype == 4)
		{
			twoDouble = (RPNDouble)(oneOb);
			secondnumbertype = 4; 
		}

		// Do caculation of itself
		if ((firstnumbertype == 1)&& (secondnumbertype == 1))
		{
			int			sum =0;
			
			sum = oneInteger.getValue().intValue(); 
			sum += twoInteger.getValue().intValue(); 
			
			oneInteger = new RPNInteger(sum);
			myStack.push(oneInteger);
			return; 
		}
		
		
		if ((firstnumbertype == 1)&& (secondnumbertype == 2))
		{
			long			sum =0;
			
			sum = oneInteger.getValue().longValue(); 
			sum += twoLong.getValue().longValue(); 
			
			oneLong = new RPNLong(sum);
			myStack.push(oneLong);
			return; 
		}
		
		if ((firstnumbertype == 2)&& (secondnumbertype == 1))
		{
			long			sum =0;
			
			sum = oneLong.getValue().longValue(); 
			sum += twoInteger.getValue().longValue(); 
			
			oneLong = new RPNLong(sum);
			myStack.push(oneLong);
			return; 
		}
		
		if ((firstnumbertype == 2)&& (secondnumbertype == 2))
		{
			long			sum =0;
			
			sum = oneLong.getValue().longValue(); 
			sum += twoLong.getValue().longValue(); 
			
			oneLong = new RPNLong(sum);
			myStack.push(oneLong);
			return; 
		}
		
		if ((firstnumbertype == 3)&& (secondnumbertype == 1))
		{
			float			sum =0;
			
			sum = oneFloat.getValue().floatValue(); 
			sum += twoInteger.getValue().floatValue(); 
			
			oneFloat = new RPNFloat(sum);
			myStack.push(oneFloat);
			return; 
		}
		
		if ((firstnumbertype == 3)&& (secondnumbertype == 2))
		{
			float			sum =0;
			
			sum = oneFloat.getValue().floatValue(); 
			sum += twoLong.getValue().floatValue(); 
			
			oneFloat = new RPNFloat(sum);
			myStack.push(oneFloat);
			return; 
		}
		
		if ((firstnumbertype == 1)&& (secondnumbertype == 3))
		{
			float			sum =0;
			
			sum = oneInteger.getValue().floatValue(); 
			sum += twoFloat.getValue().floatValue(); 
			
			oneFloat = new RPNFloat(sum);
			myStack.push(oneFloat);
			return; 
		}
		
		if ((firstnumbertype == 2)&& (secondnumbertype == 3))
		{
			float			sum =0;
			
			sum = oneLong.getValue().floatValue(); 
			sum += twoFloat.getValue().floatValue(); 
			
			oneFloat = new RPNFloat(sum);
			myStack.push(oneFloat);
			return; 
		}
		
		if ((firstnumbertype == 3)&& (secondnumbertype == 3))
		{
			float			sum =0;
			
			sum = oneFloat.getValue().floatValue(); 
			sum += twoFloat.getValue().floatValue(); 
			
			oneFloat = new RPNFloat(sum);
			myStack.push(oneFloat);
			return; 
		}
		
		
		if ((firstnumbertype == 4)&& (secondnumbertype == 1))
		{
			double			sum =0;
			
			sum = oneDouble.getValue().doubleValue(); 
			sum += twoInteger.getValue().doubleValue(); 
			
			oneDouble = new RPNDouble(sum);
			myStack.push(oneDouble);
			return; 
		}
		
		if ((firstnumbertype == 4)&& (secondnumbertype == 2))
		{
			double			sum =0;
			
			sum = oneDouble.getValue().doubleValue(); 
			sum += twoLong.getValue().doubleValue(); 
			
			oneDouble = new RPNDouble(sum);
			myStack.push(oneDouble);
			return; 
		}
		
		if ((firstnumbertype == 4)&& (secondnumbertype == 3))
		{
			double			sum =0;
			
			sum = oneDouble.getValue().doubleValue(); 
			sum += twoFloat.getValue().doubleValue(); 
			
			oneDouble = new RPNDouble(sum);
			myStack.push(oneDouble);
			return; 
		}
		
		if ((firstnumbertype == 1)&& (secondnumbertype == 4))
		{
			double			sum =0;
			
			sum = oneInteger.getValue().doubleValue(); 
			sum += twoDouble.getValue().doubleValue(); 
			
			oneDouble = new RPNDouble(sum);
			myStack.push(oneDouble);
			return; 
		}
		
		if ((firstnumbertype == 2)&& (secondnumbertype == 4))
		{
			double			sum =0;
			
			sum = oneLong.getValue().doubleValue(); 
			sum += twoDouble.getValue().doubleValue(); 
			
			oneDouble = new RPNDouble(sum);
			myStack.push(oneDouble);
			return; 
		}
		
		if ((firstnumbertype == 3)&& (secondnumbertype == 4))
		{
			double			sum =0;
			
			sum = oneFloat.getValue().doubleValue(); 
			sum += twoDouble.getValue().doubleValue(); 
			
			oneDouble = new RPNDouble(sum);
			myStack.push(oneDouble);
			return; 
		}
		
		if ((firstnumbertype == 4)&& (secondnumbertype == 4))
		{
			double			sum =0;
			
			sum = oneDouble.getValue().doubleValue(); 
			sum += twoDouble.getValue().doubleValue(); 
			
			oneDouble = new RPNDouble(sum);
			myStack.push(oneDouble);
			return; 
		}
		
		 
		
	
	
	}

	
	public String getInfo()
	{
		String		MyInfo = "I am an Operator";
		
		return MyInfo; 
	}

}


class minusOp extends Operator implements StackElement
{
	public minusOp()
	{
		type = 2; 
	}
	
	public void execute(Stack myStack)
	{
		addOp			oneaddOp;
		minusOp			oneminusOp ;
		timeOp			onetimeOp ;
		divOp			onedivOp; 
		RPNInteger		oneInteger = new RPNInteger(0);
		RPNInteger		twoInteger = new RPNInteger(0);
		RPNDouble		oneDouble = new RPNDouble(0.0);
		RPNDouble		twoDouble = new RPNDouble(0.0);
		RPNFloat		oneFloat = new RPNFloat(0);
		RPNFloat		twoFloat = new RPNFloat(0);
		RPNLong			oneLong = new RPNLong(0);
		RPNLong			twoLong = new RPNLong(0) ;
		int				testsum; 
		int				grosstype; // 1: operator ; 2: operand
		int				operatortype, operandtype; 
		Object			oneOb; 
		String			oneInfo;
		String			operatorstring = "I am an Operator";
		String			operandstring = "I am an Operand";
		String			onetext;
		String			addex = "+";
		String			minusex ="-";
		String			mulex = "*";
		String			divex = "/";
		String			equalex = "=";
		int				oneintvalue;
		long			onelongvalue;
		float			onefloatvalue;
		double			onedoublevalue;
		int				firstnumbertype =0;
		int				secondnumbertype=0;
		
		
		
		// Get the first number
		oneOb = myStack.pop(); 
		oneInfo = ((StackElement)(oneOb)).getInfo();
		
		if (oneInfo.equalsIgnoreCase(operatorstring))
		{
			grosstype = 1; 
		}
		else 
		{
			if (oneInfo.equalsIgnoreCase(operandstring))
			{
				grosstype = 2; 
			}
			else
			{
				grosstype = -1;
			}
		}
		
		// If it is an operator, caculate it.
		if (grosstype == 1)
		{
			operatortype = ((Operator)(oneOb)).type;
			
			if (operatortype == 1)
			{
				oneaddOp = new addOp();
				oneaddOp.execute(myStack);
			}
			
			if (operatortype == 2)
			{
				oneminusOp = new minusOp();
				oneminusOp.execute(myStack);
			} 
			
			if (operatortype == 3)
			{
				onetimeOp = new timeOp();
				onetimeOp.execute(myStack);
			}
			
			if (operatortype == 4)
			{
				onedivOp = new divOp();
				onedivOp.execute(myStack);
			}

			//			 Pop out the first number
			oneOb = myStack.pop(); 
			oneInfo = ((StackElement)(oneOb)).getInfo(); // this must be an operand
			
		}
		
		
		operandtype = ((Operand)(oneOb)).type;
			
		if (operandtype == 1)
		{
			oneInteger = (RPNInteger)(oneOb);
			firstnumbertype = 1; 
		}
		
		if (operandtype == 2)
		{
			oneLong = (RPNLong)(oneOb);
			firstnumbertype = 2; 
		}
		
		if (operandtype == 3)
		{
			oneFloat = (RPNFloat)(oneOb);
			firstnumbertype = 3; 
		}
		
		if (operandtype == 4)
		{
			oneDouble = (RPNDouble)(oneOb);
			firstnumbertype = 4; 
		}
		

		//	Get the second number
		oneOb = myStack.pop(); 
		oneInfo = ((StackElement)(oneOb)).getInfo();
		
		if (oneInfo.equalsIgnoreCase(operatorstring))
		{
			grosstype = 1; 
		}
		else 
		{
			if (oneInfo.equalsIgnoreCase(operandstring))
			{
				grosstype = 2; 
			}
			else
			{
				grosstype = -1;
			}
		}
		
		// If it is an operator, caculate it.
		if (grosstype == 1)
		{
			operatortype = ((Operator)(oneOb)).type;
			
			if (operatortype == 1)
			{
				oneaddOp = new addOp();
				oneaddOp.execute(myStack);
			}
			
			if (operatortype == 2)
			{
				oneminusOp = new minusOp();
				oneminusOp.execute(myStack);
			} 
			
			if (operatortype == 3)
			{
				onetimeOp = new timeOp();
				onetimeOp.execute(myStack);
			}
			
			if (operatortype == 4)
			{
				onedivOp = new divOp();
				onedivOp.execute(myStack);
			}
			
			// Pop out the second number
			oneOb = myStack.pop(); 
			oneInfo = ((StackElement)(oneOb)).getInfo(); // this must be an operand
		
		}
	
	
		
		operandtype = ((Operand)(oneOb)).type;
			
		if (operandtype == 1)
		{
			twoInteger = (RPNInteger)(oneOb);
			secondnumbertype = 1; 
		}
		
		if (operandtype == 2)
		{
			twoLong = (RPNLong)(oneOb);
			secondnumbertype = 2; 
		}
		
		if (operandtype == 3)
		{
			twoFloat = (RPNFloat)(oneOb);
			secondnumbertype = 3; 
		}
		
		if (operandtype == 4)
		{
			twoDouble = (RPNDouble)(oneOb);
			secondnumbertype = 4; 
		}

		// Do caculation of itself
		if ((firstnumbertype == 1)&& (secondnumbertype == 1))
		{
			int			sum =0;
			
			sum = -oneInteger.getValue().intValue(); 
			sum += twoInteger.getValue().intValue(); 
			
			oneInteger = new RPNInteger(sum);
			myStack.push(oneInteger);
			return; 
		}
		
		
		if ((firstnumbertype == 1)&& (secondnumbertype == 2))
		{
			long			sum =0;
			
			sum = -oneInteger.getValue().longValue(); 
			sum += twoLong.getValue().longValue(); 
			
			oneLong = new RPNLong(sum);
			myStack.push(oneLong);
			return; 
		}
		
		if ((firstnumbertype == 2)&& (secondnumbertype == 1))
		{
			long			sum =0;
			
			sum = -oneLong.getValue().longValue(); 
			sum += twoInteger.getValue().longValue(); 
			
			oneLong = new RPNLong(sum);
			myStack.push(oneLong);
			return; 
		}
		
		if ((firstnumbertype == 2)&& (secondnumbertype == 2))
		{
			long			sum =0;
			
			sum = -oneLong.getValue().longValue(); 
			sum += twoLong.getValue().longValue(); 
			
			oneLong = new RPNLong(sum);
			myStack.push(oneLong);
			return; 
		}
		
		if ((firstnumbertype == 3)&& (secondnumbertype == 1))
		{
			float			sum =0;
			
			sum =-oneFloat.getValue().floatValue(); 
			sum += twoInteger.getValue().floatValue(); 
			
			oneFloat = new RPNFloat(sum);
			myStack.push(oneFloat);
			return; 
		}
		
		if ((firstnumbertype == 3)&& (secondnumbertype == 2))
		{
			float			sum =0;
			
			sum = - oneFloat.getValue().floatValue(); 
			sum += twoLong.getValue().floatValue(); 
			
			oneFloat = new RPNFloat(sum);
			myStack.push(oneFloat);
			return; 
		}
		
		if ((firstnumbertype == 1)&& (secondnumbertype == 3))
		{
			float			sum =0;
			
			sum = - oneInteger.getValue().floatValue(); 
			sum += twoFloat.getValue().floatValue(); 
			
			oneFloat = new RPNFloat(sum);
			myStack.push(oneFloat);
			return; 
		}
		
		if ((firstnumbertype == 2)&& (secondnumbertype == 3))
		{
			float			sum =0;
			
			sum = - oneLong.getValue().floatValue(); 
			sum += twoFloat.getValue().floatValue(); 
			
			oneFloat = new RPNFloat(sum);
			myStack.push(oneFloat);
			return; 
		}
		
		if ((firstnumbertype == 3)&& (secondnumbertype == 3))
		{
			float			sum =0;
			
			sum = - oneFloat.getValue().floatValue(); 
			sum += twoFloat.getValue().floatValue(); 
			
			oneFloat = new RPNFloat(sum);
			myStack.push(oneFloat);
			return; 
		}
		
		
		if ((firstnumbertype == 4)&& (secondnumbertype == 1))
		{
			double			sum =0;
			
			sum = - oneDouble.getValue().doubleValue(); 
			sum += twoInteger.getValue().doubleValue(); 
			
			oneDouble = new RPNDouble(sum);
			myStack.push(oneDouble);
			return; 
		}
		
		if ((firstnumbertype == 4)&& (secondnumbertype == 2))
		{
			double			sum =0;
			
			sum = - oneDouble.getValue().doubleValue(); 
			sum += twoLong.getValue().doubleValue(); 
			
			oneDouble = new RPNDouble(sum);
			myStack.push(oneDouble);
			return; 
		}
		
		if ((firstnumbertype == 4)&& (secondnumbertype == 3))
		{
			double			sum =0;
			
			sum = - oneDouble.getValue().doubleValue(); 
			sum += twoFloat.getValue().doubleValue(); 
			
			oneDouble = new RPNDouble(sum);
			myStack.push(oneDouble);
			return; 
		}
		
		if ((firstnumbertype == 1)&& (secondnumbertype == 4))
		{
			double			sum =0;
			
			sum = - oneInteger.getValue().doubleValue(); 
			sum += twoDouble.getValue().doubleValue(); 
			
			oneDouble = new RPNDouble(sum);
			myStack.push(oneDouble);
			return; 
		}
		
		if ((firstnumbertype == 2)&& (secondnumbertype == 4))
		{
			double			sum =0;
			
			sum = - oneLong.getValue().doubleValue(); 
			sum += twoDouble.getValue().doubleValue(); 
			
			oneDouble = new RPNDouble(sum);
			myStack.push(oneDouble);
			return; 
		}
		
		if ((firstnumbertype == 3)&& (secondnumbertype == 4))
		{
			double			sum =0;
			
			sum = - oneFloat.getValue().doubleValue(); 
			sum += twoDouble.getValue().doubleValue(); 
			
			oneDouble = new RPNDouble(sum);
			myStack.push(oneDouble);
			return; 
		}
		
		if ((firstnumbertype == 4)&& (secondnumbertype == 4))
		{
			double			sum =0;
			
			sum = - oneDouble.getValue().doubleValue(); 
			sum += twoDouble.getValue().doubleValue(); 
			
			oneDouble = new RPNDouble(sum);
			myStack.push(oneDouble);
			return; 
		}
		
		 
		
	
	
	}
	
	public String getInfo()
	{
		String		MyInfo = "I am an Operator";
		
		return MyInfo; 
	}

}

class timeOp extends Operator implements StackElement
{
	public timeOp()
	{
		type = 3; 
	}
	
	public void execute(Stack myStack)
	{
		addOp			oneaddOp;
		minusOp			oneminusOp ;
		timeOp			onetimeOp ;
		divOp			onedivOp; 
		RPNInteger		oneInteger = new RPNInteger(0);
		RPNInteger		twoInteger = new RPNInteger(0);
		RPNDouble		oneDouble = new RPNDouble(0.0);
		RPNDouble		twoDouble = new RPNDouble(0.0);
		RPNFloat		oneFloat = new RPNFloat(0);
		RPNFloat		twoFloat = new RPNFloat(0);
		RPNLong			oneLong = new RPNLong(0);
		RPNLong			twoLong = new RPNLong(0) ;
		int				testsum; 
		int				grosstype; // 1: operator ; 2: operand
		int				operatortype, operandtype; 
		Object			oneOb; 
		String			oneInfo;
		String			operatorstring = "I am an Operator";
		String			operandstring = "I am an Operand";
		String			onetext;
		String			addex = "+";
		String			minusex ="-";
		String			mulex = "*";
		String			divex = "/";
		String			equalex = "=";
		int				oneintvalue;
		long			onelongvalue;
		float			onefloatvalue;
		double			onedoublevalue;
		int				firstnumbertype =0;
		int				secondnumbertype=0;
		
		
		
		// Get the first number
		oneOb = myStack.pop(); 
		oneInfo = ((StackElement)(oneOb)).getInfo();
		
		if (oneInfo.equalsIgnoreCase(operatorstring))
		{
			grosstype = 1; 
		}
		else 
		{
			if (oneInfo.equalsIgnoreCase(operandstring))
			{
				grosstype = 2; 
			}
			else
			{
				grosstype = -1;
			}
		}
		
		// If it is an operator, caculate it.
		if (grosstype == 1)
		{
			operatortype = ((Operator)(oneOb)).type;
			
			if (operatortype == 1)
			{
				oneaddOp = new addOp();
				oneaddOp.execute(myStack);
			}
			
			if (operatortype == 2)
			{
				oneminusOp = new minusOp();
				oneminusOp.execute(myStack);
			} 
			
			if (operatortype == 3)
			{
				onetimeOp = new timeOp();
				onetimeOp.execute(myStack);
			}
			
			if (operatortype == 4)
			{
				onedivOp = new divOp();
				onedivOp.execute(myStack);
			}

			//			 Pop out the first number
			oneOb = myStack.pop(); 
			oneInfo = ((StackElement)(oneOb)).getInfo(); // this must be an operand
			
		}
		
		
		operandtype = ((Operand)(oneOb)).type;
			
		if (operandtype == 1)
		{
			oneInteger = (RPNInteger)(oneOb);
			firstnumbertype = 1; 
		}
		
		if (operandtype == 2)
		{
			oneLong = (RPNLong)(oneOb);
			firstnumbertype = 2; 
		}
		
		if (operandtype == 3)
		{
			oneFloat = (RPNFloat)(oneOb);
			firstnumbertype = 3; 
		}
		
		if (operandtype == 4)
		{
			oneDouble = (RPNDouble)(oneOb);
			firstnumbertype = 4; 
		}
		

		//	Get the second number
		oneOb = myStack.pop(); 
		oneInfo = ((StackElement)(oneOb)).getInfo();
		
		if (oneInfo.equalsIgnoreCase(operatorstring))
		{
			grosstype = 1; 
		}
		else 
		{
			if (oneInfo.equalsIgnoreCase(operandstring))
			{
				grosstype = 2; 
			}
			else
			{
				grosstype = -1;
			}
		}
		
		// If it is an operator, caculate it.
		if (grosstype == 1)
		{
			operatortype = ((Operator)(oneOb)).type;
			
			if (operatortype == 1)
			{
				oneaddOp = new addOp();
				oneaddOp.execute(myStack);
			}
			
			if (operatortype == 2)
			{
				oneminusOp = new minusOp();
				oneminusOp.execute(myStack);
			} 
			
			if (operatortype == 3)
			{
				onetimeOp = new timeOp();
				onetimeOp.execute(myStack);
			}
			
			if (operatortype == 4)
			{
				onedivOp = new divOp();
				onedivOp.execute(myStack);
			}
			
			// Pop out the second number
			oneOb = myStack.pop(); 
			oneInfo = ((StackElement)(oneOb)).getInfo(); // this must be an operand
		
		}
	
	
		
		operandtype = ((Operand)(oneOb)).type;
			
		if (operandtype == 1)
		{
			twoInteger = (RPNInteger)(oneOb);
			secondnumbertype = 1; 
		}
		
		if (operandtype == 2)
		{
			twoLong = (RPNLong)(oneOb);
			secondnumbertype = 2; 
		}
		
		if (operandtype == 3)
		{
			twoFloat = (RPNFloat)(oneOb);
			secondnumbertype = 3; 
		}
		
		if (operandtype == 4)
		{
			twoDouble = (RPNDouble)(oneOb);
			secondnumbertype = 4; 
		}

		// Do caculation of itself
		if ((firstnumbertype == 1)&& (secondnumbertype == 1))
		{
			int			sum =0;
			
			sum = oneInteger.getValue().intValue(); 
			sum *= twoInteger.getValue().intValue(); 
			
			oneInteger = new RPNInteger(sum);
			myStack.push(oneInteger);
			return; 
		}
		
		
		if ((firstnumbertype == 1)&& (secondnumbertype == 2))
		{
			long			sum =0;
			
			sum = oneInteger.getValue().longValue(); 
			sum *= twoLong.getValue().longValue(); 
			
			oneLong = new RPNLong(sum);
			myStack.push(oneLong);
			return; 
		}
		
		if ((firstnumbertype == 2)&& (secondnumbertype == 1))
		{
			long			sum =0;
			
			sum = oneLong.getValue().longValue(); 
			sum *= twoInteger.getValue().longValue(); 
			
			oneLong = new RPNLong(sum);
			myStack.push(oneLong);
			return; 
		}
		
		if ((firstnumbertype == 2)&& (secondnumbertype == 2))
		{
			long			sum =0;
			
			sum = oneLong.getValue().longValue(); 
			sum *= twoLong.getValue().longValue(); 
			
			oneLong = new RPNLong(sum);
			myStack.push(oneLong);
			return; 
		}
		
		if ((firstnumbertype == 3)&& (secondnumbertype == 1))
		{
			float			sum =0;
			
			sum = oneFloat.getValue().floatValue(); 
			sum *= twoInteger.getValue().floatValue(); 
			
			oneFloat = new RPNFloat(sum);
			myStack.push(oneFloat);
			return; 
		}
		
		if ((firstnumbertype == 3)&& (secondnumbertype == 2))
		{
			float			sum =0;
			
			sum = oneFloat.getValue().floatValue(); 
			sum *= twoLong.getValue().floatValue(); 
			
			oneFloat = new RPNFloat(sum);
			myStack.push(oneFloat);
			return; 
		}
		
		if ((firstnumbertype == 1)&& (secondnumbertype == 3))
		{
			float			sum =0;
			
			sum = oneInteger.getValue().floatValue(); 
			sum *= twoFloat.getValue().floatValue(); 
			
			oneFloat = new RPNFloat(sum);
			myStack.push(oneFloat);
			return; 
		}
		
		if ((firstnumbertype == 2)&& (secondnumbertype == 3))
		{
			float			sum =0;
			
			sum = oneLong.getValue().floatValue(); 
			sum *= twoFloat.getValue().floatValue(); 
			
			oneFloat = new RPNFloat(sum);
			myStack.push(oneFloat);
			return; 
		}
		
		if ((firstnumbertype == 3)&& (secondnumbertype == 3))
		{
			float			sum =0;
			
			sum = oneFloat.getValue().floatValue(); 
			sum *= twoFloat.getValue().floatValue(); 
			
			oneFloat = new RPNFloat(sum);
			myStack.push(oneFloat);
			return; 
		}
		
		
		if ((firstnumbertype == 4)&& (secondnumbertype == 1))
		{
			double			sum =0;
			
			sum = oneDouble.getValue().doubleValue(); 
			sum *= twoInteger.getValue().doubleValue(); 
			
			oneDouble = new RPNDouble(sum);
			myStack.push(oneDouble);
			return; 
		}
		
		if ((firstnumbertype == 4)&& (secondnumbertype == 2))
		{
			double			sum =0;
			
			sum = oneDouble.getValue().doubleValue(); 
			sum *= twoLong.getValue().doubleValue(); 
			
			oneDouble = new RPNDouble(sum);
			myStack.push(oneDouble);
			return; 
		}
		
		if ((firstnumbertype == 4)&& (secondnumbertype == 3))
		{
			double			sum =0;
			
			sum = oneDouble.getValue().doubleValue(); 
			sum *= twoFloat.getValue().doubleValue(); 
			
			oneDouble = new RPNDouble(sum);
			myStack.push(oneDouble);
			return; 
		}
		
		if ((firstnumbertype == 1)&& (secondnumbertype == 4))
		{
			double			sum =0;
			
			sum = oneInteger.getValue().doubleValue(); 
			sum *= twoDouble.getValue().doubleValue(); 
			
			oneDouble = new RPNDouble(sum);
			myStack.push(oneDouble);
			return; 
		}
		
		if ((firstnumbertype == 2)&& (secondnumbertype == 4))
		{
			double			sum =0;
			
			sum = oneLong.getValue().doubleValue(); 
			sum *= twoDouble.getValue().doubleValue(); 
			
			oneDouble = new RPNDouble(sum);
			myStack.push(oneDouble);
			return; 
		}
		
		if ((firstnumbertype == 3)&& (secondnumbertype == 4))
		{
			double			sum =0;
			
			sum = oneFloat.getValue().doubleValue(); 
			sum *= twoDouble.getValue().doubleValue(); 
			
			oneDouble = new RPNDouble(sum);
			myStack.push(oneDouble);
			return; 
		}
		
		if ((firstnumbertype == 4)&& (secondnumbertype == 4))
		{
			double			sum =0;
			
			sum = oneDouble.getValue().doubleValue(); 
			sum *= twoDouble.getValue().doubleValue(); 
			
			oneDouble = new RPNDouble(sum);
			myStack.push(oneDouble);
			return; 
		}
		
		
	
	}
	
	public String getInfo()
	{
		String		MyInfo = "I am an Operator";
		
		return MyInfo; 
	}

}

class divOp extends Operator implements StackElement
{
	public divOp()
	{
		type = 4; 
	}
	
	public void execute(Stack myStack)
	{
		addOp			oneaddOp;
		minusOp			oneminusOp ;
		timeOp			onetimeOp ;
		divOp			onedivOp; 
		RPNInteger		oneInteger = new RPNInteger(0);
		RPNInteger		twoInteger = new RPNInteger(0);
		RPNDouble		oneDouble = new RPNDouble(0.0);
		RPNDouble		twoDouble = new RPNDouble(0.0);
		RPNFloat		oneFloat = new RPNFloat(0);
		RPNFloat		twoFloat = new RPNFloat(0);
		RPNLong			oneLong = new RPNLong(0);
		RPNLong			twoLong = new RPNLong(0) ;
		int				testsum; 
		int				grosstype; // 1: operator ; 2: operand
		int				operatortype, operandtype; 
		Object			oneOb; 
		String			oneInfo;
		String			operatorstring = "I am an Operator";
		String			operandstring = "I am an Operand";
		String			onetext;
		String			addex = "+";
		String			minusex ="-";
		String			mulex = "*";
		String			divex = "/";
		String			equalex = "=";
		int				oneintvalue;
		long			onelongvalue;
		float			onefloatvalue;
		double			onedoublevalue;
		int				firstnumbertype =0;
		int				secondnumbertype=0;
		
		
		
		// Get the first number
		oneOb = myStack.pop(); 
		oneInfo = ((StackElement)(oneOb)).getInfo();
		
		if (oneInfo.equalsIgnoreCase(operatorstring))
		{
			grosstype = 1; 
		}
		else 
		{
			if (oneInfo.equalsIgnoreCase(operandstring))
			{
				grosstype = 2; 
			}
			else
			{
				grosstype = -1;
			}
		}
		
		// If it is an operator, caculate it.
		if (grosstype == 1)
		{
			operatortype = ((Operator)(oneOb)).type;
			
			if (operatortype == 1)
			{
				oneaddOp = new addOp();
				oneaddOp.execute(myStack);
			}
			
			if (operatortype == 2)
			{
				oneminusOp = new minusOp();
				oneminusOp.execute(myStack);
			} 
			
			if (operatortype == 3)
			{
				onetimeOp = new timeOp();
				onetimeOp.execute(myStack);
			}
			
			if (operatortype == 4)
			{
				onedivOp = new divOp();
				onedivOp.execute(myStack);
			}

			//			 Pop out the first number
			oneOb = myStack.pop(); 
			oneInfo = ((StackElement)(oneOb)).getInfo(); // this must be an operand
			
		}
		
		
		operandtype = ((Operand)(oneOb)).type;
			
		if (operandtype == 1)
		{
			oneInteger = (RPNInteger)(oneOb);
			firstnumbertype = 1; 
		}
		
		if (operandtype == 2)
		{
			oneLong = (RPNLong)(oneOb);
			firstnumbertype = 2; 
		}
		
		if (operandtype == 3)
		{
			oneFloat = (RPNFloat)(oneOb);
			firstnumbertype = 3; 
		}
		
		if (operandtype == 4)
		{
			oneDouble = (RPNDouble)(oneOb);
			firstnumbertype = 4; 
		}
		

		//	Get the second number
		oneOb = myStack.pop(); 
		oneInfo = ((StackElement)(oneOb)).getInfo();
		
		if (oneInfo.equalsIgnoreCase(operatorstring))
		{
			grosstype = 1; 
		}
		else 
		{
			if (oneInfo.equalsIgnoreCase(operandstring))
			{
				grosstype = 2; 
			}
			else
			{
				grosstype = -1;
			}
		}
		
		// If it is an operator, caculate it.
		if (grosstype == 1)
		{
			operatortype = ((Operator)(oneOb)).type;
			
			if (operatortype == 1)
			{
				oneaddOp = new addOp();
				oneaddOp.execute(myStack);
			}
			
			if (operatortype == 2)
			{
				oneminusOp = new minusOp();
				oneminusOp.execute(myStack);
			} 
			
			if (operatortype == 3)
			{
				onetimeOp = new timeOp();
				onetimeOp.execute(myStack);
			}
			
			if (operatortype == 4)
			{
				onedivOp = new divOp();
				onedivOp.execute(myStack);
			}
			
			// Pop out the second number
			oneOb = myStack.pop(); 
			oneInfo = ((StackElement)(oneOb)).getInfo(); // this must be an operand
		
		}
	
	
		
		operandtype = ((Operand)(oneOb)).type;
			
		if (operandtype == 1)
		{
			twoInteger = (RPNInteger)(oneOb);
			secondnumbertype = 1; 
		}
		
		if (operandtype == 2)
		{
			twoLong = (RPNLong)(oneOb);
			secondnumbertype = 2; 
		}
		
		if (operandtype == 3)
		{
			twoFloat = (RPNFloat)(oneOb);
			secondnumbertype = 3; 
		}
		
		if (operandtype == 4)
		{
			twoDouble = (RPNDouble)(oneOb);
			secondnumbertype = 4; 
		}

		// Do caculation of itself
		if ((firstnumbertype == 1)&& (secondnumbertype == 1))
		{
			int			sum =0;
			
			sum = twoInteger.getValue().intValue();
			sum /= oneInteger.getValue().intValue(); 
			
			oneInteger = new RPNInteger(sum);
			myStack.push(oneInteger);
			return; 
		}
		
		
		if ((firstnumbertype == 1)&& (secondnumbertype == 2))
		{
			long			sum =0;
			
			sum = twoLong.getValue().longValue();
			sum /= oneInteger.getValue().longValue(); 
			 
			
			oneLong = new RPNLong(sum);
			myStack.push(oneLong);
			return; 
		}
		
		if ((firstnumbertype == 2)&& (secondnumbertype == 1))
		{
			long			sum =0;
			
			sum = twoInteger.getValue().longValue();
			sum /= oneLong.getValue().longValue(); 
			 
			
			oneLong = new RPNLong(sum);
			myStack.push(oneLong);
			return; 
		}
		
		if ((firstnumbertype == 2)&& (secondnumbertype == 2))
		{
			long			sum =0;
			
			sum = twoLong.getValue().longValue();
			sum /= oneLong.getValue().longValue(); 
			 
			
			oneLong = new RPNLong(sum);
			myStack.push(oneLong);
			return; 
		}
		
		if ((firstnumbertype == 3)&& (secondnumbertype == 1))
		{
			float			sum =0;
			
			sum = twoInteger.getValue().floatValue();
			sum /= oneFloat.getValue().floatValue(); 
			 
			
			oneFloat = new RPNFloat(sum);
			myStack.push(oneFloat);
			return; 
		}
		
		if ((firstnumbertype == 3)&& (secondnumbertype == 2))
		{
			float			sum =0;
			
			sum = twoLong.getValue().floatValue();
			sum /= oneFloat.getValue().floatValue(); 
			 
			
			oneFloat = new RPNFloat(sum);
			myStack.push(oneFloat);
			return; 
		}
		
		if ((firstnumbertype == 1)&& (secondnumbertype == 3))
		{
			float			sum =0;
			
			sum = twoFloat.getValue().floatValue();
			sum /= oneInteger.getValue().floatValue(); 
			 
			
			oneFloat = new RPNFloat(sum);
			myStack.push(oneFloat);
			return; 
		}
		
		if ((firstnumbertype == 2)&& (secondnumbertype == 3))
		{
			float			sum =0;
			
			sum = twoFloat.getValue().floatValue();
			sum /= oneLong.getValue().floatValue(); 
			 
			
			oneFloat = new RPNFloat(sum);
			myStack.push(oneFloat);
			return; 
		}
		
		if ((firstnumbertype == 3)&& (secondnumbertype == 3))
		{
			float			sum =0;
			
			sum = twoFloat.getValue().floatValue();
			sum /= oneFloat.getValue().floatValue(); 
			 
			
			oneFloat = new RPNFloat(sum);
			myStack.push(oneFloat);
			return; 
		}
		
		
		if ((firstnumbertype == 4)&& (secondnumbertype == 1))
		{
			double			sum =0;
			
			sum = twoInteger.getValue().doubleValue();
			sum /= oneDouble.getValue().doubleValue(); 
			 
			
			oneDouble = new RPNDouble(sum);
			myStack.push(oneDouble);
			return; 
		}
		
		if ((firstnumbertype == 4)&& (secondnumbertype == 2))
		{
			double			sum =0;
			
			sum = twoLong.getValue().doubleValue();
			sum /= oneDouble.getValue().doubleValue(); 
			 
			
			oneDouble = new RPNDouble(sum);
			myStack.push(oneDouble);
			return; 
		}
		
		if ((firstnumbertype == 4)&& (secondnumbertype == 3))
		{
			double			sum =0;
			
			sum = twoFloat.getValue().doubleValue();
			sum /= oneDouble.getValue().doubleValue(); 
			 
			
			oneDouble = new RPNDouble(sum);
			myStack.push(oneDouble);
			return; 
		}
		
		if ((firstnumbertype == 1)&& (secondnumbertype == 4))
		{
			double			sum =0;
			
			sum = twoDouble.getValue().doubleValue();
			sum /= oneInteger.getValue().doubleValue(); 
			 
			
			oneDouble = new RPNDouble(sum);
			myStack.push(oneDouble);
			return; 
		}
		
		if ((firstnumbertype == 2)&& (secondnumbertype == 4))
		{
			double			sum =0;
			
			sum = twoDouble.getValue().doubleValue();
			sum /= oneLong.getValue().doubleValue(); 
			 
			
			oneDouble = new RPNDouble(sum);
			myStack.push(oneDouble);
			return; 
		}
		
		if ((firstnumbertype == 3)&& (secondnumbertype == 4))
		{
			double			sum =0;
			
			sum = twoDouble.getValue().doubleValue();
			sum /= oneFloat.getValue().doubleValue(); 
			 
			
			oneDouble = new RPNDouble(sum);
			myStack.push(oneDouble);
			return; 
		}
		
		if ((firstnumbertype == 4)&& (secondnumbertype == 4))
		{
			double			sum =0;
			
			sum = twoDouble.getValue().doubleValue();
			sum /= oneDouble.getValue().doubleValue(); 
			 
			
			oneDouble = new RPNDouble(sum);
			myStack.push(oneDouble);
			return; 
		}
	
	
	}
	
	public String getInfo()
	{
		String		MyInfo = "I am an Operator";
		
		return MyInfo; 
	}

}
