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 #include "oql_p.h"
00026
00027
00028 #define DELAY_IDENT
00029
00030 namespace eyedb {
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
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
00098
00099
00100
00101 const char oqml_uninit_fmt[] = "uninitialized identifier '%s'";
00102
00103
00104
00105
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
00120
00121
00122
00123 oqmlIdent::~oqmlIdent()
00124 {
00125 free(name);
00126 }
00127
00128
00129
00130
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
00155 const char *xname = name;
00156
00157
00158
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
00171
00172 eval_type.type = oqmlATOM_UNKNOWN_TYPE;
00173 }
00174 else
00175
00176
00177 eval_type.type = oqmlATOM_UNKNOWN_TYPE;
00178
00179 return oqmlSuccess;
00180 }
00181
00182
00183
00184
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
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
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251 if (ctx->getFunction(name, &entry))
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
00268
00269
00270
00271 void oqmlIdent::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00272 {
00273 *at = eval_type;
00274 }
00275
00276
00277
00278
00279
00280
00281
00282 oqmlBool oqmlIdent::isConstant() const
00283 {
00284 return oqml_False;
00285 }
00286
00287
00288
00289
00290
00291
00292
00293 const char *oqmlIdent::getName() const
00294 {
00295 return name;
00296 }
00297
00298
00299
00300
00301
00302
00303
00304 std::string
00305 oqmlIdent::toString(void) const
00306 {
00307 return std::string(name) + oqml_isstat();
00308 }
00309
00310
00311
00312
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
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
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
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
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
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
00676
00677
00678
00679
00680
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
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
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
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
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 }