Guest User

Untitled

a guest
Dec 5th, 2018
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.27 KB | None | 0 0
  1. /*
  2. * value.h
  3. */
  4.  
  5. #ifndef VALUE_H_
  6. #define VALUE_H_
  7.  
  8. #include <string>
  9. #include <iostream>
  10. #include "parsetree.h"
  11. using namespace std;
  12. extern void RuntimeError(int, string);
  13.  
  14. // object holds boolean, integer, or string, and remembers which it holds
  15. class Value {
  16. bool bval;
  17. int ival;
  18. string sval;
  19. enum VT { isBool, isInt, isString, isTypeError, isIdent } type;
  20.  
  21.  
  22. public:
  23. Value() : bval(false), ival(0), type(isTypeError) {}
  24. Value(bool bval) : bval(bval), ival(0), type(isBool) {}
  25. Value(int ival) : bval(false), ival(ival), type(isInt) {}
  26. Value(string sval) : bval(false), ival(0), sval(sval), type(isString) {}
  27.  
  28.  
  29.  
  30. // in the case of an error, I use the value to hold the error message
  31. Value(string sval, bool isError) : bval(false), ival(0), sval(sval), type(isTypeError) {}
  32.  
  33. bool isBoolType() const { return type == VT::isBool; }
  34. bool isIdentType() const { return type == VT::isIdent; }
  35. bool isIntType() const { return type == VT::isInt; }
  36. bool isStringType() const { return type == VT::isString; }
  37. bool isError() const { return type == VT::isTypeError; }
  38. bool hasMessage() const { return isError() && sval.size() > 0; }
  39. bool isSameType(Value that) const { return this->type == that.type; }
  40.  
  41. bool isTrue() const { return isBoolType() && bval; }
  42. bool getBoolean() const {
  43. if( !isBoolType() )
  44. throw "Not boolean valued";
  45. return bval;
  46. }
  47.  
  48. int getInteger() const {
  49. if( !isIntType() )
  50. throw "Not integer valued";
  51. return ival;
  52. }
  53.  
  54. string getString() const {
  55. if( !isStringType() )
  56. throw "Not string valued";
  57. return sval;
  58. }
  59.  
  60. string getMessage() const {
  61. if( !hasMessage() )
  62. throw "No message";
  63. return sval;
  64. }
  65.  
  66. friend ostream& operator<<(ostream& out, const Value& v) {
  67. if( v.type == VT::isBool ) out << (v.bval ? "True" : "False");
  68. else if( v.type == VT::isInt ) out << v.ival;
  69. else if( v.type == VT::isString ) out << v.sval;
  70. else if( v.sval.size() > 0 ) out << "RUNTIME ERROR " << v.sval;
  71. else out << "TYPE ERROR";
  72. return out;
  73. }
  74.  
  75. Value operator+(const Value& that){
  76. if (this->type == VT::isInt and that.type == VT::isInt)
  77. {
  78. return Value(ival + that.ival);
  79. }
  80.  
  81. if (this->type == VT::isString and that.type == VT::isString)
  82. {
  83. return Value(sval + that.sval);
  84. }
  85. else {
  86. RuntimeError(0, "Cannot add these two values");
  87. }
  88. return Value();
  89. }
  90. Value operator-(const Value& that){
  91. if (this->type == VT::isInt and that.type == VT::isInt)
  92. {
  93. return Value(ival - that.ival);
  94. }
  95. throw "ERROR";
  96. }
  97. Value operator*(const Value& that){
  98. if (this->type == VT::isString and that.type == VT::isInt) {
  99. string lVal = this->getString();
  100. int rVal = that.getInteger();
  101. char newStr[lVal.length() * rVal + 1];
  102. for (unsigned int i = 0; i < lVal.length() * rVal; i++)
  103. newStr[i] = lVal[i % lVal.length()];
  104. newStr[lVal.length() * rVal] = '\0';
  105. return Value(string(newStr));
  106. } else if (this->type == VT::isInt and that.type == VT::isString) {
  107. int lVal = this->getInteger();
  108. string rVal = that.getString();
  109. char newStr[rVal.length() * lVal + 1];
  110. for (unsigned int i = 0; i < rVal.length() * lVal; i++)
  111. newStr[i] = rVal[i % rVal.length()];
  112. newStr[rVal.length() * lVal] = '\0';
  113. return Value(string(newStr));
  114. } else if (this->type == VT::isInt and that.type == VT::isInt) {
  115. return Value(ival * that.ival);
  116. } else {
  117. RuntimeError(0, "Tried to multiply with invalid operands");
  118. }
  119. return Value();
  120. }
  121. Value operator/(const Value& that){
  122. if (this->type == VT::isInt and that.type == VT::isInt) {
  123. return Value(ival / that.ival);
  124. } else {
  125. RuntimeError(0, "Tried to divide with invalid operands");
  126. }
  127. return Value();
  128. }
  129. Value operator<(const Value& that){
  130. if (this->type == VT::isInt and that.type == VT::isInt){
  131. return Value(ival < that.ival);
  132. }
  133. throw "ERROR";
  134. }
  135. Value operator<=(const Value& that){
  136. if (this->type == VT::isInt and that.type == VT::isInt){
  137. return Value(ival <= that.ival);
  138. }
  139. throw "ERROR";
  140. }
  141. Value operator>(const Value& that){
  142. if (this->type == VT::isInt and that.type == VT::isInt){
  143. return Value(ival > that.ival);
  144. }
  145. throw "ERROR";
  146. }
  147. Value operator>=(const Value& that){
  148. if (this->type == VT::isInt and that.type == VT::isInt){
  149. return Value(ival >= that.ival);
  150. }
  151. throw "ERROR";
  152. }
  153. Value operator==(const Value& that){
  154. if (this->type == VT::isInt and that.type == VT::isInt){
  155. return Value(ival == that.ival);
  156. }
  157. throw "ERROR";
  158. }
  159. Value operator!=(const Value& v) {
  160. Value ans = this->operator==(v);
  161. ans.bval = !ans.bval;
  162. return ans;
  163. }
  164. };
  165.  
  166. #endif /* VALUE_H_ */
Add Comment
Please, Sign In to add comment