Value.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. using System;
  2. namespace NTERA.Interpreter
  3. {
  4. public enum ValueType
  5. {
  6. Real,
  7. String
  8. }
  9. public struct Value
  10. {
  11. public static readonly Value Zero = new Value(0);
  12. public ValueType Type { get; set; }
  13. public double Real { get; set; }
  14. public string String { get; set; }
  15. public Value(double real) : this()
  16. {
  17. Type = ValueType.Real;
  18. Real = real;
  19. }
  20. public Value(string str)
  21. : this()
  22. {
  23. Type = ValueType.String;
  24. String = str;
  25. }
  26. public Value Convert(ValueType type)
  27. {
  28. if (Type != type)
  29. {
  30. switch (type)
  31. {
  32. case ValueType.Real:
  33. Real = double.Parse(String);
  34. Type = ValueType.Real;
  35. break;
  36. case ValueType.String:
  37. String = Real.ToString();
  38. Type = ValueType.String;
  39. break;
  40. }
  41. }
  42. return this;
  43. }
  44. public Value BinOp(Value b, Token tok)
  45. {
  46. Value a = this;
  47. if (a.Type != b.Type)
  48. {
  49. if (a.Type > b.Type)
  50. b = b.Convert(a.Type);
  51. else
  52. a = a.Convert(b.Type);
  53. }
  54. if (tok == Token.Plus)
  55. {
  56. if (a.Type == ValueType.Real)
  57. return new Value(a.Real + b.Real);
  58. else
  59. return new Value(a.String + b.String);
  60. }
  61. else if(tok == Token.Equal)
  62. {
  63. if (a.Type == ValueType.Real)
  64. return new Value(a.Real == b.Real ? 1 : 0);
  65. else
  66. return new Value(a.String == b.String ? 1 : 0);
  67. }
  68. else if(tok == Token.NotEqual)
  69. {
  70. if (a.Type == ValueType.Real)
  71. return new Value(a.Real == b.Real ? 0 : 1);
  72. else
  73. return new Value(a.String == b.String ? 0 : 1);
  74. }
  75. else
  76. {
  77. if (a.Type == ValueType.String)
  78. throw new Exception("Cannot do binop on strings(except +).");
  79. switch (tok)
  80. {
  81. case Token.Minus: return new Value(a.Real - b.Real);
  82. case Token.Asterisk: return new Value(a.Real * b.Real);
  83. case Token.Slash: return new Value(a.Real / b.Real);
  84. case Token.Caret: return new Value(Math.Pow(a.Real, b.Real));
  85. case Token.Less: return new Value(a.Real < b.Real ? 1 : 0);
  86. case Token.More: return new Value(a.Real > b.Real ? 1 : 0);
  87. case Token.LessEqual: return new Value(a.Real <= b.Real ? 1 : 0);
  88. case Token.MoreEqual: return new Value(a.Real >= b.Real ? 1 : 0);
  89. }
  90. }
  91. throw new Exception("Unkown binop");
  92. }
  93. public override string ToString()
  94. {
  95. if (Type == ValueType.Real)
  96. return Real.ToString();
  97. return String;
  98. }
  99. }
  100. }