示例#1
0
static void describe_internal( VMachine *vm, String &tgt, const Item *elem, int32 level, int32 maxLevel, int32 maxSize )
{
   uint32 count;

   // return if we reached the maximum level.
   if ( maxLevel >= 0 && level > maxLevel )
   {
      tgt += "...";
      return;
   }

   switch( elem->type() )
   {
      case FLC_ITEM_NIL:
         tgt += "Nil";
      break;

      case FLC_ITEM_UNB:
         tgt += "_";
      break;


      case FLC_ITEM_BOOL:
         tgt += elem->asBoolean() ? "true" : "false";
      break;


      case FLC_ITEM_INT:
         tgt.writeNumber( elem->asInteger() );
      break;

      case FLC_ITEM_NUM:
         tgt.writeNumber( elem->asNumeric(), "%g" );
      break;

      case FLC_ITEM_RANGE:
         elem->toString(tgt);
      break;

      case FLC_ITEM_STRING:
         tgt += "\"";
         if ( maxSize < 0 || elem->asString()->length() < (uint32) maxSize )
         {
            tgt += *elem->asString();
            tgt += "\"";
         }
         else {
            tgt += elem->asString()->subString(0, maxSize );
            tgt += " ... \"";
         }
      break;

      case FLC_ITEM_LBIND:
         tgt += "&";
         tgt += *elem->asLBind();
         if (elem->isFutureBind())
         {
            tgt +="|";
            describe_internal( vm, tgt, &elem->asFutureBind(), level+1, maxLevel, maxSize );
         }
      break;

      case FLC_ITEM_MEMBUF:
      {
         MemBuf *mb = elem->asMemBuf();
         tgt += "MB(";
         tgt.writeNumber( (int64) mb->length() );
         tgt += ",";
         tgt.writeNumber( (int64) mb->wordSize() );
         tgt += ")";

         tgt += " [";

         String fmt;
         int limit = 0;
         switch ( mb->wordSize() )
         {
            case 1: fmt = "%02" LLFMT "X"; limit = 24; break;
            case 2: fmt = "%04" LLFMT "X"; limit = 12; break;
            case 3: fmt = "%06" LLFMT "X"; limit = 9; break;
            case 4: fmt = "%08" LLFMT "X"; limit = 6; break;
         }

         uint32 max = maxSize < 0 || mb->length() < (uint32) maxSize ? mb->length() : (uint32) maxSize;
         for( count = 0; count < max; count++ )
         {
            tgt.writeNumber( (int64)  mb->get( count ), fmt );
            tgt += " ";
         }
         if ( count == (uint32) maxSize )
            tgt += " ...";
         tgt += "]";
      }
      break;

      case FLC_ITEM_ARRAY:
      {
         CoreArray *arr = elem->asArray();
         tgt += "[";

         if ( level == maxLevel )
         {
            tgt += "...]";
            break;
         }

         for( count = 0; count < arr->length(); count++ ) {
            if ( count == 0 ) tgt += " ";

            describe_internal( vm, tgt, & ((*arr)[count]), level + 1, maxLevel, maxSize );

            if ( count + 1 < arr->length() )
               tgt += ", ";
         }

         tgt +="]";
      }
      break;

      case FLC_ITEM_DICT:
      {
         CoreDict *dict = elem->asDict();
         if( dict->isBlessed() )
            tgt += "*";

         tgt += "[";

         if ( level == maxLevel )
         {
            tgt += "...=>...]";
            break;
         }

         if ( dict->length() == 0 )
         {
            tgt += "=>]";
            break;
         }

         Item key, value;
         Iterator iter( &dict->items() );

         // separate the first loop to be able to add ", "
         describe_internal( vm, tgt, &iter.getCurrentKey(), level + 1, maxLevel, maxSize );
         tgt += " => ";
         describe_internal( vm, tgt, &iter.getCurrent(), level + 1, maxLevel, maxSize );
         iter.next();
         while( iter.hasCurrent() )
         {
            tgt += ", ";
            describe_internal( vm, tgt, &iter.getCurrentKey(), level + 1, maxLevel, maxSize );
            tgt += " => ";
            describe_internal( vm, tgt, &iter.getCurrent(), level + 1, maxLevel, maxSize );
            iter.next();
         }

         tgt += "]";
      }
      break;

      case FLC_ITEM_OBJECT:
      {
         CoreObject *arr = elem->asObjectSafe();
         tgt += arr->generator()->symbol()->name() + "(){ ";

         if ( level == maxLevel )
         {
            tgt += "...}";
            break;
         }

         const PropertyTable &pt = arr->generator()->properties();

         for( count = 0; count < pt.added() ; count++ )
         {
            const String &propName = *pt.getKey( count );
			
			// write only?
			if ( pt.getEntry( count ).isWriteOnly() )
			{
				tgt.A( "(" ).A( propName ).A(")");
			}
			else
			{
				Item dummy;
				arr->getProperty( propName, dummy );

				// in describe skip methods.
				if ( dummy.isFunction() || dummy.isMethod() )
				   continue;
				
				tgt += propName + " = ";

				describe_internal( vm, tgt, &dummy, level + 1, maxLevel, maxSize );
			}

            if (count+1 < pt.added())
            {
               tgt += ", ";
            }
         }

         tgt += "}";
      }
      break;

      case FLC_ITEM_CLASS:
         tgt += "Class " + elem->asClass()->symbol()->name();
      break;

      case FLC_ITEM_METHOD:
      {
         tgt += "(";
         Item itemp;
         elem->getMethodItem( itemp );
         describe_internal( vm, tgt, &itemp, level + 1, maxLevel, maxSize );
         tgt += ").";
         tgt += elem->asMethodFunc()->name() + "()";
      }
      break;

      case FLC_ITEM_CLSMETHOD:
         tgt += "Class ";
         tgt += elem->asMethodClassOwner()->generator()->symbol()->name();
         tgt += "." + elem->asMethodClass()->symbol()->name() + "()";
      break;

      case FLC_ITEM_FUNC:
      {
         const Symbol *funcSym = elem->asFunction()->symbol();
         tgt += funcSym->name() + "()";
      }
      break;

      case FLC_ITEM_REFERENCE:
         tgt += "->";
         describe_internal( vm, tgt, elem->dereference(), level + 1, maxLevel, maxSize );
      break;

      default:
         tgt += "?";
   }
}
示例#2
0
void inspect_internal( VMachine *vm, const Item *elem, int32 level, int32 maxLevel, int32 maxSize, Item* i_stream, bool add, bool addline )
{

   uint32 count;
   int32 i;
   Stream *stream = i_stream != 0 ?
         dyncast<Stream*>(i_stream->asObjectSafe()->getFalconData()) :
         vm->stdErr();

   // return if we reached the maximum level.
   if ( maxLevel >= 0 && level > maxLevel )
   {
      stream->writeString( "..." );
      if ( addline )
         stream->writeString( "\n" );
      return;
   }

   if ( stream == 0 )
   {
      stream = vm->stdOut();
      if ( stream == 0 )
         return;
   }

   if ( add )
      for ( i = 0; i < level*3; i ++ )
      {
         stream->put( 0x20 ); // space
      }

   if ( elem == 0 ) {
      stream->writeString( "Nothing" );
      if ( addline )
         stream->writeString( "\n" );
      return;
   }

   String temp;

   switch( elem->type() )
   {
      case FLC_ITEM_NIL:
         stream->writeString( "Nil" );
      break;

      case FLC_ITEM_UNB:
            stream->writeString( "_" );
      break;

      case FLC_ITEM_BOOL:
         stream->writeString( elem->asBoolean() ? "true" : "false" );
      break;


      case FLC_ITEM_INT:
         temp.writeNumber( elem->asInteger() );
         stream->writeString( "int(" );
         stream->writeString( temp );
         stream->writeString( ")" );
      break;

      case FLC_ITEM_NUM:
         temp.writeNumber( elem->asNumeric(), "%g" );
         stream->writeString( "num(" );
         stream->writeString( temp );
         stream->writeString( ")" );
      break;

      case FLC_ITEM_RANGE:
         elem->toString(temp);
         stream->writeString( temp );
      break;

      case FLC_ITEM_STRING:
         stream->writeString( "\"" );
         if ( maxSize < 0 || elem->asString()->length() < (uint32) maxSize )
         {
            stream->writeString( *elem->asString() );
            stream->writeString( "\"" );
         }
         else {
            stream->writeString( elem->asString()->subString(0, maxSize ) );
            stream->writeString( " ... \"" );
         }
      break;

      case FLC_ITEM_LBIND:
         stream->writeString( "&" );
         stream->writeString( *elem->asLBind() );
      break;

      case FLC_ITEM_MEMBUF:
      {
         MemBuf *mb = elem->asMemBuf();
         temp = "MemBuf(";
         temp.writeNumber( (int64) mb->length() );
         temp += ",";
         temp.writeNumber( (int64) mb->wordSize() );
         temp += ")";

         if ( maxSize == 0 )
            stream->writeString( temp );
         else {
            temp += " [\n";

            String fmt;
            int limit = 0;
            switch ( mb->wordSize() )
            {
               case 1: fmt = "%02" LLFMT "X"; limit = 24; break;
               case 2: fmt = "%04" LLFMT "X"; limit = 12; break;
               case 3: fmt = "%06" LLFMT "X"; limit = 9; break;
               case 4: fmt = "%08" LLFMT "X"; limit = 6; break;
            }

            int written = 0;
            uint32 max = maxSize < 0 || mb->length() < (uint32) maxSize ? mb->length() : (uint32) maxSize;
            for( count = 0; count < max; count++ )
            {
               temp.writeNumber( (int64)  mb->get( count ), fmt );
               temp += " ";
               written ++;
               if ( written == limit )
               {
                  temp += "\n";
                  written = 0;
               }
               stream->writeString( temp );
               temp = "";
            }
            if ( count == (uint32) maxSize )
               stream->writeString( " ... " );
            stream->writeString( "]" );
         }
      }
      break;

      case FLC_ITEM_ARRAY:
      {
         CoreArray *arr = elem->asArray();
         temp = "Array[";
         temp.writeNumber( (int64) arr->length() );
         temp += "]";
         stream->writeString( temp );

         if ( level == maxLevel )
         {
            stream->writeString( "{...}" );
            break;
         }

         stream->writeString( "{\n" );

         for( count = 0; count < arr->length(); count++ ) {
            inspect_internal( vm, & ((*arr)[count]), level + 1, maxLevel, maxSize, i_stream, true, true );
         }

         for ( i = 0; i < level; i ++ )
         {
            stream->writeString( "   " );
         }
         stream->writeString( "}" );
      }
      break;

      case FLC_ITEM_DICT:
      {
         CoreDict *dict = elem->asDict();
         temp = "Dict[";
         temp.writeNumber( (int64) dict->length() );
         temp += "]";
         stream->writeString( temp );

         if ( level == maxLevel )
         {
            stream->writeString( "{...}" );
            break;
         }

         stream->writeString( "{\n" );

         Iterator iter( &dict->items() );
         while( iter.hasCurrent() )
         {
            inspect_internal( vm, &iter.getCurrentKey(), level + 1, maxLevel, maxSize, i_stream, true, false );
            stream->writeString( " => " );
            inspect_internal( vm, &iter.getCurrent(), level + 1, maxLevel, maxSize, i_stream, false, true );
            iter.next();
         }
         for ( i = 0; i < level; i ++ )
         {
            stream->writeString("   ");
         }
         stream->writeString( "}" );
      }
      break;

      case FLC_ITEM_OBJECT:
      {
         CoreObject *arr = elem->asObjectSafe();
         stream->writeString( "Object of class " + arr->generator()->symbol()->name() );
         if ( level == maxLevel )
         {
            stream->writeString( "{...}" );
            break;
         }

         stream->writeString( " {\n" );
         const PropertyTable &pt = arr->generator()->properties();

         for( count = 0; count < pt.added() ; count++ )
         {
            for ( i = 0; i < (level+1); i ++ )
            {
               stream->writeString("   ");
            }
            const String &propName = *pt.getKey( count );
			
			if ( pt.getEntry(count).isWriteOnly() )
			{
				stream->writeString( "(" );
				stream->writeString( propName + ")\n" );
			}
			else 
			{
				stream->writeString( propName + " => " );
				Item dummy;
				arr->getProperty( propName, dummy);
				inspect_internal( vm, &dummy, level + 1, maxLevel, maxSize, i_stream, false, true );
			}
         }
         for ( i = 0; i < level; i ++ )
         {
            stream->writeString("   ");
         }
         stream->writeString( "}" );
      }
      break;

      case FLC_ITEM_CLASS:
         stream->writeString( "Class " + elem->asClass()->symbol()->name() );
      break;

      case FLC_ITEM_METHOD:
      {
         temp = "Method ";
         temp += "->" + elem->asMethodFunc()->name();
         stream->writeString( temp );

         Item itemp;
         elem->getMethodItem( itemp );

         inspect_internal( vm, &itemp, level + 1, maxLevel, maxSize, i_stream, true, true );
         for ( i = 0; i < level; i ++ )
         {
            stream->writeString("   ");
         }
         stream->writeString( "}" );
      }
      break;

      case FLC_ITEM_CLSMETHOD:
         temp = "Cls.Method 0x";
         temp.writeNumberHex( (uint64) elem->asMethodClassOwner() );
         temp += "->" + elem->asMethodClass()->symbol()->name();
         stream->writeString( temp );
      break;

      case FLC_ITEM_FUNC:
      {
         const Symbol *funcSym = elem->asFunction()->symbol();

         if ( funcSym->isExtFunc() )
         {
            stream->writeString( "Ext. Function " + funcSym->name() );
         }
         else {
            stream->writeString( "Function " + funcSym->name() );

            FuncDef *def = funcSym->getFuncDef();
            uint32 itemId = def->onceItemId();
            if ( itemId != FuncDef::NO_STATE )
            {
               if ( elem->asFunction()->liveModule()->globals()[ itemId ].isNil() )
                  stream->writeString( "{ not called }");
               else
                  stream->writeString( "{ called }");
            }
         }
      }
      break;

      case FLC_ITEM_REFERENCE:
         stream->writeString( "Ref to " );
         inspect_internal( vm, elem->dereference(), level + 1, maxLevel, maxSize, i_stream, false, true );
      break;

      default:
         stream->writeString( "Invalid type");
   }
   if ( addline )
      stream->writeString( "\n" );

   stream->flush();
}