Skip to content

Commit a29b19f

Browse files
committed
Implement iterators on optional types
1 parent deff1f5 commit a29b19f

File tree

5 files changed

+122
-37
lines changed

5 files changed

+122
-37
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package org.openzen.zenscript.codemodel.type.builtin;
2+
3+
import org.openzen.zenscript.codemodel.FunctionHeader;
4+
import org.openzen.zenscript.codemodel.Modifiers;
5+
import org.openzen.zenscript.codemodel.identifiers.DefinitionSymbol;
6+
import org.openzen.zenscript.codemodel.identifiers.MethodID;
7+
import org.openzen.zenscript.codemodel.identifiers.MethodSymbol;
8+
import org.openzen.zenscript.codemodel.identifiers.instances.MethodInstance;
9+
import org.openzen.zenscript.codemodel.type.OptionalTypeID;
10+
import org.openzen.zenscript.codemodel.type.TypeID;
11+
12+
import java.util.Optional;
13+
14+
public class OptionalIteratorMethod implements MethodSymbol {
15+
public final MethodSymbol original;
16+
17+
public OptionalIteratorMethod(MethodSymbol original) {
18+
this.original = original;
19+
}
20+
21+
@Override
22+
public DefinitionSymbol getDefiningType() {
23+
return original.getDefiningType();
24+
}
25+
26+
@Override
27+
public TypeID getTargetType() {
28+
return new OptionalTypeID(original.getTargetType());
29+
}
30+
31+
@Override
32+
public Modifiers getModifiers() {
33+
return original.getModifiers();
34+
}
35+
36+
@Override
37+
public MethodID getID() {
38+
return original.getID();
39+
}
40+
41+
@Override
42+
public FunctionHeader getHeader() {
43+
return original.getHeader();
44+
}
45+
46+
@Override
47+
public Optional<MethodInstance> getOverrides() {
48+
return original.getOverrides();
49+
}
50+
}

CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/OptionalResolvedType.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import org.openzen.zenscript.codemodel.type.OptionalTypeID;
1212
import org.openzen.zenscript.codemodel.type.TypeID;
1313
import org.openzen.zenscript.codemodel.type.builtin.BuiltinMethodSymbol;
14+
import org.openzen.zenscript.codemodel.type.builtin.OptionalIteratorMethod;
1415
import org.openzen.zenscript.codemodel.type.builtin.OptionalToStringMethod;
1516

