// // aegis - project change supervisor // Copyright (C) 1994-1996, 2002-2008 Peter Miller // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see // . // #include #include #include #include #include #include #include #include #include #include rpt_expr::~rpt_expr() { trace(("rpt_expr::~rpt_expr(%08lX)\n", (long)this)); delete [] child; } rpt_expr::rpt_expr() : child(0), nchild(0), nchild_max(0) { trace(("rpt_expr::rpt_expr(%08lX)\n", (long)this)); } void rpt_expr::append(const rpt_expr::pointer &ep) { trace(("rpt_expr_append(this = %08lX, ep = %08lX)\n{\n", (long)this, (long)ep.get())); if (nchild >= nchild_max) { size_t new_nchild_max = nchild_max * 2 + 4; rpt_expr::pointer *new_child = new rpt_expr::pointer [new_nchild_max]; for (size_t j = 0; j < nchild; ++j) new_child[j] = child[j]; delete [] child; child = new_child; nchild_max = new_nchild_max; } child[nchild++] = ep; // // update the parent's position // if (ep->pos) { if (!pos) pos = ep->pos; else pos = rpt_position::join(pos, ep->pos); assert(pos); trace(("pos = \"%s\" %ld;\n", pos->get_file_name().c_str(), pos->get_line_number())); } else { trace(("pos = NULL\n")); } trace(("}\n")); } void rpt_expr::prepend(const rpt_expr::pointer &ep) { trace(("rpt_expr::prepend(this = %08lX, ep = %08lX)\n{\n", (long)this, (long)ep.get())); if (nchild >= nchild_max) { size_t new_nchild_max = nchild_max * 2 + 4; rpt_expr::pointer *new_child = new rpt_expr::pointer [new_nchild_max]; for (size_t j = 0; j < nchild; ++j) new_child[j + 1] = child[j]; delete [] child; child = new_child; nchild_max = new_nchild_max; } else { for (size_t j = nchild; j > 0; --j) child[j] = child[j - 1]; } nchild++; child[0] = ep; // // update the parent's position // //assert(ep->pos); if (ep->pos) { if (!pos) pos = ep->pos; else pos = rpt_position::join(pos, ep->pos); assert(pos); } trace(("}\n")); } void rpt_expr::parse_error(const char *fmt) const { assert(pos); rpt_lex_error(pos, fmt); } bool rpt_expr::lvalue() const { return false; } rpt_value::pointer rpt_expr::evaluate(bool resolve_deferred, bool deref) const { trace(("rpt_expr::execute(this = %08lX, resdef = %d, deref = %d)\n{\n", (long)this, resolve_deferred, deref)); if (pos) { trace(("%s\n", pos->representation().c_str())); } rpt_value::pointer result = evaluate(); trace(("resolve_deferred = %s\n", (resolve_deferred ? "true" : "false"))); trace(("result->name() = \"%s\"\n", result->name())); if (deref) { rpt_value_reference *rvrp = dynamic_cast(result.get()); if (rvrp) { trace(("dereference\n")); result = rvrp->get(); assert(!dynamic_cast(result.get())); } } if (resolve_deferred) { result = rpt_value::undefer(result); } trace(("return %08lX\n", (long)result.get())); trace(("}\n")); return result; } rpt_expr::pointer rpt_expr::nth_child(size_t n) const { if (n >= nchild) return pointer(); return child[n]; }