oqlflwctl.cc

00001 /* 
00002    EyeDB Object Database Management System
00003    Copyright (C) 1994-2008 SYSRA
00004    
00005    EyeDB is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009    
00010    EyeDB is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014    
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with this library; if not, write to the Free Software
00017    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA 
00018 */
00019 
00020 /*
00021   Author: Eric Viara <viara@sysra.com>
00022 */
00023 
00024 
00025 #include "oql_p.h"
00026 
00027 #define EXT_LOGIC
00028 
00029 namespace eyedb {
00030 
00031   int oqmlLoopLevel, oqmlBreakLevel;
00032   static const char OQML_BREAK_MAGIC[] = "$oqml$break$magic$";
00033 
00034 #define oqml_is_break(S) ((S) && !strcmp((S)->msg, OQML_BREAK_MAGIC))
00035 
00036   // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00037   //
00038   // oqmlIf operator methods
00039   //
00040   // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00041 
00042   oqmlIf::oqmlIf(oqmlNode * _qcond, oqmlNode * _qthen, oqmlNode *_qelse,
00043                  oqmlBool _is_cond_expr) :
00044     oqmlNode(oqmlIF)
00045   {
00046     qcond = _qcond;
00047     qthen = _qthen;
00048     qelse = _qelse;
00049     qthen_compiled = oqml_False;
00050     qelse_compiled = oqml_False;
00051     is_cond_expr = _is_cond_expr;
00052   }
00053 
00054   oqmlIf::~oqmlIf()
00055   {
00056   }
00057 
00058   oqmlStatus *oqmlIf::compile(Database *db, oqmlContext *ctx)
00059   {
00060     return qcond->compile(db, ctx);
00061   }
00062 
00063   oqmlStatus *oqmlIf::eval(Database *db, oqmlContext *ctx, oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00064   {
00065     oqmlStatus *s;
00066     oqmlAtomList *al = 0;
00067     oqmlNode *toeval;
00068     oqmlBool *compiled = 0;
00069 
00070     s = qcond->eval(db, ctx, &al);
00071     if (s)
00072       return s;
00073 
00074     if (!al->cnt) {
00075       toeval = qelse;
00076       compiled = &qelse_compiled;
00077     }
00078     else if (al->cnt == 1) {
00079       oqmlAtom *a = al->first;
00080 #ifdef EXT_LOGIC
00081       oqmlBool b;
00082       s = oqml_check_logical(this, al, b);
00083       if (s)
00084         return s;
00085       
00086       if (b) {
00087         toeval = qthen;
00088         compiled = &qthen_compiled;
00089       }
00090       else {
00091         toeval = qelse;
00092         compiled = &qelse_compiled;
00093       }
00094 #else
00095       if (!OQML_IS_BOOL(a))
00096         return new oqmlStatus(this, "boolean expected for condition");
00097       
00098       if (OQML_ATOM_BOOLVAL(a)) {
00099         toeval = qthen;
00100         compiled = &qthen_compiled;
00101       }
00102       else {
00103         toeval = qelse;
00104         compiled = &qelse_compiled;
00105       }
00106 #endif
00107       }
00108     else
00109       toeval = qthen;
00110 
00111 #ifdef SYNC_GARB
00112     OQL_DELETE(al);
00113 #endif
00114 
00115     *alist = 0;
00116 
00117     if (toeval) {
00118       if (!*compiled) {
00119         s = toeval->compile(db, ctx);
00120         if (s) return s;
00121         *compiled = oqml_True;
00122       }
00123 
00124       s = toeval->eval(db, ctx, alist);
00125       if (s) return s;
00126     }
00127     else
00128       *alist = new oqmlAtomList();
00129 
00130     if (!is_cond_expr && toeval) {
00131 #ifdef SYNC_GARB
00132       OQL_DELETE(*alist);
00133 #endif
00134       *alist = new oqmlAtomList();
00135     }
00136 
00137     return oqmlSuccess;
00138   }
00139 
00140   oqmlBool
00141   oqmlIf::hasIdent(const char *_ident)
00142   {
00143     return OQMLBOOL(qcond->hasIdent(_ident) ||
00144                     qthen->hasIdent(_ident) ||
00145                     (qelse && qelse->hasIdent(_ident)));
00146   }
00147 
00148   void oqmlIf::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00149   {
00150     *at = eval_type;
00151   }
00152 
00153   oqmlBool oqmlIf::isConstant() const
00154   {
00155     return oqml_False;
00156   }
00157 
00158   std::string
00159   oqmlIf::toString(void) const
00160   {
00161     if (is_statement)
00162       return std::string("if (") + qcond->toString() + ") " + qthen->toString() +
00163         (qelse ? std::string(" else " ) + qelse->toString() : std::string(""));
00164     //oqml_isstat();
00165   
00166     return std::string("(") + qcond->toString() + "?" + qthen->toString() +
00167       ":" + qelse->toString() + ")";
00168   }
00169 
00170   // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00171   //
00172   // oqmlForEach operator methods
00173   //
00174   // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00175 
00176   oqmlForEach::oqmlForEach(const char * _ident, oqmlNode * _in,
00177                            oqmlNode * _action) : oqmlNode(oqmlFOREACH)
00178   {
00179     ident = strdup(_ident);
00180     in = _in;
00181     action = _action;
00182   }
00183 
00184   oqmlForEach::~oqmlForEach()
00185   {
00186     free(ident);
00187   }
00188 
00189   void oqmlForEach::setAction(oqmlNode *_action)
00190   {
00191     action = _action;
00192   }
00193 
00194   oqmlStatus *oqmlForEach::compile(Database *db, oqmlContext *ctx)
00195   {
00196     oqmlStatus *s;
00197 
00198     s = in->compile(db, ctx);
00199     if (s) return s;
00200 
00201     if (action)
00202       {
00203         oqmlAtomType at;
00204         ctx->pushSymbol(ident, &at);
00205         s = action->compile(db, ctx);
00206         ctx->popSymbol(ident);
00207       }
00208 
00209     if (s) return s;
00210 
00211     return oqmlSuccess;
00212   }
00213 
00214   oqmlStatus *oqmlForEach::eval(Database *db, oqmlContext *ctx,
00215                                 oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00216   {
00217     oqmlStatus *s;
00218     oqmlAtomList *al;
00219 
00220     s = in->eval(db, ctx, &al);
00221     if (s) return s;
00222 
00223     oqmlAtom *a = al->first;
00224     int iter = 0;
00225     int level = ++oqmlLoopLevel;
00226 
00227     oqmlAtomList *tal;
00228     if (a && OQML_IS_COLL(a)) {
00229       oqmlAtomList *list = OQML_ATOM_COLLVAL(a);
00230       oqmlAtom *x = list->first;
00231       while(x) {
00232 #ifdef SYNC_GARB
00233         if (level == 1) {
00234           //printf("foreach level #%d, iter #%d\n", level, iter);
00235           iter++;
00236         }
00237 #endif
00238         oqmlAtom * next = x->next;
00239 
00240         if (action) {
00241           gbContext *gbctx = oqmlGarbManager::peek();
00242           ctx->pushSymbol(ident, &x->type, x);
00243           tal = 0;
00244           s = action->eval(db, ctx, &tal);
00245 #ifdef SYNC_GARB
00246           OQL_DELETE(tal);
00247 #endif
00248           ctx->popSymbol(ident);
00249           oqmlGarbManager::garbage(gbctx);
00250           if (s)
00251             break;
00252         }
00253       
00254         OQML_CHECK_INTR();
00255       
00256         x = next;
00257       }
00258     }
00259     else if (action && a) {
00260       ctx->pushSymbol(ident, &a->type, a);
00261 #ifdef SYNC_GARB
00262       tal = 0;
00263       s = action->eval(db, ctx, &tal);
00264       OQL_DELETE(tal);
00265 #else
00266       s = action->eval(db, ctx, alist);
00267 #endif
00268       ctx->popSymbol(ident);
00269     }
00270 
00271 #ifdef SYNC_GARB
00272     // 8/02/06
00273     //  delete al;
00274 #endif
00275     --oqmlLoopLevel;
00276 
00277     *alist = new oqmlAtomList();
00278     if (s && !oqml_is_break(s))
00279       return s;
00280 
00281     if (oqml_is_break(s) && oqmlBreakLevel == level) {
00282       delete s;
00283       return oqmlSuccess;
00284     }
00285 
00286     return s;
00287   }
00288 
00289   void oqmlForEach::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00290   {
00291     *at = eval_type;
00292   }
00293 
00294   oqmlBool oqmlForEach::isConstant() const
00295   {
00296     return oqml_False;
00297   }
00298 
00299   oqmlBool
00300   oqmlForEach::hasIdent(const char *_ident)
00301   {
00302     return OQMLBOOL(in->hasIdent(_ident) ||
00303                     (action ? action->hasIdent(_ident) : oqml_False));
00304   }
00305 
00306   std::string
00307   oqmlForEach::toString(void) const
00308   {
00309     return std::string("for (") + ident + " in " + in->toString() + ") " +
00310       (action ? action->toString() : std::string("")); // + oqml_isstat();
00311   }
00312 
00313   void
00314   oqmlForEach::lock()
00315   {
00316     oqmlNode::lock();
00317     in->lock();
00318     if (action)
00319       action->lock();
00320   }
00321 
00322   void
00323   oqmlForEach::unlock()
00324   {
00325     oqmlNode::unlock();
00326     in->unlock();
00327     if (action)
00328       action->unlock();
00329   }
00330 
00331   // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00332   //
00333   // oqmlWhile operator methods
00334   //
00335   // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00336 
00337   oqmlWhile::oqmlWhile(oqmlNode * _qleft, oqmlNode *_qright) : oqmlNode(oqmlWHILE)
00338   {
00339     qleft = _qleft;
00340     qright = _qright;
00341   }
00342 
00343   oqmlWhile::~oqmlWhile()
00344   {
00345   }
00346 
00347   oqmlStatus *oqmlWhile::compile(Database *db, oqmlContext *ctx)
00348   {
00349     oqmlStatus *s;
00350 
00351     s = qleft->compile(db, ctx);
00352     if (s) return s;
00353 
00354     s = qright->compile(db, ctx);
00355     if (s) return s;
00356 
00357     return oqmlSuccess;
00358   }
00359 
00360   oqmlStatus *oqmlWhile::eval(Database *db, oqmlContext *ctx, oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00361   {
00362     oqmlStatus *s = oqmlSuccess;
00363 
00364     int level = ++oqmlLoopLevel;
00365     for (;;)
00366       {
00367         oqmlAtomList *al;
00368 
00369         s = qleft->eval(db, ctx, &al);
00370         if (s)
00371           break;
00372 
00373 #ifdef EXT_LOGIC
00374         oqmlBool b;
00375         s = oqml_check_logical(this, al, b);
00376         if (s)
00377           break;
00378 
00379         if (!b)
00380           break;
00381 #else
00382         if (al->cnt != 1 || !OQML_IS_BOOL(al->first))
00383           return new oqmlStatus(this, "boolean expected for condition");
00384 
00385         if (!OQML_ATOM_BOOLVAL(al->first))
00386           break;
00387 #endif
00388 
00389         OQML_CHECK_INTR();
00390 
00391         if (qright) {
00392           gbContext *gbctx = oqmlGarbManager::peek();
00393           s = qright->eval(db, ctx, &al);
00394           oqmlGarbManager::garbage(gbctx);
00395           if (s) break;
00396         }
00397       }
00398 
00399     --oqmlLoopLevel;
00400 
00401     *alist = new oqmlAtomList();
00402     if (s && !oqml_is_break(s))
00403       return s;
00404 
00405     if (oqml_is_break(s) && oqmlBreakLevel == level)
00406       {
00407         delete s;
00408         return oqmlSuccess;
00409       }
00410 
00411     return s;
00412   }
00413 
00414   void oqmlWhile::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00415   {
00416     *at = eval_type;
00417   }
00418 
00419   oqmlBool oqmlWhile::isConstant() const
00420   {
00421     return OQMLBOOL(qleft->isConstant() && qright->isConstant());
00422   }
00423 
00424   std::string
00425   oqmlWhile::toString(void) const
00426   {
00427     return std::string("while (") + qleft->toString() + ") " +
00428       (qright ? qright->toString() : std::string(""));
00429     //oqml_isstat();
00430   }
00431 
00432   // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00433   //
00434   // oqmlDoWhile operator methods
00435   //
00436   // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00437 
00438   oqmlDoWhile::oqmlDoWhile(oqmlNode * _qleft, oqmlNode *_qright) : oqmlNode(oqmlDOWHILE)
00439   {
00440     qleft = _qleft;
00441     qright = _qright;
00442   }
00443 
00444   oqmlDoWhile::~oqmlDoWhile()
00445   {
00446   }
00447 
00448   oqmlStatus *oqmlDoWhile::compile(Database *db, oqmlContext *ctx)
00449   {
00450     oqmlStatus *s;
00451 
00452     s = qleft->compile(db, ctx);
00453     if (s) return s;
00454 
00455     s = qright->compile(db, ctx);
00456     if (s) return s;
00457 
00458     return oqmlSuccess;
00459   }
00460 
00461   oqmlStatus *oqmlDoWhile::eval(Database *db, oqmlContext *ctx, oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00462   {
00463     oqmlStatus *s = oqmlSuccess;
00464     oqmlBool b;
00465 
00466     int level = ++oqmlLoopLevel;
00467     do {
00468       oqmlAtomList *al;
00469 
00470       s = qleft->eval(db, ctx, &al);
00471       if (s) break;
00472     
00473 #ifdef EXT_LOGIC
00474       s = oqml_check_logical(this, al, b);
00475       if (s)
00476         break;
00477 
00478       OQML_CHECK_INTR();
00479 #else
00480       if (al->cnt != 1 || !OQML_IS_BOOL(al->first))
00481         return new oqmlStatus(this, "boolean expected for condition");
00482 
00483       OQML_CHECK_INTR();
00484 
00485       b = OQML_ATOM_BOOLVAL(al->first);
00486 #endif
00487     
00488       if (qright)
00489         {
00490           gbContext *gbctx = oqmlGarbManager::peek();
00491           s = qright->eval(db, ctx, &al);
00492           oqmlGarbManager::garbage(gbctx);
00493           if (s) break;
00494         }
00495 
00496     } while(b);
00497 
00498     --oqmlLoopLevel;
00499 
00500     *alist = new oqmlAtomList();
00501 
00502     if (s && !oqml_is_break(s))
00503       return s;
00504 
00505     if (oqml_is_break(s) && oqmlBreakLevel == level)
00506       {
00507         delete s;
00508         return oqmlSuccess;
00509       }
00510 
00511     return s;
00512   }
00513 
00514   void oqmlDoWhile::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00515   {
00516     *at = eval_type;
00517   }
00518 
00519   oqmlBool oqmlDoWhile::isConstant() const
00520   {
00521     return OQMLBOOL(qleft->isConstant() && qright->isConstant());
00522   }
00523 
00524   std::string
00525   oqmlDoWhile::toString(void) const
00526   {
00527     return std::string("do ") +
00528       (qright ? qright->toString() : std::string(""))
00529       + " while " + qleft->toString(); // + oqml_isstat();
00530   }
00531 
00532   // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00533   //
00534   // oqmlForDo operator methods
00535   //
00536   // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00537 
00538   oqmlForDo::oqmlForDo(oqmlNode *_start,
00539                        oqmlNode *_cond,
00540                        oqmlNode *_next,
00541                        oqmlNode *_body) : oqmlNode(oqmlFORDO)
00542   {
00543     ident = 0;
00544     start = _start;
00545     cond = _cond;
00546     next = _next;
00547     body = _body;
00548   }
00549 
00550   oqmlForDo::oqmlForDo(const char *_ident,
00551                        oqmlNode *_start,
00552                        oqmlNode *_cond,
00553                        oqmlNode *_next,
00554                        oqmlNode *_body) : oqmlNode(oqmlFORDO)
00555   {
00556     ident = strdup(_ident);
00557     start = _start;
00558     cond = _cond;
00559     next = _next;
00560     body = _body;
00561   }
00562 
00563   oqmlForDo::~oqmlForDo()
00564   {
00565     free(ident);
00566   }
00567 
00568   oqmlStatus *oqmlForDo::compile(Database *db, oqmlContext *ctx)
00569   {
00570     oqmlStatus *s;
00571 
00572     if (ident)
00573       {
00574         oqmlAtomType at;
00575         ctx->pushSymbol(ident, &at, 0, oqml_False);
00576       }
00577 
00578     if (start)
00579       {
00580         s = start->compile(db, ctx);
00581         if (s) return s;
00582       }
00583 
00584     if (cond)
00585       {
00586         s = cond->compile(db, ctx);
00587         if (s) return s;
00588       }
00589 
00590     if (next)
00591       {
00592         s = next->compile(db, ctx);
00593         if (s) return s;
00594       }
00595 
00596     if (body)
00597       {
00598         s = body->compile(db, ctx);
00599         if (s) return s;
00600       }
00601 
00602     if (ident)
00603       ctx->popSymbol(ident, oqml_False);
00604 
00605     return oqmlSuccess;
00606   }
00607 
00608   oqmlStatus *oqmlForDo::eval(Database *db, oqmlContext *ctx, oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00609   {
00610     oqmlStatus *s = oqmlSuccess;
00611     oqmlBool b;
00612 
00613     oqmlAtomList *al;
00614 
00615     if (ident)
00616       {
00617         oqmlAtomType at;
00618         ctx->pushSymbol(ident, &at, 0, oqml_False);
00619       }
00620 
00621     if (start)
00622       {
00623         s = start->eval(db, ctx, &al);
00624         if (s) return s;
00625       }
00626     
00627     int level = ++oqmlLoopLevel;
00628 
00629     for (;;) {
00630       if (cond) {
00631         s = cond->eval(db, ctx, &al);
00632         if (s)
00633           return s;
00634 
00635 #ifdef EXT_LOGIC
00636         oqmlBool b;
00637         s = oqml_check_logical(this, al, b);
00638         if (s)
00639           break;
00640 
00641         if (!b)
00642           break;
00643 #else
00644         if (al->cnt != 1 || !OQML_IS_BOOL(al->first)) {
00645           s = new oqmlStatus(this, "boolean expected for condition");
00646           break;
00647         }
00648 
00649         if (!OQML_ATOM_BOOLVAL(al->first))
00650           break;
00651 #endif
00652       }
00653     
00654       OQML_CHECK_INTR();
00655 
00656       if (body) {
00657         gbContext *gbctx = oqmlGarbManager::peek();
00658         s = body->eval(db, ctx, &al);
00659         oqmlGarbManager::garbage(gbctx);
00660         if (s) break;
00661       }
00662 
00663       if (next) {
00664         s = next->eval(db, ctx, &al);
00665         if (s) break;
00666       }
00667       }
00668 
00669     --oqmlLoopLevel;
00670 
00671     if (ident)
00672       ctx->popSymbol(ident, oqml_False);
00673 
00674     *alist = new oqmlAtomList();
00675     if (s && !oqml_is_break(s))
00676       return s;
00677 
00678     if (oqml_is_break(s) && oqmlBreakLevel == level)
00679       {
00680         delete s;
00681         return oqmlSuccess;
00682       }
00683 
00684     return oqmlSuccess;
00685   }
00686 
00687   void oqmlForDo::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00688   {
00689     *at = eval_type;
00690   }
00691 
00692   oqmlBool oqmlForDo::isConstant() const
00693   {
00694     return oqml_False;
00695   }
00696 
00697   oqmlBool
00698   oqmlForDo::hasIdent(const char *_ident)
00699   {
00700     return OQMLBOOL((start ? start->hasIdent(_ident) : oqml_False)||
00701                     (cond ? cond->hasIdent(_ident) : oqml_False) ||
00702                     (next ? next->hasIdent(_ident) : oqml_False) ||
00703                     (body ? body->hasIdent(_ident) : oqml_False));
00704   }
00705 
00706   void oqmlForDo::lock()
00707   {
00708     oqmlNode::lock();
00709     if (start)
00710       start->lock();
00711     if (cond)
00712       cond->lock();
00713     if (next)
00714       next->lock();
00715     if (body)
00716       body->lock();
00717   }
00718 
00719   void oqmlForDo::unlock()
00720   {
00721     oqmlNode::unlock();
00722     if (start)
00723       start->unlock();
00724     if (cond)
00725       cond->unlock();
00726     if (next)
00727       next->unlock();
00728     if (body)
00729       body->unlock();
00730   }
00731 
00732   std::string
00733   oqmlForDo::toString(void) const
00734   {
00735     return std::string("for(") +
00736       (start ? start->toString() : std::string("")) + ";" +
00737       (cond ? cond->toString() : std::string("")) + ";" +
00738       (next ? next->toString() : std::string("")) + ") " +
00739       (body ? body->toString() : std::string(""));
00740     //+ oqml_isstat();
00741   }
00742 
00743   // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00744   //
00745   // oqmlThrow operator methods
00746   //
00747   // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00748 
00749   oqmlThrow::oqmlThrow(oqmlNode * _ql) : oqmlNode(oqmlTHROW)
00750   {
00751     ql = _ql;
00752   }
00753 
00754   oqmlThrow::~oqmlThrow()
00755   {
00756   }
00757 
00758   oqmlStatus *oqmlThrow::compile(Database *db, oqmlContext *ctx)
00759   {
00760     return ql->compile(db, ctx);
00761   }
00762 
00763   oqmlStatus *oqmlThrow::eval(Database *db, oqmlContext *ctx, oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00764   {
00765     oqmlStatus *s;
00766     oqmlAtomList *al;
00767 
00768     s = ql->eval(db, ctx, &al); 
00769 
00770     if (s) return s;
00771 
00772     if (al->cnt == 1 && al->first->as_string())
00773       return new oqmlStatus(OQML_ATOM_STRVAL(al->first));
00774 
00775     if (al->cnt == 1)
00776       return oqmlStatus::expected(this, "string", al->first->type.getString());
00777 
00778     return new oqmlStatus(this, "string argument expected");
00779   }
00780 
00781   void oqmlThrow::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00782   {
00783     *at = eval_type;
00784   }
00785 
00786   oqmlBool oqmlThrow::isConstant() const
00787   {
00788     return oqml_False;
00789   }
00790 
00791   std::string
00792   oqmlThrow::toString(void) const
00793   {
00794     return std::string("throw ") + ql->toString() + oqml_isstat();
00795   }
00796 
00797   // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00798   //
00799   // oqmlBreak operator methods
00800   //
00801   // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00802 
00803   oqmlBreak::oqmlBreak(oqmlNode * _ql) : oqmlNode(oqmlBREAK)
00804   {
00805     ql = _ql;
00806   }
00807 
00808   oqmlBreak::~oqmlBreak()
00809   {
00810   }
00811 
00812   oqmlStatus *oqmlBreak::compile(Database *db, oqmlContext *ctx)
00813   {
00814     if (ql)
00815       return ql->compile(db, ctx);
00816 
00817     return oqmlSuccess;
00818   }
00819 
00820   oqmlStatus *oqmlBreak::eval(Database *db, oqmlContext *ctx, oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00821   {
00822     int level;
00823 
00824     if (ql)
00825       {
00826         oqmlStatus *s;
00827         oqmlAtomList *al;
00828       
00829         s = ql->eval(db, ctx, &al); 
00830 
00831         if (s) return s;
00832 
00833         if (al->cnt != 1 || !al->first->as_int())
00834           return new oqmlStatus(this, "integer expected");
00835 
00836         level = OQML_ATOM_INTVAL(al->first);
00837       }
00838     else
00839       level = 1;
00840 
00841     if (level > oqmlLoopLevel)
00842       return new oqmlStatus(this, "level %d is too deep", level);
00843 
00844     oqmlBreakLevel = oqmlLoopLevel - level + 1;
00845 
00846     return new oqmlStatus(OQML_BREAK_MAGIC);
00847   }
00848 
00849   void oqmlBreak::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00850   {
00851     *at = eval_type;
00852   }
00853 
00854   oqmlBool oqmlBreak::isConstant() const
00855   {
00856     return oqml_False;
00857   }
00858 
00859   std::string
00860   oqmlBreak::toString(void) const
00861   {
00862     return std::string("break") +
00863       (ql ? std::string(" ") + ql->toString() : std::string("")) + oqml_isstat();
00864   }
00865 }

Generated on Mon Dec 22 18:16:05 2008 for eyedb by  doxygen 1.5.3