|
FAUST compiler
0.9.9.6b8
|
00001 /************************************************************************ 00002 ************************************************************************ 00003 FAUST compiler 00004 Copyright (C) 2003-2004 GRAME, Centre National de Creation Musicale 00005 --------------------------------------------------------------------- 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 2 of the License, or 00009 (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program; if not, write to the Free Software 00018 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 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, kDoubleNode, kSymNode, kPointerNode }; 00065 00066 00070 class Node 00071 { 00072 int fType; 00073 union { 00074 int i; 00075 double f; 00076 Sym s; 00077 void* p; 00078 } fData; 00079 00080 public: 00081 // constructeurs (assume size of field f is the biggest) 00082 Node (int x) : fType(kIntNode) { fData.f = 0; fData.i = x; } 00083 Node (double x) : fType(kDoubleNode) { fData.f = x; } 00084 Node (const char* name) : fType(kSymNode) { fData.f = 0; fData.s = symbol(name); } 00085 Node (const string& name) : fType(kSymNode) { fData.f = 0; fData.s = symbol(name); } 00086 Node (Sym x) : fType(kSymNode) { fData.f = 0; fData.s = x; } 00087 Node (void* x) : fType(kPointerNode) { fData.f = 0; fData.p = x; } 00088 00089 Node (const Node& n) : fType(n.fType) { fData = n.fData; } 00090 00091 // predicats 00092 bool operator == (const Node& n) const { return fType == n.fType && fData.f == n.fData.f; } 00093 bool operator != (const Node& n) const { return fType != n.fType || fData.f != n.fData.f; } 00094 00095 // accessors 00096 int type() const { return fType; } 00097 00098 int getInt() const { return fData.i; } 00099 double getDouble() const { return fData.f; } 00100 Sym getSym() const { return fData.s; } 00101 void* getPointer() const { return fData.p; } 00102 00103 // conversions and promotion for numbers 00104 operator int() const { return (fType == kIntNode) ? fData.i : (fType == kDoubleNode) ? int(fData.f) : 0 ; } 00105 operator double() const { return (fType == kIntNode) ? double(fData.i) : (fType == kDoubleNode) ? fData.f : 0.0 ; } 00106 00107 ostream& print (ostream& fout) const; 00108 }; 00109 00110 //printing 00111 inline ostream& operator << (ostream& s, const Node& n) { return n.print(s); } 00112 00113 00114 00115 //------------------------------------------------------------------------- 00116 // Perdicates and pattern matching 00117 //------------------------------------------------------------------------- 00118 00119 // integers 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 // floats 00137 inline bool isDouble (const Node& n) 00138 { 00139 return (n.type() == kDoubleNode); 00140 } 00141 00142 inline bool isDouble (const Node& n, double* x) 00143 { 00144 if (n.type() == kDoubleNode) { 00145 *x = n.getDouble(); 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() == kDoubleNode) && (n.getDouble() == 0.0) 00157 || (n.type() == kIntNode) && (n.getInt() == 0); 00158 } 00159 00160 inline bool isGEZero (const Node& n) 00161 { 00162 return (n.type() == kDoubleNode) && (n.getDouble() >= 0.0) 00163 || (n.type() == kIntNode) && (n.getInt() >= 0); 00164 } 00165 00166 inline bool isGTZero (const Node& n) 00167 { 00168 return (n.type() == kDoubleNode) && (n.getDouble() > 0.0) 00169 || (n.type() == kIntNode) && (n.getInt() > 0); 00170 } 00171 00172 inline bool isOne (const Node& n) 00173 { 00174 return (n.type() == kDoubleNode) && (n.getDouble() == 1.0) 00175 || (n.type() == kIntNode) && (n.getInt() == 1); 00176 } 00177 00178 inline bool isMinusOne (const Node& n) 00179 { 00180 return (n.type() == kDoubleNode) && (n.getDouble() == -1.0) 00181 || (n.type() == kIntNode) && (n.getInt() == -1); 00182 } 00183 00184 00185 // numbers in general 00186 inline bool isNum (const Node& n) 00187 { 00188 return isInt(n)||isDouble(n); 00189 } 00190 00191 00192 // symbols 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 // void pointer 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 // Mathematical operations on nodes 00230 //------------------------------------------------------------------------- 00231 00232 00233 // arithmetic operations 00234 00235 inline const Node addNode (const Node& x, const Node& y) 00236 { return (isDouble(x)||isDouble(y)) ? Node(double(x)+double(y)) : Node(int(x)+int(y)); } 00237 00238 inline const Node subNode (const Node& x, const Node& y) 00239 { return (isDouble(x)||isDouble(y)) ? Node(double(x)-double(y)) : Node(int(x)-int(y)); } 00240 00241 inline const Node mulNode (const Node& x, const Node& y) 00242 { return (isDouble(x)||isDouble(y)) ? Node(double(x)*double(y)) : Node(int(x)*int(y)); } 00243 00244 inline const Node divNode (const Node& x, const Node& y) 00245 { return (isDouble(x)||isDouble(y)) ? Node(double(x)/double(y)) : Node(int(x)/int(y)); } 00246 00247 inline const Node divExtendedNode (const Node& x, const Node& y) 00248 { return (isDouble(x)||isDouble(y)) ? Node(double(x)/double(y)) 00249 : (double(int(x)/int(y))==double(x)/double(y)) ? Node(int(x)/int(y)) 00250 : Node(double(x)/double(y)); } 00251 00252 inline const Node remNode (const Node& x, const Node& y) 00253 { return Node(int(x)%int(y)); } 00254 00255 // inverse functions 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 // bit shifting operations 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 // boolean operations on bits 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 // compare operations 00286 00287 inline const Node gtNode (const Node& x, const Node& y) 00288 { return (isDouble(x)||isDouble(y)) ? Node(double(x)>double(y)) : Node(int(x)>int(y)); } 00289 00290 inline const Node ltNode (const Node& x, const Node& y) 00291 { return (isDouble(x)||isDouble(y)) ? Node(double(x)<double(y)) : Node(int(x)<int(y)); } 00292 00293 inline const Node geNode (const Node& x, const Node& y) 00294 { return (isDouble(x)||isDouble(y)) ? Node(double(x)>=double(y)) : Node(int(x)>=int(y)); } 00295 00296 inline const Node leNode (const Node& x, const Node& y) 00297 { return (isDouble(x)||isDouble(y)) ? Node(double(x)<=double(y)) : Node(int(x)<=int(y)); } 00298 #if 1 00299 inline const Node eqNode (const Node& x, const Node& y) 00300 { return (isDouble(x)||isDouble(y)) ? Node(double(x)==double(y)) : Node(int(x)==int(y)); } 00301 00302 inline const Node neNode (const Node& x, const Node& y) 00303 { return (isDouble(x)||isDouble(y)) ? Node(double(x)!=double(y)) : Node(int(x)!=int(y)); } 00304 #endif 00305 00306 00307 00308 #endif
1.8.0