示例#1
0
int ForEachStatement::execIterator(AbstractIteratorHelper& aih, QoreValue& return_value, ExceptionSink* xsink) {
   // execute "foreach" body
   unsigned i = 0;

   int rc = 0;

   while (true) {
      bool b = aih.next(xsink);
      if (*xsink)
         return 0;
      if (!b)
         break;

      // get next argument value
      ValueHolder arg(aih.getValue(xsink), xsink);
      //ReferenceHolder<AbstractQoreNode> arg(aih.getValue(xsink), xsink);
      if (*xsink)
         return 0;

      {
         LValueHelper n(var, xsink);
         if (!n)
            break;

         // assign variable to current value in list
         if (n.assign(arg.release()))
            break;
      }

      // set offset in thread-local data for "$#"
      ImplicitElementHelper eh((int)i);

      // execute "foreach" body
      if (((rc = code->execImpl(return_value, xsink)) == RC_BREAK) || *xsink) {
         rc = 0;
         break;
      }

      if (rc == RC_RETURN)
         break;
      else if (rc == RC_CONTINUE)
         rc = 0;
      i++;
   }

   return rc;
}
QoreValue QoreHashMapOperatorNode::mapIterator(AbstractIteratorHelper& h, ExceptionSink* xsink) const {
   ReferenceHolder<QoreHashNode> rv(ref_rv ? new QoreHashNode : 0, xsink);

   qore_size_t i = 0;
   // set offset in thread-local data for "$#"
   while (true) {
      bool has_next = h.next(xsink);
      if (*xsink)
         return QoreValue();
      if (!has_next)
	 break;

      ImplicitElementHelper eh(i++);

      ReferenceHolder<> iv(h.getValue(xsink), xsink);
      if (*xsink)
         return QoreValue();

      // check if value can be mapped
      SingleArgvContextHelper argv_helper(*iv, xsink);

      {
	 ValueEvalRefHolder ekey(e[0], xsink);
	 if (*xsink)
	    return QoreValue();
	 
	 // we have to convert to a string in the default encoding to use a hash key
	 QoreStringValueHelper key(*ekey, QCS_DEFAULT, xsink);
	 if (*xsink)
	    return QoreValue();
	 
	 ValueEvalRefHolder val(e[1], xsink);
	 if (*xsink)
	    return QoreValue();
	 
	 if (ref_rv)
	    rv->setKeyValue(key->getBuffer(), val.getReferencedValue(), xsink);
      }
      // if there is an exception dereferencing one of the evaluted nodes above, then exit the loop
      if (*xsink)
	 return QoreValue();
   }
   
   return rv.release();
}