Example #1
0
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;
}
Example #2
0
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;
}