Main Page | Namespace List | Class Hierarchy | Class List | File List | Class Members | File Members

ExprUtil.h

Go to the documentation of this file.
00001 #ifndef EXPRUTIL_H 00002 #define EXPRUTIL_H 00003 00004 #include "NArgs.h" 00005 //#include "Expression.h" 00006 00007 //BOREALIS_NAMESPACE_BEGIN 00008 using namespace Borealis; 00009 00010 inline vector<ptr<Expression> > makeArgs(ptr<Expression> a = ptr<Expression>(), 00011 ptr<Expression> b = ptr<Expression>(), 00012 ptr<Expression> c = ptr<Expression>()) 00013 { 00014 vector<ptr<Expression> > out; 00015 00016 if (a) { out.push_back(a); } 00017 if (b) { out.push_back(b); } 00018 if (c) { out.push_back(c); } 00019 00020 return out; 00021 } 00022 00023 00024 00025 00026 // A Constant expression of type T. 00027 template<typename T> 00028 class ConstantExpression : public TypedExpression<T> { 00029 public: 00030 ConstantExpression(T val) : _val(val) {} 00031 T evalImpl(EvalAs<T>, const EvalContext& ctxt) throw (EvalException) { return _val; } 00032 00033 T getValue() const { return _val; } 00034 string value() const { return to_string(_val); } 00035 00036 private: 00037 T _val; 00038 }; 00039 00040 template<> 00041 class ConstantExpression<EString> : public TypedExpression<EString> { 00042 public: 00043 ConstantExpression(string val) : _val(val) {} 00044 EString evalImpl(EvalAs<EString>, const EvalContext& ctxt) throw (EvalException) { return EString(_val); } 00045 00046 string value() const { return "\"" + to_escaped_string(to_string(_val)) + "\""; } 00047 00048 private: 00049 string _val; 00050 }; 00051 00052 00053 00054 00055 00056 00057 00058 00059 // An expression returning the value, of type T, at a given offset in 00060 // the input tuple. 00061 template<typename T> 00062 class FieldExpression : public TypedExpression<T> { 00063 public: 00064 FieldExpression(unsigned int which_tuple, unsigned int offset) : 00065 _which_tuple(which_tuple), _offset(offset) {} 00066 00067 T evalImpl(EvalAs<T>, const EvalContext& ctxt) throw (EvalException) { 00068 return *(T*)(ctxt.getTuple(_which_tuple) + _offset); 00069 } 00070 00071 private: 00072 unsigned int _which_tuple; 00073 unsigned int _offset; 00074 }; 00075 00076 template<> 00077 class FieldExpression<EString> : public TypedExpression<EString> { 00078 public: 00079 FieldExpression(unsigned int which_tuple, unsigned int offset, unsigned int length) : 00080 _which_tuple(which_tuple), _offset(offset), _length(length) {} 00081 00082 EString evalImpl(EvalAs<EString>, const EvalContext& ctxt) throw (EvalException) { 00083 const char *field = ctxt.getTuple(_which_tuple) + _offset; 00084 const char *end = field + _length; 00085 00086 // ignore null padding at end 00087 while (end != field) { 00088 if (*(end - 1) != 0) break; 00089 --end; 00090 } 00091 00092 return EString(field, end - field); 00093 } 00094 00095 int32 getStringLength() const { return _length; } 00096 00097 private: 00098 unsigned int _which_tuple; 00099 unsigned int _offset, _length; 00100 }; 00101 00102 00103 00104 00105 00106 00107 00108 #define OP(N, Name, Out, Expr) \ 00109 template<typename T> \ 00110 class Name##Expression : public TypedExpression<Out>, NArgs { \ 00111 public: \ 00112 Name##Expression(const NArgs& args) throw (ExprException) : NArgs(args) { \ 00113 requireNumArgs(N); \ 00114 } \ 00115 Out evalImpl(EvalAs<Out>, const EvalContext& ctxt) throw (EvalException) { \ 00116 return Expr; \ 00117 } \ 00118 }; \ 00119 struct Name##Expressions { \ 00120 template <class T> struct forType { \ 00121 typedef Name##Expression<T> ExprType; \ 00122 }; \ 00123 }; 00124 00125 00126 template <class T> 00127 inline T exprMod(T a, T b) { return a % b; } 00128 00129 template <> 00130 inline single exprMod( single a, single b) { return( fmodf( a, b )); } 00131 00132 template <> 00133 inline double exprMod( double a, double b) { return( fmod( a, b )); } 00134 00135 00136 template <class T> 00137 inline T divide(T a, T b) { 00138 if (b == 0) { 00139 WARN << "Divided by zero."; 00140 return numeric_limits<T>::infinity(); 00141 } else { 00142 return a / b; 00143 } 00144 } 00145 00146 // Actual operator declarations 00147 00148 #define A (_args[0]->template eval<T>(ctxt)) 00149 #define B (_args[1]->template eval<T>(ctxt)) 00150 #define C (_args[2]->template eval<T>(ctxt)) 00151 00152 #define A_as(type) (_args[0]->template eval<type>(ctxt)) 00153 00154 OP(2, Plus, T, A + B); 00155 OP(2, Minus, T, A - B); 00156 OP(2, Times, T, A * B); 00157 OP(2, Div, T, divide(A,B)); 00158 OP(2, Mod, T, exprMod(A, B)); 00159 OP(2, Concat, T, A.concat(B, ctxt.getPool())); 00160 00161 OP(2, EQ, bool, A == B); 00162 OP(2, NE, bool, A != B); 00163 OP(2, LT, bool, A < B); 00164 OP(2, GT, bool, A > B); 00165 OP(2, LE, bool, A <= B); 00166 OP(2, GE, bool, A >= B); 00167 00168 OP(2, And, bool, A && B); 00169 OP(2, Or, bool, A || B); 00170 00171 OP(1, UMinus, T, -A); 00172 OP(1, Not, T, !A); 00173 00174 OP(3, IfThenElse, T, A_as(bool) ? B : C); 00175 00176 #undef A 00177 #undef B 00178 #undef C 00179 00180 00181 00182 template <typename Types> 00183 ptr<Expression> arithPromote( ptr<Expression> l, ptr<Expression> r ) 00184 throw( ExprException ) 00185 { 00186 if ( l->is_numeric() && r->is_numeric() ) 00187 { if (( l->getType() == DataType::DOUBLE ) || 00188 ( r->getType() == DataType::DOUBLE )) 00189 { 00190 return( ptr<Expression>( 00191 new typename Types::forType<double>::ExprType( 00192 NArgs( l, r )))); 00193 } 00194 else if (( l->getType() == DataType::SINGLE ) || 00195 ( r->getType() == DataType::SINGLE ) || 00196 ( r->getType() == DataType::FLOAT ) || // bb: Depricated 00197 ( r->getType() == DataType::FLOAT )) 00198 { 00199 return( ptr<Expression>( 00200 new typename Types::forType<single>::ExprType( 00201 NArgs( l, r )))); 00202 } 00203 else if (( l->getType() == DataType::LONG ) || 00204 ( r->getType() == DataType::LONG )) 00205 { 00206 return( ptr<Expression>( 00207 new typename Types::forType<int64>::ExprType( 00208 NArgs( l, r )))); 00209 } 00210 else 00211 { return( ptr<Expression>( 00212 new typename Types::forType<int32>::ExprType( 00213 NArgs( l, r )))); 00214 } 00215 } 00216 00217 Throw( ExprException, "invalid types" ); 00218 } 00219 00220 template <typename Types> 00221 ptr<Expression> relPromote( ptr<Expression> l, ptr<Expression> r ) 00222 throw( ExprException ) 00223 { 00224 if (( l->getType() == DataType::BOOL ) && 00225 ( r->getType() == DataType::BOOL )) 00226 { 00227 return( ptr<Expression>( 00228 new typename Types::forType<bool>::ExprType( 00229 NArgs( l, r )))); 00230 } 00231 else if ( l->is_numeric() && r->is_numeric()) 00232 { 00233 if (( l->getType() == DataType::DOUBLE ) || 00234 ( r->getType() == DataType::DOUBLE )) 00235 { 00236 return( ptr<Expression>( 00237 new typename Types::forType<double>::ExprType( 00238 NArgs( l, r )))); 00239 } 00240 else if (( l->getType() == DataType::SINGLE ) || 00241 ( r->getType() == DataType::SINGLE ) || 00242 ( r->getType() == DataType::FLOAT ) || // bb: Depricated 00243 ( r->getType() == DataType::FLOAT )) 00244 { 00245 return( ptr<Expression>( 00246 new typename Types::forType<single>::ExprType( 00247 NArgs( l, r )))); 00248 } 00249 else if (( l->getType() == DataType::LONG ) || 00250 ( r->getType() == DataType::LONG )) 00251 { 00252 return( ptr<Expression>( 00253 new typename Types::forType<int64>::ExprType( 00254 NArgs( l, r )))); 00255 } 00256 else 00257 { return( ptr<Expression>( 00258 new typename Types::forType<int32>::ExprType( 00259 NArgs( l, r )))); 00260 } 00261 } 00262 else if (( l->getType() == DataType::STRING ) && 00263 ( r->getType() == DataType::STRING )) 00264 { 00265 return( ptr<Expression>( 00266 new typename Types::forType<EString>::ExprType( 00267 NArgs( l, r )))); 00268 } 00269 else 00270 { Throw(ExprException, "invalid types"); 00271 } 00272 } 00273 00274 //BOREALIS_NAMESPACE_END 00275 #endif // EXPRUTIL_H

Generated on Fri Nov 12 15:15:21 2004 for Borealis by doxygen 1.3.8