Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * value.h
- */
- #ifndef VALUE_H_
- #define VALUE_H_
- #include <string>
- #include <iostream>
- #include "parsetree.h"
- using namespace std;
- extern void RuntimeError(int, string);
- // object holds boolean, integer, or string, and remembers which it holds
- class Value {
- bool bval;
- int ival;
- string sval;
- enum VT { isBool, isInt, isString, isTypeError, isIdent } type;
- public:
- Value() : bval(false), ival(0), type(isTypeError) {}
- Value(bool bval) : bval(bval), ival(0), type(isBool) {}
- Value(int ival) : bval(false), ival(ival), type(isInt) {}
- Value(string sval) : bval(false), ival(0), sval(sval), type(isString) {}
- // in the case of an error, I use the value to hold the error message
- Value(string sval, bool isError) : bval(false), ival(0), sval(sval), type(isTypeError) {}
- bool isBoolType() const { return type == VT::isBool; }
- bool isIdentType() const { return type == VT::isIdent; }
- bool isIntType() const { return type == VT::isInt; }
- bool isStringType() const { return type == VT::isString; }
- bool isError() const { return type == VT::isTypeError; }
- bool hasMessage() const { return isError() && sval.size() > 0; }
- bool isSameType(Value that) const { return this->type == that.type; }
- bool isTrue() const { return isBoolType() && bval; }
- bool getBoolean() const {
- if( !isBoolType() )
- throw "Not boolean valued";
- return bval;
- }
- int getInteger() const {
- if( !isIntType() )
- throw "Not integer valued";
- return ival;
- }
- string getString() const {
- if( !isStringType() )
- throw "Not string valued";
- return sval;
- }
- string getMessage() const {
- if( !hasMessage() )
- throw "No message";
- return sval;
- }
- friend ostream& operator<<(ostream& out, const Value& v) {
- if( v.type == VT::isBool ) out << (v.bval ? "True" : "False");
- else if( v.type == VT::isInt ) out << v.ival;
- else if( v.type == VT::isString ) out << v.sval;
- else if( v.sval.size() > 0 ) out << "RUNTIME ERROR " << v.sval;
- else out << "TYPE ERROR";
- return out;
- }
- Value operator+(const Value& that){
- if (this->type == VT::isInt and that.type == VT::isInt)
- {
- return Value(ival + that.ival);
- }
- if (this->type == VT::isString and that.type == VT::isString)
- {
- return Value(sval + that.sval);
- }
- else {
- RuntimeError(0, "Cannot add these two values");
- }
- return Value();
- }
- Value operator-(const Value& that){
- if (this->type == VT::isInt and that.type == VT::isInt)
- {
- return Value(ival - that.ival);
- }
- throw "ERROR";
- }
- Value operator*(const Value& that){
- if (this->type == VT::isString and that.type == VT::isInt) {
- string lVal = this->getString();
- int rVal = that.getInteger();
- char newStr[lVal.length() * rVal + 1];
- for (unsigned int i = 0; i < lVal.length() * rVal; i++)
- newStr[i] = lVal[i % lVal.length()];
- newStr[lVal.length() * rVal] = '\0';
- return Value(string(newStr));
- } else if (this->type == VT::isInt and that.type == VT::isString) {
- int lVal = this->getInteger();
- string rVal = that.getString();
- char newStr[rVal.length() * lVal + 1];
- for (unsigned int i = 0; i < rVal.length() * lVal; i++)
- newStr[i] = rVal[i % rVal.length()];
- newStr[rVal.length() * lVal] = '\0';
- return Value(string(newStr));
- } else if (this->type == VT::isInt and that.type == VT::isInt) {
- return Value(ival * that.ival);
- } else {
- RuntimeError(0, "Tried to multiply with invalid operands");
- }
- return Value();
- }
- Value operator/(const Value& that){
- if (this->type == VT::isInt and that.type == VT::isInt) {
- return Value(ival / that.ival);
- } else {
- RuntimeError(0, "Tried to divide with invalid operands");
- }
- return Value();
- }
- Value operator<(const Value& that){
- if (this->type == VT::isInt and that.type == VT::isInt){
- return Value(ival < that.ival);
- }
- throw "ERROR";
- }
- Value operator<=(const Value& that){
- if (this->type == VT::isInt and that.type == VT::isInt){
- return Value(ival <= that.ival);
- }
- throw "ERROR";
- }
- Value operator>(const Value& that){
- if (this->type == VT::isInt and that.type == VT::isInt){
- return Value(ival > that.ival);
- }
- throw "ERROR";
- }
- Value operator>=(const Value& that){
- if (this->type == VT::isInt and that.type == VT::isInt){
- return Value(ival >= that.ival);
- }
- throw "ERROR";
- }
- Value operator==(const Value& that){
- if (this->type == VT::isInt and that.type == VT::isInt){
- return Value(ival == that.ival);
- }
- throw "ERROR";
- }
- Value operator!=(const Value& v) {
- Value ans = this->operator==(v);
- ans.bval = !ans.bval;
- return ans;
- }
- };
- #endif /* VALUE_H_ */
Add Comment
Please, Sign In to add comment