// // Values used by stack machine // #ifndef VALUE_H #define VALUE_H #include #include #include using std::string; using std::vector; class Value; // Predefinition class Label; // Predefinition class StdFuncDef; // Predefinition class InterpretatorException { public: char reason[128]; InterpretatorException() { reason[0] = 0; } InterpretatorException(const char* cause) { strncpy(reason, cause, 127); reason[127] = 0; } InterpretatorException(const string& cause) { strncpy(reason, cause.c_str(), 127); reason[127] = 0; } const char* what() const { return reason; } }; // Bits in value_type: const int VALUE_TYPE_INT = 1; const int VALUE_TYPE_DOUBLE = 2; const int VALUE_TYPE_STRING = 4; const int VALUE_TYPE_VARIABLE = 8; const int VALUE_TYPE_ARRAY = 16; const int VALUE_TYPE_ARRAY_ELEMENT = 32; const int VALUE_TYPE_REFERENCE = 64; const int VALUE_TYPE_FUNCTION = 128; const int VALUE_TYPE_STANDARD_FUNCTION = 256; extern Value value_none; class Value { public: int value_type; int64_t int_value; // For array element, it is an offset of element, double double_value; string string_value; // string constant, variable/function name vector array_value; vector* array_ptr; // Used for array elements, references, functions. // For reference type, it is // a pointer to Value. // For function, it is a pointer to label table Value(): value_type(0), // this in none int_value(0), double_value(0.0), string_value(), array_value(), array_ptr(0) {} Value(int n): value_type(VALUE_TYPE_INT), int_value(n), double_value(0.0), string_value(), array_value(), array_ptr(0) {} Value(int64_t n): value_type(VALUE_TYPE_INT), int_value(n), double_value(0.0), string_value(), array_value(), array_ptr(0) {} Value(double x): value_type(VALUE_TYPE_DOUBLE), int_value(0), double_value(x), string_value(), array_value(), array_ptr(0) {} Value(const char* str): value_type(VALUE_TYPE_STRING), int_value(0), double_value(0.0), string_value(str), array_value(), array_ptr(0) {} Value(const vector& array): value_type(VALUE_TYPE_ARRAY), int_value(0), double_value(0.0), string_value(), array_value(array), array_ptr(0) {} bool isNumber() const { return ( value_type == VALUE_TYPE_INT || value_type == VALUE_TYPE_DOUBLE ); } bool isInt() const { return (value_type == VALUE_TYPE_INT); } bool isDouble() const { return (value_type == VALUE_TYPE_DOUBLE); } bool isString() const { return ( value_type == VALUE_TYPE_STRING ); } bool isVariable() const { return ( value_type == VALUE_TYPE_VARIABLE ); } bool isArray() const { return ( value_type == VALUE_TYPE_ARRAY ); } bool isArrayElement() const { return ( value_type == VALUE_TYPE_ARRAY_ELEMENT ); } bool isReference() const { return ( value_type == VALUE_TYPE_REFERENCE ); } bool isFunction() const { return ( value_type == VALUE_TYPE_FUNCTION ); } bool isStandardFunction() const { return ( value_type == VALUE_TYPE_STANDARD_FUNCTION ); } bool isNone() const { return ( value_type == 0 ); } bool isLValue() const { return (isVariable() || isArrayElement()); } Value* reference() const { assert(isReference()); return reinterpret_cast(array_ptr); } void setReference(Value* v) { array_ptr = reinterpret_cast*>(v); } const Label* labelPtr() const { assert(isFunction()); return reinterpret_cast(array_ptr); } void setLabelPtr(const Label* l) { Label* ll = const_cast(l); array_ptr = reinterpret_cast*>(ll); } const StdFuncDef* stdFuncPtr() const { assert(isStandardFunction()); return reinterpret_cast(array_ptr); } void setStdFuncPtr(const StdFuncDef* f) { StdFuncDef* ff = const_cast(f); array_ptr = reinterpret_cast*>(ff); } static Value& none() { return value_none; } void convertToInt(Value& v) const; void convertToDouble(Value& v) const; void convertToString(Value& v) const; // Operations: static void add( const Value& v0, const Value& v1, Value& res ); static void sub( const Value& v0, const Value& v1, Value& res ); static void mul( const Value& v0, const Value& v1, Value& res ); static void div( const Value& v0, const Value& v1, Value& res ); static void mod( const Value& v0, const Value& v1, Value& res ); static void power( const Value& v0, const Value& v1, Value& res ); static void negate( const Value& v0, Value& res ); static void compare( const Value& v0, const Value& v1, Value& res ); static void array_append( Value& v0, const Value& v1 ); void print() const; void scan(); // Moved to interpreter void clear(); }; typedef Value* ValuePtr; #endif