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"); }
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"); }
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 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"); }