Working iterable foreach with tests.

This commit is contained in:
Jack Conradson 2016-06-06 13:53:31 -07:00
parent 64ff818f9f
commit a4ffaa6e7a
4 changed files with 20 additions and 8 deletions

View File

@ -74,7 +74,7 @@ decltype
;
funcref
: TYPE REF ID
: ( TYPE | ID ) REF ID
;
declvar

View File

@ -279,7 +279,7 @@ public final class Walker extends PainlessParserBaseVisitor<Object> {
String type = ctx.decltype().getText();
String name = ctx.ID().getText();
AExpression expression = (AExpression)visit(ctx.expression());
AExpression expression = (AExpression)visitExpression(ctx.expression());
SBlock block = (SBlock)visit(ctx.trailer());
return new SEach(location(ctx), settings.getMaxLoopCounter(), type, name, expression, block);

View File

@ -33,6 +33,9 @@ import org.elasticsearch.painless.Variables.Variable;
import org.objectweb.asm.Label;
import org.objectweb.asm.Opcodes;
import java.util.HashMap;
import java.util.Map;
public class SEach extends AStatement {
final int maxLoopCounter;
@ -85,7 +88,7 @@ public class SEach extends AStatement {
Type itr = Definition.getType("Iterator");
variable = variables.addVariable(location, type, name, false, false);
variable = variables.addVariable(location, type, name, true, false);
iterator = variables.addVariable(location, itr, "#itr" + location.getOffset(), true, false);
method = expression.actual.struct.methods.get(new MethodKey("iterator", 0));
@ -107,11 +110,11 @@ public class SEach extends AStatement {
if (next == null) {
throw location.createError(new IllegalArgumentException("Method [next] does not exist for type [Iterator]."));
} else if (next.rtn.sort != Sort.OBJECT) {
throw location.createError(new IllegalArgumentException("Method [next] does not return type [Object]."));
} else if (next.rtn.sort != Sort.DEF) {
throw location.createError(new IllegalArgumentException("Method [next] does not return type [def]."));
}
cast = AnalyzerCaster.getLegalCast(location, Definition.getType("Object"), type, true, true);
cast = AnalyzerCaster.getLegalCast(location, Definition.DEF_TYPE, type, true, true);
if (block == null) {
throw location.createError(new IllegalArgumentException("Extraneous for each loop."));
@ -150,8 +153,11 @@ public class SEach extends AStatement {
writer.visitVarInsn(iterator.type.type.getOpcode(Opcodes.ISTORE), iterator.slot);
Label begin = new Label();
Label end = new Label();
writer.mark(begin);
writer.visitVarInsn(iterator.type.type.getOpcode(Opcodes.ILOAD), iterator.slot);
writer.invokeInterface(hasNext.owner.type, hasNext.method);
writer.ifZCmp(MethodWriter.EQ, end);
@ -163,6 +169,7 @@ public class SEach extends AStatement {
block.write(writer);
writer.goTo(begin);
writer.mark(end);
}
}

View File

@ -125,9 +125,14 @@ public class BasicStatementTests extends ScriptTestCase {
}
}
public void testEachStatement() {
public void testIterableForEachStatement() {
assertEquals(6, exec("List l = new ArrayList(); l.add(1); l.add(2); l.add(3); int total = 0;" +
" for (int x : l) total += x; return x"));
" for (int x : l) total += x; return total"));
assertEquals("123", exec("List l = new ArrayList(); l.add('1'); l.add('2'); l.add('3'); String cat = '';" +
" for (String x : l) cat += x; return cat"));
assertEquals("1236", exec("Map m = new HashMap(); m.put('1', 1); m.put('2', 2); m.put('3', 3);" +
" String cat = ''; int total = 0;" +
" for (Map.Entry e : m.entrySet()) { cat += e.getKey(); total += e.getValue(); } return cat + total"));
}
public void testDeclarationStatement() {