void TopLevelStatementBlock::parseInit(int64 po) { QORE_TRACE("TopLevelStatementBlock::parseInit"); //printd(5, "TopLevelStatementBlock::parseInit(rns=%p) first=%d\n", &rns, first); if (!first && lvars) { // push already-registered local variables on the stack for (unsigned i = 0; i < lvars->size(); ++i) push_top_level_local_var(lvars->lv[i], loc); } // resolve global variables before initializing the top-level statements qore_root_ns_private::parseResolveGlobalVars(); int lvids = parseInitIntern(0, PF_TOP_LEVEL, hwm); //printd(5, "TopLevelStatementBlock::parseInit(rns=%p) first=%d, lvids=%d\n", &rns, first, lvids); if (!first && lvids) { parseException("ILLEGAL-TOP-LEVEL-LOCAL-VARIABLE", "local variables declared with 'my' in the top-level block of a Program object can only be declared in the very first code block parsed"); // discard variables immediately for (int i = 0; i < lvids; ++i) pop_local_var(); } // now initialize root namespace and functions before local variables are popped off the stack qore_root_ns_private::parseInit(); if (first) { // if parsing a module, then initialize the init function QoreModuleDefContext* qmd = get_module_def_context(); if (qmd) qmd->parseInit(); // this call will pop all local vars off the stack setupLVList(lvids); first = false; } else if (lvars) { for (unsigned i = 0; i < lvars->size(); ++i) pop_local_var(); } assert(!getVStack()); //printd(5, "TopLevelStatementBlock::parseInitTopLevel(this=%p): done (lvars=%p, %d vars, vstack = %p)\n", this, lvars, lvids, getVStack()); return; }
int SwitchStatement::parseInitImpl(LocalVar *oflag, int pflag) { int lvids = 0; // turn off top-level flag for statement vars pflag &= (~PF_TOP_LEVEL); const QoreTypeInfo *argTypeInfo = 0; if (sexp) sexp = sexp->parseInit(oflag, pflag, lvids, argTypeInfo); CaseNode *w = head; ExceptionSink xsink; QoreProgram *pgm = getProgram(); while (w) { if (w->val) { argTypeInfo = 0; w->val = w->val->parseInit(oflag, pflag | PF_CONST_EXPRESSION, lvids, argTypeInfo); if (lvids) { parse_error("illegal local variable declaration in assignment expression for case block"); while (lvids--) pop_local_var(); w = w->next; continue; } // evaluate case expression if necessary and no parse expressions have been raised if (w->val && !w->val->is_value()) { if (pgm->parseExceptionRaised()) { w = w->next; continue; } ReferenceHolder<AbstractQoreNode> v(w->val->eval(&xsink), &xsink); if (!xsink) { w->val->deref(&xsink); w->val = v.release(); if (!w->val) w->val = nothing(); } else qore_program_private::addParseException(pgm, xsink); } //printd(5, "SwitchStatement::parseInit() this=%p case exp: %p %s\n", this, w->val, get_type_name(w->val)); // check for duplicate values CaseNode *cw = head; while (cw != w) { // Check only the simple case blocks (case 1: ...), // not those with relational operators. Could be changed later to provide more checking. // note that no exception can be raised here as the case node values are parse values if (w->isCaseNode() && cw->isCaseNode() && !compareHard(w->val, cw->val, &xsink)) parse_error("duplicate case values in switch"); assert(!xsink); cw = cw->next; } } if (w->code) w->code->parseInitImpl(oflag, pflag); w = w->next; } // save local variables if (lvids) lvars = new LVList(lvids); return 0; }