/**
 * 
 */
package dspl.intermediate;

import dspl.intermediate.variable.Variable;

/**
 * Comparison expresses a binary comparison between two Variables. <br>
 * It is intended to be used with both branch and loop instructions.<br>
 * @author David
 *
 */
public class Comparison {
	/**
	 * Greater than
	 */
	public final static int CONDITION_GREATER = 0;
	
	/**
	 * Less than
	 */
	public final static int CONDITION_LESS    = 1; 
	
	/**
	 * Greater than or equal
	 */
	public final static int CONDITION_GE      = 2; 
	
	/**
	 * Less than or equal
	 */
	public final static int CONDITION_LE      = 3; 
	
	/**
	 * Equal to 
	 */
	public final static int CONDITION_EQUAL   = 4; 
	
	/**
	 * Not equal too
	 */
	public final static int CONDITION_NEQUAL  = 5; 
	
	/**
	 * First argument to be compared
	 */
	public Variable arg1; 
	
	/**
	 * Second arguement to compared to arg1
	 */
	public Variable arg2; 
	
	/**
	 * Perform if-instructions if arg1 *Condition* arg2 is true, 
	 * else perform else-instruction
	 * Must be one of the CONDITION_xxx values
	 */
	public int condition = -1 ; 
	
	
	public Comparison(Variable arg1, Variable arg2, int condition) {
		if (condition!=CONDITION_GREATER && condition!=CONDITION_LESS && condition!=CONDITION_GE && condition!=CONDITION_LE && condition!=CONDITION_EQUAL && condition!=CONDITION_NEQUAL) {
			throw new Error("invalid condition");
		}
		if (arg1==null) { 
			throw new Error("arg1 is null"); 
		}
		if (arg2==null) { 
			throw new Error("arg2 is null"); 
		}
		if (!arg1.isSameDataType(arg2)) { 
			throw new Error("arg1 and arg2 are not same type"); 
		}
		if (arg1.getDataType()==Variable.DATA_TYPE_STRING || arg2.getDataType()==Variable.DATA_TYPE_STRING) {
			throw new Error("comparison on strings not valid"); 
		}
		
		this.arg1 = arg1;
		this.arg2 = arg2;
		this.condition = condition; 
		
		//To keep the BranchInstructionProcessor simpler, will ensure that if one arg is a constant, it will appear as the second arguement
		if (arg1.isConstant() && !arg2.isConstant()) { 
			Variable temp = this.arg1;
			this.arg2 = this.arg1;
			this.arg1 = temp; 
		}
	}
}
