public bool CanAssign(Value left, Value right) { // Check if the left value is a variable if (!(left is Variable)) { var msg = "Cannot assign a value to a non-variable type"; throw new InvalidOperationException(msg); } return true; }
public Value And(Value left, Value right) { // Convert values into literals left = left.AsLiteral(); right = right.AsLiteral(); if (IsTrue(left)) { return new Literal((Literal)right); } else { return new Literal((Literal)left); } }
public Value Add(Value left, Value right) { // Convert values into literals left = left.AsLiteral(); right = right.AsLiteral(); // Convert booleans into ints if (ValueType.BOOL == left.Type) { left = new Literal((bool)left.AsValue() ? 1 : 0); } if (ValueType.BOOL == right.Type) { right = new Literal((bool)right.AsValue() ? 1 : 0); } var lVal = left.AsValue(); var rVal = right.AsValue(); // String concatenations if (ValueType.STRING == left.Type && ValueType.STRING == right.Type) { var lStr = lVal.ToString(); var rStr = rVal.ToString(); return new Literal(lStr + rStr); } if (ValueType.STRING == left.Type || ValueType.STRING == right.Type) { string msg = "Cannot implicity convert to string"; throw new InvalidOperationException(msg); } // Arithmetic operations if (ValueType.INT == left.Type) { if (ValueType.INT == right.Type) { return new Literal((int)lVal + (int)rVal); } if (ValueType.FLOAT == right.Type) { return new Literal((int)lVal + (float)rVal); } } if (ValueType.FLOAT == left.Type) { if (ValueType.INT == right.Type) { return new Literal((float)lVal + (int)rVal); } if (ValueType.FLOAT == right.Type) { return new Literal((float)lVal + (float)rVal); } } // The calculator doesn't know how to handle this type throw new InvalidOperationException("Invalid value type"); }
/// <summary> /// Assigns the right-hand Value to the left-hand Value. /// </summary> /// <param name="left"> /// The left-hand value. /// </param> /// <param name="right"> /// The right-hand value /// </param> public void Assign(Value left, Value right) { if (m_calculator.CanAssign(left, right)) { var name = (left as Variable).Name; if (m_variables.ContainsKey(name)) { m_variables[name] = new Literal(right.AsLiteral()); } else { string msg = "Variable has not been instantiated"; throw new InvalidOperationException(msg); } } else { string msg = "Cannot assign value to variable"; throw new InvalidOperationException(msg); } }
public Value Xor(Value left, Value right) { // Convert values into literals left = left.AsLiteral(); right = right.AsLiteral(); if (ValueType.FLOAT == left.Type || ValueType.FLOAT == right.Type) { throw new InvalidOperationException("Invalid value type"); } if (ValueType.STRING == left.Type || ValueType.STRING == right.Type) { throw new InvalidOperationException("Invalid value type"); } if (ValueType.BOOL == left.Type && ValueType.BOOL == right.Type) { return new Literal(IsTrue(left) ^ IsTrue(right)); } // Convert booleans into ints if (ValueType.BOOL == left.Type) { left = new Literal((bool)left.AsValue() ? 1 : 0); } if (ValueType.BOOL == right.Type) { right = new Literal((bool)right.AsValue() ? 1 : 0); } // Perform bitwise xor on integers if (ValueType.INT == left.Type && ValueType.INT == right.Type) { return new Literal((int)left.AsValue() ^ (int)right.AsValue()); } // The calculator doesn't know how to handle this type throw new InvalidOperationException("Invalid value type"); }
public Value Not(Value value) { value = value.AsLiteral(); if (ValueType.BOOL == value.Type) { value = new Literal((bool)value.AsValue() ? 1 : 0); } var obj = value.AsValue(); if (ValueType.INT == value.Type) { return new Literal(0 == (int)obj); } if (ValueType.FLOAT == value.Type) { return new Literal(0.0f == (float)obj); } if (ValueType.STRING == value.Type) { return new Literal(0 == ((string)obj).Length); } // The calculator doesn't know how to handle this type throw new InvalidOperationException("Invalid value type"); }
public Value LessThan(Value left, Value right) { // Convert values into literals left = left.AsLiteral(); right = right.AsLiteral(); // Convert booleans into ints if (ValueType.BOOL == left.Type) { left = new Literal((bool)left.AsValue() ? 1 : 0); } if (ValueType.BOOL == right.Type) { right = new Literal((bool)right.AsValue() ? 1 : 0); } var lVal = left.AsValue(); var rVal = right.AsValue(); // String comparison if (ValueType.STRING == left.Type && ValueType.STRING == right.Type) { string lStr = (string)lVal; string rStr = (string)rVal; int max = lStr.Length < rStr.Length ? rStr.Length : lStr.Length; for (int i = 0; i < max; ++i) { if (i >= lStr.Length && lStr.Length != rStr.Length) { return new Literal(true); } if (i >= rStr.Length && lStr.Length != rStr.Length) { return new Literal(false); } if (lStr[i] < rStr[i]) { return new Literal(true); } else if (lStr[i] > rStr[i]) { return new Literal(false); } } // Strings are equal return new Literal(false); } // Arithmetic operations if (ValueType.INT == left.Type) { if (ValueType.INT == right.Type) { return new Literal((int)lVal < (int)rVal); } if (ValueType.FLOAT == right.Type) { return new Literal((int)lVal < (float)rVal); } } if (ValueType.FLOAT == left.Type) { if (ValueType.INT == right.Type) { return new Literal((float)lVal < (int)rVal); } if (ValueType.FLOAT == right.Type) { return new Literal((float)lVal < (float)rVal); } } // The calculator doesn't know how to handle this type throw new InvalidOperationException("Invalid value type"); }
public Value GreaterThan(Value left, Value right) { return m_calculator.GreaterThan(left, right); }
public Value Multiply(Value left, Value right) { return m_calculator.Multiply(left, right); }
public bool CanAssign(Value left, Value right) { return m_calculator.CanAssign(left, right); }
public Value And(Value left, Value right) { return m_calculator.And(left, right); }
public Value Xor(Value left, Value right) { return m_calculator.Xor(left, right); }
public Value Subtract(Value left, Value right) { return m_calculator.Subtract(left, right); }
public Value Not(Value value) { return m_calculator.Not(value); }
private bool IsTrue(Value value) { switch (value.Type) { case ValueType.BOOL: if (false == (bool)value.AsValue()) { return false; } break; case ValueType.INT: if (0 == (int)value.AsValue()) { return false; } break; case ValueType.FLOAT: if (0.0f == (float)value.AsValue()) { return false; } break; case ValueType.STRING: if ("" == (string)value.AsValue()) { return false; } break; default: throw new InvalidOperationException("Invalid value type"); } return true; }
public Value Divide(Value left, Value right) { return m_calculator.Divide(left, right); }
public Value EqualTo(Value left, Value right) { return m_calculator.EqualTo(left, right); }
public Value Divide(Value left, Value right) { // Convert values into literals left = left.AsLiteral(); right = right.AsLiteral(); // Convert booleans into ints if (ValueType.BOOL == left.Type) { left = new Literal((bool)left.AsValue() ? 1 : 0); } if (ValueType.BOOL == right.Type) { right = new Literal((bool)right.AsValue() ? 1 : 0); } var lVal = left.AsValue(); var rVal = right.AsValue(); // Arithmetic operations if (ValueType.INT == right.Type) { if (0 == (int)rVal) { throw new DivideByZeroException(); } } if (ValueType.FLOAT == right.Type) { if (0.0f == (float)rVal) { throw new DivideByZeroException(); } } if (ValueType.INT == left.Type) { if (ValueType.INT == right.Type) { return new Literal((int)lVal / (int)rVal); } if (ValueType.FLOAT == right.Type) { return new Literal((int)lVal / (float)rVal); } } if (ValueType.FLOAT == left.Type) { if (ValueType.INT == right.Type) { return new Literal((float)lVal / (int)rVal); } if (ValueType.FLOAT == right.Type) { return new Literal((float)lVal / (float)rVal); } } // The calculator doesn't know how to handle this type throw new InvalidOperationException("Invalid value type"); }
public Value LessThan(Value left, Value right) { return m_calculator.LessThan(left, right); }