Logo Search packages:      
Sourcecode: falconpl version File versions  Download package

bool Falcon::VMachine::functionalEval ( const Item itm  ) 

Evaluate the item in a functional context. The function return either true or false, evaluating the item as a funcional token. # If the item is an array, it is recursively scanned. # If the item is a callable item (including callable arrayas), it is called and then the return value is evaluated in a non-functional context (plain evaluation). # In all the other cases, the item is evaluated in a non-functional context.

More simply, if the item is callable is called, and is result is checked for Falcon truth value. If not, it's simply checked.

The return value will be in regA(), and it's the "reduced" list of items.

The function returns true if it has to stop for frame evaluation, false if the caller can loop. When the function returns true, the caller must immediately return to the calling frame; in case it needs to continue processing, it must install a frame return handler to be called back when the frame created by functionalEval is done.

Returns:
false if the caller can proceed, true if it must return.

Definition at line 2959 of file vm.cpp.

References addLocals(), Falcon::Item::asArray(), callFrame(), callReturn(), createFrame(), Falcon::CoreArray::elements(), Falcon::Item::isArray(), Falcon::CoreArray::length(), local(), m_stack, pushParameter(), and returnHandler().

{
   // An array
   if ( itm.isArray() )
   {
      createFrame(0);

      CoreArray *arr = itm.asArray();

      // great. Then recursively evaluate the parameters.
      uint32 count = arr->length();
      if ( count > 0 )
      {
         // if the first element is an ETA function, just call it as frame and return.
         if ( (*arr)[0].isFunction() && (*arr)[0].asFunction()->isEta() )
         {
            callFrame( arr, 0 );
            return true;
         }

         // create two locals; we may need it
         addLocals( 2 );
         // time to install our handleres
         returnHandler( vm_func_eval );
         *local(0) = itm;
         *local(1) = (int64)0;

         for ( uint32 l = 0; l < count; l ++ )
         {
            const Item &citem = (*arr)[l];
            *local(1) = (int64)l+1;
            if ( functionalEval( citem ) )
            {
               return true;
            }

            pushParameter( m_regA );
         }
         // we got nowere to go
         returnHandler( 0 );

         // is there anything to call? -- is the first element an atom?
         // local 2 is the first element we have pushed
         if( local(2)->isCallable() )
         {
            callFrame( *local(2), count-1 );
            return true;
         }
      }

      // if the first element is not callable, generate an array
      CoreArray *array = new CoreArray( this, count );
      Item *data = array->elements();
      int32 base = m_stack->size() - count;

      for ( uint32 i = 0; i < count; i++ ) {
         data[ i ] = m_stack->itemAt(i + base);
      }
      array->length( count );
      m_regA = array;
      callReturn();
   }
   else
   {
      m_regA = itm;
   }

   return false;
}


Generated by  Doxygen 1.6.0   Back to index