00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00049
00050
00051
00052
00053 #ifndef __NODE__
00054 #define __NODE__
00055
00056 #include <iostream>
00057 #include "symbol.hh"
00058
00059 using namespace std;
00060
00064 enum { kIntNode, kFloatNode, kSymNode, kPointerNode };
00065
00066
00070 class Node
00071 {
00072 int fType;
00073 union {
00074 int i;
00075 float f;
00076 Sym s;
00077 void* p;
00078 } fData;
00079
00080 public:
00081
00082 Node (int x) : fType(kIntNode) { fData.p = 0; fData.i = x; }
00083 Node (float x) : fType(kFloatNode) { fData.p = 0; fData.f = (float)x; }
00084 Node (const char* name) : fType(kSymNode) { fData.s = symbol(name); }
00085 Node (const string& name) : fType(kSymNode) { fData.s = symbol(name); }
00086 Node (Sym x) : fType(kSymNode) { fData.s = x; }
00087 Node (void* x) : fType(kPointerNode) { fData.p = x; }
00088
00089 Node (const Node& n) : fType(n.fType) { fData.p = n.fData.p; }
00090
00091
00092 bool operator == (const Node& n) const { return fType == n.fType && fData.p == n.fData.p; }
00093 bool operator != (const Node& n) const { return fType != n.fType || fData.p != n.fData.p; }
00094
00095
00096 int type() const { return fType; }
00097
00098 int getInt() const { return fData.i; }
00099 float getFloat() const { return fData.f; }
00100 Sym getSym() const { return fData.s; }
00101 void* getPointer() const { return fData.p; }
00102
00103
00104 operator int() const { return (fType == kIntNode) ? fData.i : (fType == kFloatNode) ? int(fData.f) : 0 ; }
00105 operator float() const { return (fType == kIntNode) ? float(fData.i) : (fType == kFloatNode) ? fData.f : 0.0f ; }
00106
00107 ostream& print (ostream& fout) const;
00108 };
00109
00110
00111 inline ostream& operator << (ostream& s, const Node& n) { return n.print(s); }
00112
00113
00114
00115
00116
00117
00118
00119
00120 inline bool isInt (const Node& n)
00121 {
00122 return (n.type() == kIntNode);
00123 }
00124
00125 inline bool isInt (const Node& n, int* x)
00126 {
00127 if (n.type() == kIntNode) {
00128 *x = n.getInt();
00129 return true;
00130 } else {
00131 return false;
00132 }
00133 }
00134
00135
00136
00137 inline bool isFloat (const Node& n)
00138 {
00139 return (n.type() == kFloatNode);
00140 }
00141
00142 inline bool isFloat (const Node& n, float* x)
00143 {
00144 if (n.type() == kFloatNode) {
00145 *x = n.getFloat();
00146 return true;
00147 } else {
00148 return false;
00149 }
00150 }
00151
00152
00153
00154 inline bool isZero (const Node& n)
00155 {
00156 return (n.type() == kFloatNode) && (n.getFloat() == 0.0f)
00157 || (n.type() == kIntNode) && (n.getInt() == 0);
00158 }
00159
00160 inline bool isGEZero (const Node& n)
00161 {
00162 return (n.type() == kFloatNode) && (n.getFloat() >= 0.0f)
00163 || (n.type() == kIntNode) && (n.getInt() >= 0);
00164 }
00165
00166 inline bool isGTZero (const Node& n)
00167 {
00168 return (n.type() == kFloatNode) && (n.getFloat() > 0.0f)
00169 || (n.type() == kIntNode) && (n.getInt() > 0);
00170 }
00171
00172 inline bool isOne (const Node& n)
00173 {
00174 return (n.type() == kFloatNode) && (n.getFloat() == 1.0f)
00175 || (n.type() == kIntNode) && (n.getInt() == 1);
00176 }
00177
00178 inline bool isMinusOne (const Node& n)
00179 {
00180 return (n.type() == kFloatNode) && (n.getFloat() == -1.0f)
00181 || (n.type() == kIntNode) && (n.getInt() == -1);
00182 }
00183
00184
00185
00186 inline bool isNum (const Node& n)
00187 {
00188 return isInt(n)||isFloat(n);
00189 }
00190
00191
00192
00193 inline bool isSym (const Node& n)
00194 {
00195 return (n.type() == kSymNode);
00196 }
00197
00198 inline bool isSym (const Node& n, Sym* x)
00199 {
00200 if (n.type() == kSymNode) {
00201 *x = n.getSym();
00202 return true;
00203 } else {
00204 return false;
00205 }
00206 }
00207
00208
00209
00210 inline bool isPointer (const Node& n)
00211 {
00212 return (n.type() == kPointerNode);
00213 }
00214
00215 inline bool isPointer (const Node& n, void** x)
00216 {
00217 if (n.type() == kPointerNode) {
00218 *x = n.getPointer();
00219 return true;
00220 } else {
00221 return false;
00222 }
00223 }
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 inline const Node addNode (const Node& x, const Node& y)
00236 { return (isFloat(x)||isFloat(y)) ? Node(float(x)+float(y)) : Node(int(x)+int(y)); }
00237
00238 inline const Node subNode (const Node& x, const Node& y)
00239 { return (isFloat(x)||isFloat(y)) ? Node(float(x)-float(y)) : Node(int(x)-int(y)); }
00240
00241 inline const Node mulNode (const Node& x, const Node& y)
00242 { return (isFloat(x)||isFloat(y)) ? Node(float(x)*float(y)) : Node(int(x)*int(y)); }
00243
00244 inline const Node divNode (const Node& x, const Node& y)
00245 { return (isFloat(x)||isFloat(y)) ? Node(float(x)/float(y)) : Node(int(x)/int(y)); }
00246
00247 inline const Node divExtendedNode (const Node& x, const Node& y)
00248 { return (isFloat(x)||isFloat(y)) ? Node(float(x)/float(y))
00249 : (float(int(x)/int(y))==float(x)/float(y)) ? Node(int(x)/int(y))
00250 : Node(float(x)/float(y)); }
00251
00252 inline const Node remNode (const Node& x, const Node& y)
00253 { return Node(int(x)%int(y)); }
00254
00255
00256
00257 inline const Node minusNode (const Node& x)
00258 { return subNode(0, x); }
00259
00260 inline const Node inverseNode (const Node& x)
00261 { return divNode(1.0f, x); }
00262
00263
00264
00265
00266 inline const Node lshNode (const Node& x, const Node& y)
00267 { return Node(int(x)<<int(y)); }
00268
00269 inline const Node rshNode (const Node& x, const Node& y)
00270 { return Node(int(x)>>int(y)); }
00271
00272
00273
00274
00275 inline const Node andNode (const Node& x, const Node& y)
00276 { return Node(int(x)&int(y)); }
00277
00278 inline const Node orNode (const Node& x, const Node& y)
00279 { return Node(int(x)|int(y)); }
00280
00281 inline const Node xorNode (const Node& x, const Node& y)
00282 { return Node(int(x)^int(y)); }
00283
00284
00285
00286
00287 inline const Node gtNode (const Node& x, const Node& y)
00288 { return (isFloat(x)||isFloat(y)) ? Node(float(x)>float(y)) : Node(int(x)>int(y)); }
00289
00290 inline const Node ltNode (const Node& x, const Node& y)
00291 { return (isFloat(x)||isFloat(y)) ? Node(float(x)<float(y)) : Node(int(x)<int(y)); }
00292
00293 inline const Node geNode (const Node& x, const Node& y)
00294 { return (isFloat(x)||isFloat(y)) ? Node(float(x)>=float(y)) : Node(int(x)>=int(y)); }
00295
00296 inline const Node leNode (const Node& x, const Node& y)
00297 { return (isFloat(x)||isFloat(y)) ? Node(float(x)<=float(y)) : Node(int(x)<=int(y)); }
00298 #if 1
00299 inline const Node eqNode (const Node& x, const Node& y)
00300 { return (isFloat(x)||isFloat(y)) ? Node(float(x)==float(y)) : Node(int(x)==int(y)); }
00301
00302 inline const Node neNode (const Node& x, const Node& y)
00303 { return (isFloat(x)||isFloat(y)) ? Node(float(x)!=float(y)) : Node(int(x)!=int(y)); }
00304 #endif
00305
00306
00307
00308 #endif