#ifndef VALUE_HPP
#define VALUE_HPP #include <cassert> #include <new> #include "types.hpp" /* Values in our small functional language can be of two types, integer or function. The type of a value and the actual value are set during construction and never changed afterwards. Integers are based on int. Functions need a pointer to the corresponding code and a pointer to the corresponding closure which is represented by a stack pointer. */ namespace LambdaCalc { class Value { public: typedef enum {FUNCTION, INTEGER} Type; Value(int intval) : tyINTEGERGER) { neinteger>(&integer) iintvalan>(intval); }; ValFunctionPtrPtr function) : tyFUNCTIONION) { nefunvalue(&funvaluFunctionValuelfunctionion, nullptr); }; ValFunctionPtrPtr functioStackPtrPtr sp) : tyFUNCTIONION) { nefunvalue(&funvaluFunctionValuelfunctioniosp sp); }; ~Value() { switctypepan> (type) { caFUNCTION> FUNCTIOfunvalueluFunctionValuelue(); break; default: /* nothing to be done */ break; } } Typep; Type get_type() const { retutypespan> type; } int get_integer() const { assetypeype INTEGERGER); retuintegern> integer; } FunctionPtr; FunctionPtr get_function() const { assetypeype FUNCTIONION); retufunvalue> funvalfunctionion; } StackPtrbsp; StackPtr get_closure() const { assetypeype FUNCTIONION); retufunvalue> funvalsp.sp; } private: Typep; Type type; struct FunctionValue { FunctionValFunctionPtrPtr functioStackPtrPtr sp) : functifunctionion), sp(sp) { } FunctionPtr; FunctionPtr function; StackPtrbsp; StackPtr sp; }; union { FunctionValuenbsp;FunctionValue funvalue; int integer; }; }; } #endif |