#ifndef COMDEFS_H #define COMDEFS_H /* comdefs.h XIDEK: Extensible Script Language Development Kit Common code. Copyright (c) 1996-2002 Parsifal Software. All Rights Reserved. For further information about this program or the AnaGram parser generator, please contact: Parsifal Software http://www.parsifalsoft.com info@parsifalsoft.com +1-800-879-2577, Voice/Fax +1-508-358-2564 P.O. Box 219 Wayland, MA 01778 USA */ #ifndef AG_PLACEMENT_DELETE_REQUIRED #if _MSC_VER >= 1200 || __INTEL_COMPILER #define AG_PLACEMENT_DELETE_REQUIRED 1 #endif #endif #include "agstr.h" #include "agdict.h" // Forward references for classes declared in this file: class Value; class Dataset; class ErrorMessage; class ErrorDiagnostic; class FileLocation; /*** Interpreter interface specifications************************************/ // Apply a script to a dataset Value interpret(const char *, Dataset &); // ErrorMessage class is used to report interpreter errors class ErrorMessage { const AgString msg; public: ErrorMessage(const AgString &m); const char *message() const; }; class ErrorDiagnostic { const AgString msg; public: ErrorDiagnostic(const AgString &m); const char *message() const; }; /*** Data Encapsulation Classes *********************************************/ template class ValueWrapper { Object object; friend class Value; void *operator new(size_t, void *p) {return p;} void operator delete(void *) {} #ifdef AG_PLACEMENT_DELETE_REQUIRED void operator delete(void *, void *) { } #endif ValueWrapper(const Object &o) : object(o) {} ValueWrapper(const ValueWrapper &o) : object(o.object) {} ~ValueWrapper() {} operator Object &() {return object;} }; // FileLocation class is used by parsers to track line and column numbers class FileLocation { public: const unsigned char *pointer; int line, column; FileLocation(const unsigned char *p = NULL, int l = 1, int c = 1) : pointer(p), line(l), column(c) {} }; /* The Value class is used for arithmetic in interpreters. It overrides all arithmetic operators. Integer arithmetic is performed using longs. All values are stored as doubles. */ class Value { protected: // Nested type definition enum Type { uninitType, integerType, realType, stringType, pointerType }; Type type; union { double value; Value *pointer; // Make sure there is enough space char stringSpace[sizeof(ValueWrapper)]; }; public: // Constructors Value(); Value(int x); Value(long x); Value(double x, Type t = realType); Value(const AgString &s); Value(Value *p); Value(const Value &); // Destructor ~Value(); // Error checking functions void assertInitialized() const; void assertInteger() const; void assertScalar() const; void assertString() const; void assertPointer() const; // Data access functions double getDouble() const {assertScalar(); return value;} long getLong() const {assertInteger(); return (long) value;} AgString &getString() const {assertString(); return *(AgString *) &value;} Value &deref(); AgString asString() const; AgString asLiteral() const; int isDefined() const {return type != uninitType;} int isTrue() const; int isFalse() const {return !isTrue();} // Type conversion functions Value &makeInteger(); // Force type to be integer Value &makeReal(); // Force type to be real // Miscellaneous functions Value &setValue(const Value &); int hash(int) const; Value idiv(const Value &divisor); Value rdiv(const Value &divisor); // Operator overrides const Value &operator = (const Value &); const Value &operator += (const Value &); const Value &operator -= (const Value &); const Value &operator *= (const Value &); const Value &operator /= (const Value &); const Value &operator %= (const Value &); const Value &operator &= (const Value &); const Value &operator |= (const Value &); const Value &operator ^= (const Value &); const Value &operator <<= (const Value &); const Value &operator >>= (const Value &); Value operator + (const Value &x) const {return Value(*this) += x;} Value operator - (const Value &x) const {return Value(*this) -= x;} Value operator * (const Value &x) const {return Value(*this) *= x;} Value operator / (const Value &x) const {return Value(*this) /= x;} Value operator % (const Value &x) const {return Value(*this) %= x;} Value operator & (const Value &x) const {return Value(*this) &= x;} Value operator | (const Value &x) const {return Value(*this) |= x;} Value operator ^ (const Value &x) const {return Value(*this) ^= x;} Value operator << (const Value &x) const {return Value(*this) <<= x;} Value operator >> (const Value &x) const {return Value(*this) >>= x;} // Unary operators Value operator -() const; Value operator !() const { return Value(isFalse()); } Value operator ~() const { assertInteger(); return Value(~(long) value); } // Comparison operators // All other inqualities are implemented in terms of the less than operator int operator < (const Value &v) const; int operator > (const Value &v) const { return v < *this; } int operator <= (const Value &v) const { return !(v < *this); } int operator >= (const Value &v) const { return !(*this < v); } int operator == (const Value &v) const; int operator != (const Value &v) const { return !(*this == v); } // Autoincrement, Autodecrement operators Value operator ++(); Value operator --(); Value operator ++(int); Value operator --(int); }; // Externally defined functions Value pow(const Value &, const Value &); inline int agABTHash(const Value &v, int startValue = 0) {return v.hash(startValue);} /* The Dataset class consists of a reference to a dictionary and an array of data values. The dictionary associates a unique integer with each distinct variable name. The integer is the index in the data array of the value of the named variable. Different scripts can operate on the same Dataset object. */ class Dataset { public: AgDictionary &dictionary; // Indexes variable names AgStack data; // Contains values of variables // Constructors Dataset(AgDictionary &d); Dataset(const Dataset &d); // Destructor ~Dataset() {} // Nothing to do // Get value Value &value(const AgString &n); // returns reference to value named by n int size() const {return dictionary.size();} // Operator overloads Value &operator [] (int x); }; /*** Support Classes ********************************************************/ // Function object definitions struct FunctionObject { void notDefined(); virtual Value oneArg(const Value &) {notDefined(); return Value();} virtual Value twoArgs(const Value &, const Value &) {notDefined(); return Value();} }; // Function table definitions struct FunctionDescriptor { const char *name; int argCount; FunctionObject *function; }; extern const FunctionDescriptor functionTable[]; int idFunction(const AgString &name, int argCount); Value callFunction(const AgString &name, AgStack &args); Value callFunction(int k, AgStack &args); // External functions // What was thought to be an octal number turns out to be decimal. // Undo the octal representation and make it decimal. long makeDecimal(long octal); #endif