Open Source Repository

Home /beanshell/bsh-2.0b4 | Repository Home


bsh/BSHEnhancedForStatement.java
package bsh;

// Just testing...
import java.util.*;

/**
   Implementation of the enhanced for(:) statement.  
   This statement uses BshIterable to support iteration over a wide variety
   of iterable types.  Under JDK 1.1 this statement supports primitive and 
   Object arrays, Vectors, and enumerations.  Under JDK 1.2 and later it 
   additionally supports collections.

   @author Daniel Leuck 
   @author Pat Niemeyer
*/
class BSHEnhancedForStatement extends SimpleNode implements ParserConstants 
{
  String varName;

    BSHEnhancedForStatement(int id) { super(id)}

    public Object evalCallStack callstack , Interpreter interpreter )
    throws EvalError 
  {
    Class elementType = null;
    SimpleNode expression, statement=null;

    NameSpace enclosingNameSpace = callstack.top();
    SimpleNode firstNode =((SimpleNode)jjtGetChild(0));
    int nodeCount = jjtGetNumChildren();
    
    if firstNode instanceof BSHType 
    {
      elementType=((BSHType)firstNode).getTypecallstack, interpreter );
      expression=((SimpleNode)jjtGetChild(1));
      if nodeCount>)
        statement=((SimpleNode)jjtGetChild(2));
    else 
    {
      expression=firstNode;
      if nodeCount>)
        statement=((SimpleNode)jjtGetChild(1));
    }

    BlockNameSpace eachNameSpace = new BlockNameSpaceenclosingNameSpace );
    callstack.swapeachNameSpace );

    final Object iteratee = expression.evalcallstack, interpreter );

    if iteratee == Primitive.NULL )
      throw new EvalError("The collection, array, map, iterator, or " +
        "enumeration portion of a for statement cannot be null."
        this, callstack );

    CollectionManager cm = CollectionManager.getCollectionManager();
    if !cm.isBshIterableiteratee ) )
      throw new EvalError("Can't iterate over type: "
        +iteratee.getClass(), this, callstack );
    BshIterator iterator = cm.getBshIteratoriteratee );
    
    Object returnControl = Primitive.VOID;
        whileiterator.hasNext() )
        {
      try {
      if elementType != null )
        eachNameSpace.setTypedVariable(
          varName/*name*/, elementType/*type*/,
          iterator.next()/*value*/new Modifiers()/*none*/ );
      else
        eachNameSpace.setVariablevarName, iterator.next()false );
      catch UtilEvalError e ) {
        throw e.toEvalError(
          "for loop iterator variable:"+ varName, this, callstack );
      }

            boolean breakout = false// switch eats a multi-level break here?
            if statement != null // not empty statement
            {
                Object ret = statement.evalcallstack, interpreter );

                if (ret instanceof ReturnControl)
                {
                    switch(((ReturnControl)ret).kind)
                    {
                        case RETURN:
              returnControl = ret;
              breakout = true;
                            break;

                        case CONTINUE:
                            break;

                        case BREAK:
                            breakout = true;
                            break;
                    }
                }
            }

            if (breakout)
                break;
        }

    callstack.swap(enclosingNameSpace);
        return returnControl;
    }
}