Skip to content

Commit

Permalink
Implement iterators on optional types
Browse files Browse the repository at this point in the history
  • Loading branch information
stanhebben committed Nov 15, 2024
1 parent deff1f5 commit a29b19f
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 37 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package org.openzen.zenscript.codemodel.type.builtin;

import org.openzen.zenscript.codemodel.FunctionHeader;
import org.openzen.zenscript.codemodel.Modifiers;
import org.openzen.zenscript.codemodel.identifiers.DefinitionSymbol;
import org.openzen.zenscript.codemodel.identifiers.MethodID;
import org.openzen.zenscript.codemodel.identifiers.MethodSymbol;
import org.openzen.zenscript.codemodel.identifiers.instances.MethodInstance;
import org.openzen.zenscript.codemodel.type.OptionalTypeID;
import org.openzen.zenscript.codemodel.type.TypeID;

import java.util.Optional;

public class OptionalIteratorMethod implements MethodSymbol {
public final MethodSymbol original;

public OptionalIteratorMethod(MethodSymbol original) {
this.original = original;
}

@Override
public DefinitionSymbol getDefiningType() {
return original.getDefiningType();
}

@Override
public TypeID getTargetType() {
return new OptionalTypeID(original.getTargetType());
}

@Override
public Modifiers getModifiers() {
return original.getModifiers();
}

@Override
public MethodID getID() {
return original.getID();
}

@Override
public FunctionHeader getHeader() {
return original.getHeader();
}

@Override
public Optional<MethodInstance> getOverrides() {
return original.getOverrides();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.openzen.zenscript.codemodel.type.OptionalTypeID;
import org.openzen.zenscript.codemodel.type.TypeID;
import org.openzen.zenscript.codemodel.type.builtin.BuiltinMethodSymbol;
import org.openzen.zenscript.codemodel.type.builtin.OptionalIteratorMethod;
import org.openzen.zenscript.codemodel.type.builtin.OptionalToStringMethod;

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

@Override
public Optional<IteratorInstance> findIterator(int variables) {
return Optional.empty();
return baseType.findIterator(variables).map(iterator -> {
MethodSymbol wrappedMethodSymbol = new OptionalIteratorMethod(iterator.method.method);
MethodInstance wrappedMethodInstance = new MethodInstance(
wrappedMethodSymbol,
iterator.method.getHeader(),
type,
iterator.method.getExpansionTypeArguments(),
iterator.method.hasWideningConversions());
return new IteratorInstance(type, iterator.getLoopVariableTypes(), wrappedMethodInstance);
});
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package org.openzen.zenscript.javabytecode.compiler;

import org.objectweb.asm.Type;
import org.openzen.zenscript.codemodel.identifiers.MethodSymbol;
import org.openzen.zenscript.codemodel.identifiers.instances.IteratorInstance;
import org.openzen.zenscript.codemodel.statement.ForeachStatement;
import org.openzen.zenscript.codemodel.type.ArrayTypeID;
import org.openzen.zenscript.codemodel.type.BasicTypeID;
import org.openzen.zenscript.codemodel.type.OptionalTypeID;
import org.openzen.zenscript.codemodel.type.RangeTypeID;
import org.openzen.zenscript.codemodel.type.TypeID;
import org.openzen.zenscript.codemodel.type.builtin.BuiltinMethodSymbol;
import org.openzen.zenscript.codemodel.type.builtin.OptionalIteratorMethod;
import org.openzen.zenscript.javabytecode.BytecodeLoopLabels;
import org.openzen.zenscript.javabytecode.JavaLocalVariableInfo;
import org.openzen.zenscript.javashared.JavaClass;
Expand All @@ -32,6 +36,43 @@ public JavaForeachWriter(JavaStatementVisitor statementVisitor, ForeachStatement
this.unboxingTypeVisitor = JavaUnboxingTypeVisitor.forJavaUnboxing(this.javaWriter);
}

public void compileIterator(MethodSymbol iteratorSymbol) {
if (iteratorSymbol instanceof BuiltinMethodSymbol) {
switch ((BuiltinMethodSymbol) iteratorSymbol) {
case ITERATOR_INT_RANGE:
visitIntRange(((RangeTypeID) statement.iterator.targetType));
break;
case ITERATOR_ARRAY_VALUES:
visitArrayValueIterator();
break;
case ITERATOR_ARRAY_KEY_VALUES:
visitArrayKeyValueIterator();
break;
case ITERATOR_ASSOC_KEYS:
visitAssocKeyIterator();
break;
case ITERATOR_ASSOC_KEY_VALUES:
visitAssocKeyValueIterator();
break;
case ITERATOR_STRING_CHARS:
visitStringCharacterIterator();
break;
//case ITERATOR_VALUES:
// iteratorWriter.visitIteratorIterator(context.getType(statement.loopVariables[0].type));
// break;
//case ITERABLE:
// iteratorWriter.visitCustomIterator();
default:
throw new IllegalArgumentException("Invalid iterator: " + statement.iterator);

}
} else if (iteratorSymbol instanceof OptionalIteratorMethod) {
visitOptionalIterator(statement.iterator);
} else {
visitCustomIterator();
}
}

public void visitIntRange(RangeTypeID type) {
final String owner = statementVisitor.context.getInternalName(type);
javaWriter.dup();
Expand Down Expand Up @@ -64,6 +105,14 @@ public void visitStringCharacterIterator() {
handleArray(javaWriter.local(int.class), javaWriter.getLocalVariable(statement.loopVariables[0].variable));
}

public void visitOptionalIterator(IteratorInstance iterator) {
javaWriter.dup();
javaWriter.ifNull(bytecodeLoopLabels.afterLoop);

OptionalIteratorMethod optionalIteratorMethod = (OptionalIteratorMethod) iterator.method.method;
compileIterator(optionalIteratorMethod.original);
}

public void visitIteratorIterator(Type targetType) {
javaWriter.invokeInterface(JavaNativeMethod.getVirtual(JavaClass.ITERABLE, "iterator", "()Ljava/lang/Iterator;", 0));
javaWriter.label(bytecodeLoopLabels.startOfLoopBody);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@

import org.objectweb.asm.Label;
import org.objectweb.asm.Type;
import org.openzen.zenscript.codemodel.identifiers.MethodSymbol;
import org.openzen.zenscript.codemodel.statement.*;
import org.openzen.zenscript.codemodel.type.BasicTypeID;
import org.openzen.zenscript.codemodel.type.RangeTypeID;
import org.openzen.zenscript.codemodel.type.builtin.BuiltinMethodSymbol;
import org.openzen.zenscript.javabytecode.BytecodeLoopLabels;
import org.openzen.zenscript.javabytecode.JavaBytecodeContext;
import org.openzen.zenscript.javabytecode.JavaLocalVariableInfo;
Expand Down Expand Up @@ -132,38 +131,8 @@ public Boolean visitForeach(ForeachStatement statement) {

//javaWriter.label(min);
JavaForeachWriter iteratorWriter = new JavaForeachWriter(this, statement, bytecodeLoopLabels);
if (statement.iterator.method.method instanceof BuiltinMethodSymbol) {
switch ((BuiltinMethodSymbol) statement.iterator.method.method) {
case ITERATOR_INT_RANGE:
iteratorWriter.visitIntRange(((RangeTypeID) statement.iterator.targetType));
break;
case ITERATOR_ARRAY_VALUES:
iteratorWriter.visitArrayValueIterator();
break;
case ITERATOR_ARRAY_KEY_VALUES:
iteratorWriter.visitArrayKeyValueIterator();
break;
case ITERATOR_ASSOC_KEYS:
iteratorWriter.visitAssocKeyIterator();
break;
case ITERATOR_ASSOC_KEY_VALUES:
iteratorWriter.visitAssocKeyValueIterator();
break;
case ITERATOR_STRING_CHARS:
iteratorWriter.visitStringCharacterIterator();
break;
//case ITERATOR_VALUES:
// iteratorWriter.visitIteratorIterator(context.getType(statement.loopVariables[0].type));
// break;
//case ITERABLE:
// iteratorWriter.visitCustomIterator();
default:
throw new IllegalArgumentException("Invalid iterator: " + statement.iterator);

}
} else {
iteratorWriter.visitCustomIterator();
}
MethodSymbol iteratorSymbol = statement.iterator.method.method;
iteratorWriter.compileIterator(iteratorSymbol);

javaWriter.goTo(startOfLoopBody);
javaWriter.label(afterLoop);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
#dependency: stdlib
#output: [1, 2, 3, 4, 5]
#output: 1
#output: 2
#output: 3
#output: 4
#output: 5

val a = [5, 1, 2, 4, 3];
a.sort();
println(a);

for element in a {
println(element);
}

0 comments on commit a29b19f

Please sign in to comment.