1617
import java.util.Collections;
@@ -129,7 +130,16 @@ public List<Comparator> comparators() {
129130

130131
@Override
131132
public Optional<IteratorInstance> findIterator(int variables) {
132-
return Optional.empty();
133+
return baseType.findIterator(variables).map(iterator -> {
134+
MethodSymbol wrappedMethodSymbol = new OptionalIteratorMethod(iterator.method.method);
135+
MethodInstance wrappedMethodInstance = new MethodInstance(
136+
wrappedMethodSymbol,
137+
iterator.method.getHeader(),
138+
type,
139+
iterator.method.getExpansionTypeArguments(),
140+
iterator.method.hasWideningConversions());
141+
return new IteratorInstance(type, iterator.getLoopVariableTypes(), wrappedMethodInstance);
142+
});
133143
}
134144

135145
@Override

JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaForeachWriter.java

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
package org.openzen.zenscript.javabytecode.compiler;
22

33
import org.objectweb.asm.Type;
4+
import org.openzen.zenscript.codemodel.identifiers.MethodSymbol;
5+
import org.openzen.zenscript.codemodel.identifiers.instances.IteratorInstance;
46
import org.openzen.zenscript.codemodel.statement.ForeachStatement;
57
import org.openzen.zenscript.codemodel.type.ArrayTypeID;
68
import org.openzen.zenscript.codemodel.type.BasicTypeID;
79
import org.openzen.zenscript.codemodel.type.OptionalTypeID;
810
import org.openzen.zenscript.codemodel.type.RangeTypeID;
911
import org.openzen.zenscript.codemodel.type.TypeID;
12+
import org.openzen.zenscript.codemodel.type.builtin.BuiltinMethodSymbol;
13+
import org.openzen.zenscript.codemodel.type.builtin.OptionalIteratorMethod;
1014
import org.openzen.zenscript.javabytecode.BytecodeLoopLabels;
1115
import org.openzen.zenscript.javabytecode.JavaLocalVariableInfo;
1216
import org.openzen.zenscript.javashared.JavaClass;
@@ -32,6 +36,43 @@ public JavaForeachWriter(JavaStatementVisitor statementVisitor, ForeachStatement
3236
this.unboxingTypeVisitor = JavaUnboxingTypeVisitor.forJavaUnboxing(this.javaWriter);
3337
}
3438

39+
public void compileIterator(MethodSymbol iteratorSymbol) {
40+
if (iteratorSymbol instanceof BuiltinMethodSymbol) {
41+
switch ((BuiltinMethodSymbol) iteratorSymbol) {
42+
case ITERATOR_INT_RANGE:
43+
visitIntRange(((RangeTypeID) statement.iterator.targetType));
44+
break;
45+
case ITERATOR_ARRAY_VALUES:
46+
visitArrayValueIterator();
47+
break;
48+
case ITERATOR_ARRAY_KEY_VALUES:
49+
visitArrayKeyValueIterator();
50+
break;
51+
case ITERATOR_ASSOC_KEYS:
52+
visitAssocKeyIterator();
53+
break;
54+
case ITERATOR_ASSOC_KEY_VALUES:
55+
visitAssocKeyValueIterator();
56+
break;
57+
case ITERATOR_STRING_CHARS:
58+
visitStringCharacterIterator();
59+
break;
60+
//case ITERATOR_VALUES:
61+
// iteratorWriter.visitIteratorIterator(context.getType(statement.loopVariables[0].type));
62+
// break;
63+
//case ITERABLE:
64+
// iteratorWriter.visitCustomIterator();
65+
default:
66+
throw new IllegalArgumentException("Invalid iterator: " + statement.iterator);
67+
68+
}
69+
} else if (iteratorSymbol instanceof OptionalIteratorMethod) {
70+
visitOptionalIterator(statement.iterator);
71+
} else {
72+
visitCustomIterator();
73+
}
74+
}
75+
3576
public void visitIntRange(RangeTypeID type) {
3677
final String owner = statementVisitor.context.getInternalName(type);
3778
javaWriter.dup();
@@ -64,6 +105,14 @@ public void visitStringCharacterIterator() {
64105
handleArray(javaWriter.local(int.class), javaWriter.getLocalVariable(statement.loopVariables[0].variable));
65106
}
66107

108+
public void visitOptionalIterator(IteratorInstance iterator) {
109+
javaWriter.dup();
110+
javaWriter.ifNull(bytecodeLoopLabels.afterLoop);
111+
112+
OptionalIteratorMethod optionalIteratorMethod = (OptionalIteratorMethod) iterator.method.method;
113+
compileIterator(optionalIteratorMethod.original);
114+
}
115+
67116
public void visitIteratorIterator(Type targetType) {
68117
javaWriter.invokeInterface(JavaNativeMethod.getVirtual(JavaClass.ITERABLE, "iterator", "()Ljava/lang/Iterator;", 0));
69118
javaWriter.label(bytecodeLoopLabels.startOfLoopBody);

JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaStatementVisitor.java

Lines changed: 3 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@
22

33
import org.objectweb.asm.Label;
44
import org.objectweb.asm.Type;
5+
import org.openzen.zenscript.codemodel.identifiers.MethodSymbol;
56
import org.openzen.zenscript.codemodel.statement.*;
67
import org.openzen.zenscript.codemodel.type.BasicTypeID;
7-
import org.openzen.zenscript.codemodel.type.RangeTypeID;
8-
import org.openzen.zenscript.codemodel.type.builtin.BuiltinMethodSymbol;
98
import org.openzen.zenscript.javabytecode.BytecodeLoopLabels;
109
import org.openzen.zenscript.javabytecode.JavaBytecodeContext;
1110
import org.openzen.zenscript.javabytecode.JavaLocalVariableInfo;
@@ -132,38 +131,8 @@ public Boolean visitForeach(ForeachStatement statement) {
132131

133132
//javaWriter.label(min);
134133
JavaForeachWriter iteratorWriter = new JavaForeachWriter(this, statement, bytecodeLoopLabels);
135-
if (statement.iterator.method.method instanceof BuiltinMethodSymbol) {
136-
switch ((BuiltinMethodSymbol) statement.iterator.method.method) {
137-
case ITERATOR_INT_RANGE:
138-
iteratorWriter.visitIntRange(((RangeTypeID) statement.iterator.targetType));
139-
break;
140-
case ITERATOR_ARRAY_VALUES:
141-
iteratorWriter.visitArrayValueIterator();
142-
break;
143-
case ITERATOR_ARRAY_KEY_VALUES:
144-
iteratorWriter.visitArrayKeyValueIterator();
145-
break;
146-
case ITERATOR_ASSOC_KEYS:
147-
iteratorWriter.visitAssocKeyIterator();
148-
break;
149-
case ITERATOR_ASSOC_KEY_VALUES:
150-
iteratorWriter.visitAssocKeyValueIterator();
151-
break;
152-
case ITERATOR_STRING_CHARS:
153-
iteratorWriter.visitStringCharacterIterator();
154-
break;
155-
//case ITERATOR_VALUES:
156-
// iteratorWriter.visitIteratorIterator(context.getType(statement.loopVariables[0].type));
157-
// break;
158-
//case ITERABLE:
159-
// iteratorWriter.visitCustomIterator();
160-
default:
161-
throw new IllegalArgumentException("Invalid iterator: " + statement.iterator);
162-
163-
}
164-
} else {
165-
iteratorWriter.visitCustomIterator();
166-
}
134+
MethodSymbol iteratorSymbol = statement.iterator.method.method;
135+
iteratorWriter.compileIterator(iteratorSymbol);
167136

168137
javaWriter.goTo(startOfLoopBody);
169138
javaWriter.label(afterLoop);
Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
#dependency: stdlib
2-
#output: [1, 2, 3, 4, 5]
2+
#output: 1
3+
#output: 2
4+
#output: 3
5+
#output: 4
6+
#output: 5
37

48
val a = [5, 1, 2, 4, 3];
59
a.sort();
6-
println(a);
10+
11+
for element in a {
12+
println(element);
13+
}

0 commit comments

Comments
 (0)