1 package bsh; 2 3 import java.util.*; 5 6 16 class BSHEnhancedForStatement extends SimpleNode implements ParserConstants 17 { 18 String varName; 19 20 BSHEnhancedForStatement(int id) { super(id); } 21 22 public Object eval( CallStack callstack , Interpreter interpreter ) 23 throws EvalError 24 { 25 Class elementType = null; 26 SimpleNode expression, statement=null; 27 28 NameSpace enclosingNameSpace = callstack.top(); 29 SimpleNode firstNode =((SimpleNode)jjtGetChild(0)); 30 int nodeCount = jjtGetNumChildren(); 31 32 if ( firstNode instanceof BSHType ) 33 { 34 elementType=((BSHType)firstNode).getType( callstack, interpreter ); 35 expression=((SimpleNode)jjtGetChild(1)); 36 if ( nodeCount>2 ) 37 statement=((SimpleNode)jjtGetChild(2)); 38 } else 39 { 40 expression=firstNode; 41 if ( nodeCount>1 ) 42 statement=((SimpleNode)jjtGetChild(1)); 43 } 44 45 BlockNameSpace eachNameSpace = new BlockNameSpace( enclosingNameSpace ); 46 callstack.swap( eachNameSpace ); 47 48 final Object iteratee = expression.eval( callstack, interpreter ); 49 50 if ( iteratee == Primitive.NULL ) 51 throw new EvalError("The collection, array, map, iterator, or " + 52 "enumeration portion of a for statement cannot be null.", 53 this, callstack ); 54 55 CollectionManager cm = CollectionManager.getCollectionManager(); 56 if ( !cm.isBshIterable( iteratee ) ) 57 throw new EvalError("Can't iterate over type: " 58 +iteratee.getClass(), this, callstack ); 59 BshIterator iterator = cm.getBshIterator( iteratee ); 60 61 Object returnControl = Primitive.VOID; 62 while( iterator.hasNext() ) 63 { 64 try { 65 if ( elementType != null ) 66 eachNameSpace.setTypedVariable( 67 varName, elementType, 68 iterator.next(), new Modifiers() ); 69 else 70 eachNameSpace.setVariable( varName, iterator.next(), false ); 71 } catch ( UtilEvalError e ) { 72 throw e.toEvalError( 73 "for loop iterator variable:"+ varName, this, callstack ); 74 } 75 76 boolean breakout = false; if ( statement != null ) { 79 Object ret = statement.eval( callstack, interpreter ); 80 81 if (ret instanceof ReturnControl) 82 { 83 switch(((ReturnControl)ret).kind) 84 { 85 case RETURN: 86 returnControl = ret; 87 breakout = true; 88 break; 89 90 case CONTINUE: 91 break; 92 93 case BREAK: 94 breakout = true; 95 break; 96 } 97 } 98 } 99 100 if (breakout) 101 break; 102 } 103 104 callstack.swap(enclosingNameSpace); 105 return returnControl; 106 } 107 } 108 | Popular Tags |