/* SI 413 Fall 2011
* value.hpp
* C++ header file for the Value class.
*/
#ifndef VALUE_HPP
#define VALUE_HPP
#include <iostream>
#include <cstdlib>
using namespace std;
// Forward declaration of the Lambda AST class so we can have
// pointers to Lambda objects.
class Lambda;
// Forward declaration of the Frame class
class Frame;
/* This struct represents a closure: function plus referencing environment */
struct Closure {
Lambda* function;
Frame* environment;
// I am overloading the "==" operator so we can do comparison.
bool operator== (const Closure& other)
{ return function == other.function && environment == other.environment; }
};
// This gives the type of what's stored in the Value object.
// NONE_T means nothing has been set yet.
enum VType {
NUM_T, BOOL_T, FUN_T, NONE_T
};
class Value {
private:
// The value is either an int, a bool, or a Closure.
union {
int num;
bool tf;
Closure func;
} val;
VType type;
public:
Value() :type(NONE_T) { }
Value(int n) :type(NUM_T) { val.num = n; }
Value(bool b) :type(BOOL_T) { val.tf = b; }
Value(Closure c) :type(FUN_T) { val.func = c; }
VType getType() { return type; }
void setType(VType t) { type = t; }
int num() { return val.num; }
bool tf() { return val.tf; }
Closure func() { return val.func; }
/* Writes a representation of this Value object to the
* named output stream, according to the stored type.
*/
void writeTo(ostream& out) {
switch(type) {
case NUM_T: out << val.num; break;
case BOOL_T: out << (val.tf ? "true" : "false"); break;
case FUN_T: out << "closure"; break;
case NONE_T: cout << "UNSET"; break;
}
}
/* This function makes equality testing work using the == operator.
* So for instance if we have
* Value v1, v2;
* then we can write
* v1 == v2
* and get a bool back only if they have the same type and value.
* Note that != is NOT implemented.
*/
bool operator==(const Value& other) {
switch(type) {
case NUM_T: return val.num == other.val.num;
case BOOL_T: return val.tf == other.val.tf;
case FUN_T: return val.func == other.val.func;
case NONE_T: return true;
}
}
};
#endif // VALUE_HPP