oqlident.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 // added the 7/5/01
00028 #define DELAY_IDENT
00029 
00030 namespace eyedb {
00031 
00032 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00033 //
00034 // oqmlIdent utility functions
00035 //
00036 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00037 
00038 //
00039 // 25/05/01: changed following code to support constructs such as:
00040 // for (x in oql$functions) s += (bodyof x);
00041 //
00042 
00043 #define NEW_OPIDENT_PREEVAL
00044 
00045 oqmlStatus *
00046 oqml_opident_compile(oqmlNode *, Database *db, oqmlContext *ctx,
00047                      oqmlNode *ql, char *&ident)
00048 {
00049   free(ident); ident = 0;
00050 
00051   oqmlStatus *s = ql->compile(db, ctx);
00052   if (s) return s;
00053 
00054   if (ql->getType() == oqmlIDENT)
00055     ident = strdup(((oqmlIdent *)ql)->getName());
00056       
00057   return oqmlSuccess;
00058 }
00059 
00060 oqmlStatus *
00061 oqml_opident_preeval(oqmlNode *node, Database *db, oqmlContext *ctx,
00062                      oqmlNode *ql, char *&ident)
00063 {
00064 #ifdef NEW_OPIDENT_PREEVAL
00065   free(ident); ident = 0;
00066 #else
00067   if (ident)
00068     return oqmlSuccess;
00069 #endif
00070 
00071   oqmlAtomList *al;
00072   oqmlStatus *s = ql->eval(db, ctx, &al);
00073   if (s) return s;
00074   if (al->cnt != 1 || !OQML_IS_IDENT(al->first))
00075     return oqmlStatus::expected(node, "identifier",
00076                                 al->cnt ? al->first->type.getString() : 
00077                                 "nil");
00078 
00079 #ifdef NEW_OPIDENT_PREEVAL
00080   char *id = OQML_ATOM_IDENTVAL(al->first);
00081   oqmlAtomType type;
00082   oqmlAtom *at;
00083   if (ctx->getSymbol(id, &type, &at, 0, 0)) {
00084     if (!at || !OQML_IS_IDENT(at))
00085       return oqmlStatus::expected(node, "identifier", type.getString());
00086     ident = strdup(OQML_ATOM_IDENTVAL(at));
00087     return oqmlSuccess;
00088   }
00089 #endif
00090 
00091   ident = strdup(OQML_ATOM_IDENTVAL(al->first));
00092   return oqmlSuccess;
00093 }
00094 
00095 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00096 //
00097 // oqmlIdent methods
00098 //
00099 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00100 
00101 const char oqml_uninit_fmt[] = "uninitialized identifier '%s'";
00102 
00103 // -----------------------------------------------------------------------
00104 //
00105 // oqmlIdent constructor
00106 //
00107 // -----------------------------------------------------------------------
00108 
00109 oqmlIdent::oqmlIdent(const char * _name) : oqmlNode(oqmlIDENT)
00110 {
00111   name = strdup(_name);
00112   cls = 0;
00113   __class = 0;
00114   cst_atom = 0;
00115 }
00116 
00117 // -----------------------------------------------------------------------
00118 //
00119 // oqmlIdent destructor
00120 //
00121 // -----------------------------------------------------------------------
00122 
00123 oqmlIdent::~oqmlIdent()
00124 {
00125   free(name);
00126 }
00127 
00128 // -----------------------------------------------------------------------
00129 //
00130 // oqmlIdent compile public method
00131 //
00132 // -----------------------------------------------------------------------
00133 
00134 oqmlStatus *
00135 oqmlIdent::compile(Database *db, oqmlContext *ctx)
00136 {
00137   if (ctx->getDotContext())
00138     return oqmlSuccess;
00139 
00140   oqmlAtom *atom;
00141 
00142   oqmlAtomType at;
00143       
00144   if (ctx->getSymbol(name, &at, &atom))
00145     {
00146       if (at.type != oqmlATOM_SELECT)
00147         eval_type = at;
00148       cls = 0;
00149       return oqmlSuccess;
00150     }
00151 
00152   if (ctx->isSelectContext())
00153     {
00154       // added the 7/01/00
00155       const char *xname = name;
00156       /*
00157       if (!strcmp(name, "schema"))
00158         xname = "scheme";
00159         */
00160       // ...
00161 
00162       cls = db->getSchema()->getClass(xname);
00163       
00164       if (cls)
00165         {
00166           eval_type.type = oqmlATOM_OID;
00167           eval_type.cls = cls;
00168         }
00169       else
00170         // changed the 18/10/99
00171         // eval_type.type = oqmlATOM_IDENT;
00172         eval_type.type = oqmlATOM_UNKNOWN_TYPE;
00173     }
00174   else
00175     // changed the 18/10/99
00176     //eval_type.type = oqmlATOM_IDENT;
00177     eval_type.type = oqmlATOM_UNKNOWN_TYPE;
00178   
00179   return oqmlSuccess;
00180 }
00181 
00182 // -----------------------------------------------------------------------
00183 //
00184 // oqmlIdent eval public method
00185 //
00186 // -----------------------------------------------------------------------
00187 
00188 oqmlStatus *
00189 oqmlIdent::eval(Database *db, oqmlContext *ctx, oqmlAtomList **alist,
00190                 oqmlComp *, oqmlAtom *)
00191 {
00192   oqmlAtom *at;
00193   oqmlNode *ql;
00194   oqmlAtomType t;
00195   oqmlFunctionEntry *entry;
00196 
00197   if (cst_atom)
00198     {
00199       *alist = new oqmlAtomList(cst_atom->copy());
00200       return oqmlSuccess;
00201     }
00202 
00203   if (cls)
00204     return evalQuery(db, ctx, alist);
00205 
00206   if (ctx->getSymbol(name, &t, &at))
00207     {
00208       if (!at)
00209         {
00210           *alist = new oqmlAtomList();
00211           return oqmlSuccess;
00212         }
00213 
00214       if (at->type.type == oqmlATOM_SELECT)
00215         {
00216           if (!at->as_select()->list)
00217             {
00218               oqmlStatus *s = at->as_select()->node->eval(db, ctx, alist);
00219               if (s) return s;
00220               at->as_select()->list = (*alist)->copy();
00221               return oqmlSuccess;
00222             }
00223           // added the 1/03/00
00224           else
00225             *alist = at->as_select()->list->copy();
00226         }
00227       else {
00228         if (OQML_IS_OBJ(at)) {
00229           OQL_CHECK_OBJ(at);
00230         }
00231         *alist = new oqmlAtomList(at->copy());
00232       }
00233 
00234       return oqmlSuccess;
00235     }
00236 
00237   /* disconnected the 23/01/00
00238   if (ctx->getFunction(name, &entry))
00239     {
00240       *alist = new oqmlAtomList(new oqmlAtom_ident(name));
00241       return oqmlSuccess;
00242     }
00243 
00244   if (oqmlCall::getBuiltIn(db, name))
00245     {
00246       *alist = new oqmlAtomList(new oqmlAtom_ident(name));
00247       return oqmlSuccess;
00248     }
00249     */
00250 
00251   if (ctx->getFunction(name, &entry)) // should check here the argument number!
00252     return oqmlCall::realizeCall(db, ctx, entry, alist);
00253 
00254   return new oqmlStatus(this, oqml_uninit_fmt, name);
00255 }
00256 
00257 oqmlStatus *oqmlIdent::evalLeft(Database *db, oqmlContext *ctx,
00258                                 oqmlAtom **a, int &idx)
00259 {
00260   idx = -1;
00261   *a = new oqmlAtom_ident(name);
00262   return oqmlSuccess;
00263 }
00264 
00265 // -----------------------------------------------------------------------
00266 //
00267 // oqmlIdent evalType public method
00268 //
00269 // -----------------------------------------------------------------------
00270 
00271 void oqmlIdent::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00272 {
00273   *at = eval_type;
00274 }
00275 
00276 // -----------------------------------------------------------------------
00277 //
00278 // oqmlIdent evalType public method
00279 //
00280 // -----------------------------------------------------------------------
00281 
00282 oqmlBool oqmlIdent::isConstant() const
00283 {
00284   return oqml_False;
00285 }
00286 
00287 // -----------------------------------------------------------------------
00288 //
00289 // oqmlIdent evalType getName method
00290 //
00291 // -----------------------------------------------------------------------
00292 
00293 const char *oqmlIdent::getName() const
00294 {
00295   return name;
00296 }
00297 
00298 // -----------------------------------------------------------------------
00299 //
00300 // oqmlIdent toString public method
00301 //
00302 // -----------------------------------------------------------------------
00303 
00304 std::string
00305 oqmlIdent::toString(void) const
00306 {
00307   return std::string(name) + oqml_isstat();
00308 }
00309 
00310 // -----------------------------------------------------------------------
00311 //
00312 // oqmlIdent initEnumValues public method
00313 //
00314 // -----------------------------------------------------------------------
00315 
00316 void
00317 oqmlIdent::initEnumValues(Database *db, oqmlContext *ctx)
00318 {
00319   const LinkedList *list = db->getSchema()->getClassList();
00320   LinkedListCursor c(list);
00321   Class *cl;
00322   
00323   while (c.getNext((void *&)cl))
00324     if (cl->asEnumClass()) {
00325       int item_cnt;
00326       const EnumItem **items = cl->asEnumClass()->getEnumItems(item_cnt);
00327       for (int i = 0; i < item_cnt; i++) {
00328         oqmlAtom *atom = new oqmlAtom_int(items[i]->getValue());
00329         ctx->setSymbol(items[i]->getName(), &atom->type, atom, oqml_True,
00330                        oqml_True);
00331       }
00332     }
00333 }
00334 
00335 // -----------------------------------------------------------------------
00336 //
00337 // oqmlIdent evalQuery private method
00338 //
00339 // -----------------------------------------------------------------------
00340 
00341 oqmlStatus *
00342 oqmlIdent::evalQuery(Database *db, oqmlContext *ctx, oqmlAtomList **xalist)
00343 {
00344   oqmlAtomList *al;
00345   OQML_MAKE_RBAG(xalist, rlist);
00346 
00347   if (al = ctx->getAndContext())
00348     {
00349       oqmlAtom *a = al->first;
00350       while (a)
00351         {
00352           oqmlAtom *next = a->next;
00353               
00354           if (a->type.type != oqmlATOM_OID)
00355             return oqmlStatus::expected(this, "oid", a->type.getString());
00356               
00357           Status status;
00358           Bool is;
00359           status = cls->isObjectOfClass(&((oqmlAtom_oid *)a)->oid,
00360                                         &is, True);
00361           if (status)
00362             return new oqmlStatus(this, status);
00363               
00364           if (is)
00365             rlist->append(a);
00366               
00367           a = next;
00368         }
00369 
00370       return oqmlSuccess;
00371     }
00372 
00373   if ((void *)cls == db->getSchema()->Schema_Class)
00374     {
00375       const LinkedList *_class = db->getSchema()->getClassList();
00376       LinkedListCursor c(_class);
00377       Class *cl;
00378       while (c.getNext((void *&)cl))
00379         if (!cl->asCollectionClass() && !cl->isSystem())
00380           {
00381             rlist->append(new oqmlAtom_oid(cl->getOid(), cl));
00382             OQML_CHECK_MAX_ATOMS(rlist, ctx, 0);
00383           }
00384 
00385       return oqmlSuccess;
00386     }
00387 
00388   Iterator *q = new Iterator(cls, True);
00389   if (q->getStatus())
00390     {
00391       Status s = q->getStatus();
00392       delete q;
00393       return new oqmlStatus(this, s);
00394     }
00395 
00396   return oqml_scan(ctx, q, cls, rlist);
00397 }
00398 
00399 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00400 //
00401 // unset unary operator methods
00402 //
00403 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00404 
00405 oqmlUnset::oqmlUnset(oqmlNode * _ql) : oqmlNode(oqmlUNSET)
00406 {
00407   ql = _ql;
00408   ident = 0;
00409 }
00410 
00411 oqmlUnset::~oqmlUnset()
00412 {
00413   free(ident);
00414 }
00415 
00416 oqmlStatus *oqmlUnset::compile(Database *db, oqmlContext *ctx)
00417 {
00418   if (ql->getType() == oqmlIDENT)
00419     {
00420       ident = strdup(((oqmlIdent *)ql)->getName());
00421       return oqmlSuccess;
00422     }
00423 
00424   if (ql->getType() == oqmlARRAY)
00425     return ql->compile(db, ctx);
00426 
00427   return new oqmlStatus(this, "identifier or array element expected");
00428 }
00429 
00430 oqmlStatus *oqmlUnset::eval(Database *db, oqmlContext *ctx,
00431                             oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00432 {
00433   *alist = new oqmlAtomList();
00434 
00435   if (ident)
00436     {
00437       oqmlAtomType at;
00438       oqmlBool global;
00439 
00440       if (ctx->getSymbol(ident, 0, 0, &global))
00441         {
00442           if (!global)
00443             return new oqmlStatus(this, "cannot unset local symbol '%s'",
00444                                   ident);
00445           ctx->popSymbol(ident, global);
00446         }
00447 
00448       return oqmlSuccess;
00449     }
00450 
00451   return oqmlSuccess;
00452 }
00453 
00454 void oqmlUnset::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00455 {
00456   *at = eval_type;
00457 }
00458 
00459 oqmlBool oqmlUnset::isConstant() const
00460 {
00461   return oqml_False;
00462 }
00463 
00464 std::string
00465 oqmlUnset::toString(void) const
00466 {
00467   if (is_statement)
00468     return std::string("unset ") + ql->toString() + "; ";
00469   return std::string("(unset ") + ql->toString() + ")";
00470 }
00471 
00472 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00473 //
00474 // isset unary operator methods
00475 //
00476 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00477 
00478 oqmlIsset::oqmlIsset(oqmlNode *_ql) : oqmlNode(oqmlISSET)
00479 {
00480   ql = _ql;
00481   ident = 0;
00482   eval_type.type = oqmlATOM_BOOL;
00483 }
00484 
00485 oqmlIsset::~oqmlIsset()
00486 {
00487   free(ident);
00488 }
00489 
00490 oqmlStatus *oqmlIsset::compile(Database *db, oqmlContext *ctx)
00491 {
00492   return oqml_opident_compile(this, db, ctx, ql, ident);
00493 }
00494 
00495 oqmlStatus *oqmlIsset::eval(Database *db, oqmlContext *ctx,
00496                           oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00497 {
00498   oqmlStatus *s = oqml_opident_preeval(this, db, ctx, ql, ident);
00499   if (s) return s;
00500 
00501   oqmlAtomType at;
00502 
00503   if (ctx->getSymbol(ident, &at))
00504     *alist = new oqmlAtomList(new oqmlAtom_bool(oqml_True));
00505   else
00506     *alist = new oqmlAtomList(new oqmlAtom_bool(oqml_False));
00507 
00508   return oqmlSuccess;
00509 }
00510 
00511 void oqmlIsset::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00512 {
00513   *at = eval_type;
00514 }
00515 
00516 oqmlBool oqmlIsset::isConstant() const
00517 {
00518   return oqml_False;
00519 }
00520 
00521 std::string
00522 oqmlIsset::toString(void) const
00523 {
00524   const char *sident = (ident ? ident : "<null>");
00525   if (is_statement)
00526     return std::string("isset ") + sident + "; ";
00527   return std::string("(isset ") + sident + ")";
00528 }
00529 
00530 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00531 //
00532 // oqmlValRefOf methods
00533 //
00534 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00535 
00536 char *
00537 oqmlValRefOf::makeIdent(oqmlContext *ctx, const char *ident)
00538 {
00539   if (strncmp(ident, oqml_global_scope, oqml_global_scope_len))
00540     {
00541       oqmlBool global;
00542       if (!ctx->getSymbol(ident, 0, 0, &global) || global)
00543         return strdup((std::string(oqml_global_scope) + ident).c_str());
00544     }
00545 
00546   return strdup(ident);
00547 }
00548 
00549 oqmlValRefOf::oqmlValRefOf(oqmlNode * _ql, oqmlTYPE _type,
00550                            const char *_opstr) : oqmlNode(_type)
00551 {
00552   ql = _ql;
00553   ident = 0;
00554   opstr = strdup(_opstr);
00555 }
00556 
00557 oqmlValRefOf::~oqmlValRefOf()
00558 {
00559   free(ident);
00560   free(opstr);
00561 }
00562 
00563 oqmlStatus *oqmlValRefOf::realizeIdent(Database *db, oqmlContext *ctx)
00564 {
00565   if (ident)
00566     return oqmlSuccess;
00567 
00568   oqmlAtom *a;
00569   int idx;
00570   oqmlStatus *s;
00571 
00572   if (ql->getType() == oqmlREFOF)
00573     {
00574       oqmlRefOf *refof = (oqmlRefOf *)ql;
00575       ident = refof->ident ? strdup(refof->ident) : 0;
00576 
00577       if (ident)
00578         return oqmlSuccess;
00579 
00580       oqmlAtomList *al;
00581       s = ql->eval(db, ctx, &al);
00582       if (s) return s;
00583       if (al->cnt != 1)
00584         return new oqmlStatus(this, "identifier expected.");
00585       a = al->first;
00586       idx = 0;
00587     }
00588   else
00589     {
00590       s = ql->evalLeft(db, ctx, &a, idx);
00591       if (s) return s;
00592     }
00593 
00594   if (a->as_ident())
00595     {
00596       ident = makeIdent(ctx, OQML_ATOM_IDENTVAL(a));
00597       return oqmlSuccess;
00598     }
00599 
00600   if (a->as_list())
00601     {
00602       oqmlAtom *x = a->as_list()->list->getAtom(idx);
00603       if (x->as_ident())
00604         {
00605           char *xident = makeIdent(ctx, OQML_ATOM_IDENTVAL(x));
00606           oqmlAtom_ident *tmp = new oqmlAtom_ident(xident);
00607           free(xident);
00608 
00609           const char *tmp_ident = ctx->getTempSymb().c_str();
00610           oqmlAtomType tident(oqmlATOM_IDENT);
00611           ctx->pushSymbol(tmp_ident, &tident, tmp, oqml_False);
00612 
00613           ident = strdup(tmp_ident);
00614           return oqmlSuccess;
00615         }
00616     }
00617 
00618   return new oqmlStatus(this, "identifier expected.");
00619 }
00620 
00621 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00622 //
00623 // oqmlRefOf methods
00624 //
00625 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00626 
00627 oqmlRefOf::oqmlRefOf(oqmlNode * _ql) : oqmlValRefOf(_ql, oqmlREFOF, "&")
00628 {
00629 }
00630 
00631 oqmlRefOf::~oqmlRefOf()
00632 {
00633 }
00634 
00635 oqmlStatus *oqmlRefOf::compile(Database *db, oqmlContext *ctx)
00636 {
00637   oqmlStatus *s;
00638 
00639   free(ident); ident = 0;
00640 
00641   s = ql->compile(db, ctx);
00642   if (s)
00643     return s;
00644 
00645 #ifndef DELAY_IDENT
00646   if (ql->getType() == oqmlIDENT)
00647     ident = makeIdent(ctx, ((oqmlIdent *)ql)->getName());
00648 #endif
00649       
00650   return oqmlSuccess;
00651 }
00652 
00653 oqmlStatus *oqmlRefOf::eval(Database *db, oqmlContext *ctx,
00654                             oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00655 {
00656 #ifdef DELAY_IDENT
00657   if (ql->getType() == oqmlIDENT && !ident)
00658     ident = makeIdent(ctx, ((oqmlIdent *)ql)->getName());
00659 #endif
00660 
00661   oqmlStatus *s;
00662 
00663   s = realizeIdent(db, ctx);
00664   if (s) return s;
00665 
00666   *alist = new oqmlAtomList(new oqmlAtom_ident(ident,
00667                                                ctx->getSymbolEntry(ident)));
00668   return oqmlSuccess;
00669 }
00670 
00671 oqmlStatus *oqmlRefOf::evalLeft(Database *db, oqmlContext *ctx,
00672                                 oqmlAtom **a, int &idx)
00673 {
00674   /*
00675   oqmlStatus *s = realizeIdent(db, ctx);
00676   if (s) return s;
00677 
00678   idx = -1;
00679   *a = new oqmlAtom_ident(ident, ctx->getSymbolEntry(ident));
00680   return oqmlSuccess;
00681   */
00682 
00683   return new oqmlStatus(this, "not a left value.");
00684 }
00685 
00686 void oqmlRefOf::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00687 {
00688   *at = eval_type;
00689 }
00690 
00691 oqmlBool oqmlRefOf::isConstant() const
00692 {
00693   return oqml_False;
00694 }
00695 
00696 std::string
00697 oqmlRefOf::toString(void) const
00698 {
00699   return oqml_unop_string(ql, "&", is_statement);
00700 }
00701 
00702 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00703 //
00704 // oqmlValOf methods
00705 //
00706 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00707 
00708 oqmlValOf::oqmlValOf(oqmlNode * _ql) : oqmlValRefOf(_ql, oqmlVALOF, "*")
00709 {
00710 }
00711 
00712 oqmlValOf::~oqmlValOf()
00713 {
00714 }
00715 
00716 oqmlStatus *oqmlValOf::compile(Database *db, oqmlContext *ctx)
00717 {
00718   oqmlStatus *s;
00719 
00720   free(ident); ident = 0;
00721 
00722   s = ql->compile(db, ctx);
00723   if (s)
00724     return s;
00725 
00726 #ifndef DELAY_IDENT
00727   if (ql->getType() == oqmlIDENT)
00728     ident = makeIdent(ctx, ((oqmlIdent *)ql)->getName());
00729 #endif
00730       
00731   return oqmlSuccess;
00732 }
00733 
00734 oqmlStatus *oqmlValOf::eval(Database *db, oqmlContext *ctx,
00735                             oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00736 {
00737 #ifdef DELAY_IDENT
00738   if (ql->getType() == oqmlIDENT && !ident)
00739     ident = makeIdent(ctx, ((oqmlIdent *)ql)->getName());
00740 #endif
00741 
00742   oqmlStatus *s;
00743 
00744   s = realizeIdent(db, ctx);
00745   if (s) return s;
00746 
00747   oqmlAtomType t;
00748   oqmlAtom *a = 0;
00749 
00750   if (!ctx->getSymbol(ident, &t, &a) || !a)
00751     return new oqmlStatus(this, oqml_uninit_fmt, ident);
00752 
00753   oqmlAtom *xa = 0;
00754 
00755   if (ql->getType() == oqmlREFOF)
00756     xa = a;
00757   else
00758     {
00759       if (!a->as_ident())
00760         return new oqmlStatus(this, "value of '%s': identifier expected, "
00761                               "got %s", ident, a->type.getString());
00762 
00763       oqmlSymbolEntry *entry = a->as_ident()->entry;
00764 
00765       if (entry)
00766         xa = entry->at;
00767 
00768       if (!xa && !ctx->getSymbol(OQML_ATOM_IDENTVAL(a), &t, &xa) || !a)
00769         return new oqmlStatus(this, oqml_uninit_fmt, OQML_ATOM_IDENTVAL(a));
00770     }
00771 
00772   *alist = new oqmlAtomList(xa);
00773   return oqmlSuccess;
00774 }
00775 
00776 oqmlStatus *oqmlValOf::evalLeft(Database *db, oqmlContext *ctx,
00777                                 oqmlAtom **a, int &idx)
00778 {
00779   oqmlStatus *s = realizeIdent(db, ctx);
00780   if (s) return s;
00781 
00782   idx = -1;
00783   oqmlAtomType t;
00784   oqmlAtom *ta;
00785 
00786   if (!ctx->getSymbol(ident, &t, &ta) || !ta)
00787     return new oqmlStatus(this, "identifier '%s' is not initialized.", ident);
00788 
00789   if (ql->getType() == oqmlREFOF)
00790     *a = ta;
00791   else
00792     {
00793       if (!ta->as_ident())
00794         return new oqmlStatus(this, "value of '%s': identifier expected, "
00795                               "got %s", ident, ta->type.getString());
00796 
00797       *a = ta->as_ident();
00798     }
00799 
00800   return oqmlSuccess;
00801 }
00802 
00803 void oqmlValOf::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00804 {
00805   *at = eval_type;
00806 }
00807 
00808 oqmlBool oqmlValOf::isConstant() const
00809 {
00810   return oqml_False;
00811 }
00812 
00813 std::string
00814 oqmlValOf::toString(void) const
00815 {
00816   return oqml_unop_string(ql, "*", is_statement);
00817 }
00818 
00819 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00820 //
00821 // oqmlScopeOf operator methods
00822 //
00823 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00824 
00825 oqmlScopeOf::oqmlScopeOf(oqmlNode *_ql) : oqmlNode(oqmlSCOPEOF)
00826 {
00827   ql = _ql;
00828   ident = 0;
00829   eval_type.type = oqmlATOM_STRING;
00830 }
00831 
00832 oqmlScopeOf::~oqmlScopeOf()
00833 {
00834   free(ident);
00835 }
00836 
00837 oqmlStatus *oqmlScopeOf::compile(Database *db, oqmlContext *ctx)
00838 {
00839   return oqml_opident_compile(this, db, ctx, ql, ident);
00840 }
00841 
00842 oqmlStatus *oqmlScopeOf::eval(Database *db, oqmlContext *ctx, oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00843 {
00844   oqmlStatus *s = oqml_opident_preeval(this, db, ctx, ql, ident);
00845   if (s) return s;
00846 
00847   oqmlBool global;
00848 
00849   if (ctx->getSymbol(ident, 0, 0, &global))
00850     {
00851       (*alist) = new oqmlAtomList(new oqmlAtom_string
00852                                   (global ? "global" : "local"));
00853       return oqmlSuccess;
00854     }
00855 
00856   return new oqmlStatus(this, oqml_uninit_fmt, ident);
00857 }
00858 
00859 void oqmlScopeOf::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00860 {
00861   *at = eval_type;
00862 }
00863 
00864 oqmlBool oqmlScopeOf::isConstant() const
00865 {
00866   return oqml_False;
00867 }
00868 
00869 std::string
00870 oqmlScopeOf::toString(void) const
00871 {
00872   if (is_statement)
00873     return std::string("scopeof ") + ident + "; ";
00874   return std::string("(scopeof ") + ident + ")";
00875 }
00876 
00877 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00878 //
00879 // oqmlPush operator methods
00880 //
00881 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00882 
00883 oqmlPush::oqmlPush(const char *_ident) : oqmlNode(oqmlPUSH)
00884 {
00885   ident = strdup(_ident);
00886 }
00887 
00888 oqmlPush::~oqmlPush()
00889 {
00890   free(ident);
00891 }
00892 
00893 oqmlStatus *oqmlPush::compile(Database *db, oqmlContext *ctx)
00894 {
00895   return oqmlSuccess;
00896 }
00897 
00898 oqmlStatus *oqmlPush::eval(Database *db, oqmlContext *ctx, oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00899 {
00900   oqmlAtomType at;
00901   oqmlStatus *s = ctx->pushSymbol(ident, &at, 0, oqml_False);
00902   if (s) return s;
00903   (*alist) = new oqmlAtomList(new oqmlAtom_ident(ident));
00904   return oqmlSuccess;
00905 }
00906 
00907 void oqmlPush::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00908 {
00909   *at = eval_type;
00910 }
00911 
00912 oqmlBool oqmlPush::isConstant() const
00913 {
00914   return oqml_False;
00915 }
00916 
00917 std::string
00918 oqmlPush::toString(void) const
00919 {
00920   return std::string("(push ") + ident + ")" + oqml_isstat();
00921 }
00922 
00923 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00924 //
00925 // oqmlPop operator methods
00926 //
00927 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00928 
00929 oqmlPop::oqmlPop(const char *_ident) : oqmlNode(oqmlPOP)
00930 {
00931   ident = strdup(_ident);
00932 }
00933 
00934 oqmlPop::~oqmlPop()
00935 {
00936   free(ident);
00937 }
00938 
00939 oqmlStatus *oqmlPop::compile(Database *db, oqmlContext *ctx)
00940 {
00941   return oqmlSuccess;
00942 }
00943 
00944 oqmlStatus *oqmlPop::eval(Database *db, oqmlContext *ctx, oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00945 {
00946   oqmlStatus *s;
00947   oqmlAtom *a = 0;
00948   oqmlBool global;
00949 
00950   if (!ctx->getSymbol(ident, 0, &a, &global))
00951     return new oqmlStatus(this, oqml_uninit_fmt, ident);
00952 
00953   if (global)
00954     return new oqmlStatus(this, "cannot pop global symbol '%s'", ident);
00955 
00956   s = ctx->popSymbol(ident, oqml_False);
00957   if (s) return s;
00958   (*alist) = new oqmlAtomList(a);
00959   return oqmlSuccess;
00960 }
00961 
00962 void oqmlPop::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00963 {
00964   *at = eval_type;
00965 }
00966 
00967 oqmlBool oqmlPop::isConstant() const
00968 {
00969   return oqml_False;
00970 }
00971 
00972 std::string
00973 oqmlPop::toString(void) const
00974 {
00975   return std::string("(pop ") + ident + ")" + oqml_isstat();
00976 }
00977 }

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