Value.cs 2.5 KB

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