Skip to content

Commit

Permalink
Added optional tests, fixed match expression type inference and ssa a…
Browse files Browse the repository at this point in the history
…nalysis, fixed ssa analysis on lambda method bodies
  • Loading branch information
stanhebben committed Mar 22, 2024
1 parent 3d3c7f0 commit b2713f0
Show file tree
Hide file tree
Showing 27 changed files with 260 additions and 85 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ default boolean canCastImplicitlyTo(TypeID target) {
Optional<StaticCallable> findStaticOperator(OperatorType operator);

interface SwitchMember {
SwitchValue toSwitchValue(String[] bindingNames);
SwitchValue toSwitchValue(List<CompilingVariable> bindings);
}

interface Field {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@
import java.util.Optional;

public interface StatementCompiler {
Expression compile(CompilableExpression expression);

Expression compile(CompilableExpression expression, TypeID type);

ExpressionCompiler expressions();

TypeBuilder types();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,6 @@ public StatementCompilerImpl(CompileContext context, LocalType localType, TypeBu
expressionCompiler = new ExpressionCompilerImpl(context, localType, this.types, functionHeader.thrownType, locals, functionHeader);
}

@Override
public Expression compile(CompilableExpression expression) {
return expression.compile(expressionCompiler).eval();
}

@Override
public Expression compile(CompilableExpression expression, TypeID type) {
return expression
.compile(expressionCompiler)
.cast(CastedEval.implicit(expressionCompiler, expression.getPosition(), type))
.value;
}

@Override
public ExpressionCompiler expressions() {
return expressionCompiler;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.openzen.zenscript.codemodel.expression.switchvalue;

import org.openzen.zenscript.codemodel.VariableDefinition;
import org.openzen.zenscript.codemodel.ssa.SSAVariableCollector;
import org.openzen.zenscript.codemodel.statement.VarStatement;

Expand All @@ -14,7 +15,7 @@ public CharSwitchValue(char value) {
}

@Override
public List<VarStatement> getBindings() {
public List<VariableDefinition> getBindings() {
return Collections.emptyList();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.openzen.zenscript.codemodel.expression.switchvalue;

import org.openzen.zenscript.codemodel.VariableDefinition;
import org.openzen.zenscript.codemodel.member.EnumConstantMember;
import org.openzen.zenscript.codemodel.ssa.SSAVariableCollector;
import org.openzen.zenscript.codemodel.statement.VarStatement;
Expand All @@ -15,7 +16,7 @@ public EnumConstantSwitchValue(EnumConstantMember constant) {
}

@Override
public List<VarStatement> getBindings() {
public List<VariableDefinition> getBindings() {
return Collections.emptyList();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import org.openzen.zencode.shared.CodePosition;
import org.openzen.zencode.shared.CompileError;
import org.openzen.zenscript.codemodel.VariableDefinition;
import org.openzen.zenscript.codemodel.ssa.SSAVariableCollector;
import org.openzen.zenscript.codemodel.statement.VarStatement;

Expand All @@ -18,7 +19,7 @@ public ErrorSwitchValue(CodePosition position, CompileError error) {
}

@Override
public List<VarStatement> getBindings() {
public List<VariableDefinition> getBindings() {
return Collections.emptyList();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.openzen.zenscript.codemodel.expression.switchvalue;

import org.openzen.zenscript.codemodel.VariableDefinition;
import org.openzen.zenscript.codemodel.ssa.SSAVariableCollector;
import org.openzen.zenscript.codemodel.statement.VarStatement;

Expand All @@ -14,7 +15,7 @@ public IntSwitchValue(int value) {
}

@Override
public List<VarStatement> getBindings() {
public List<VariableDefinition> getBindings() {
return Collections.emptyList();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.openzen.zenscript.codemodel.expression.switchvalue;

import org.openzen.zenscript.codemodel.VariableDefinition;
import org.openzen.zenscript.codemodel.ssa.SSAVariableCollector;
import org.openzen.zenscript.codemodel.statement.VarStatement;

Expand All @@ -14,7 +15,7 @@ public StringSwitchValue(String value) {
}

@Override
public List<VarStatement> getBindings() {
public List<VariableDefinition> getBindings() {
return Collections.emptyList();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package org.openzen.zenscript.codemodel.expression.switchvalue;

import org.openzen.zenscript.codemodel.LocalVariable;
import org.openzen.zenscript.codemodel.VariableDefinition;
import org.openzen.zenscript.codemodel.ssa.SSAVariableCollector;
import org.openzen.zenscript.codemodel.statement.VarStatement;

import java.util.List;

public interface SwitchValue {
List<VarStatement> getBindings();
List<VariableDefinition> getBindings();

<T> T accept(SwitchValueVisitor<T> visitor);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.openzen.zenscript.codemodel.expression.switchvalue;

import org.openzen.zencode.shared.CodePosition;
import org.openzen.zenscript.codemodel.VariableDefinition;
import org.openzen.zenscript.codemodel.member.ref.VariantOptionInstance;
import org.openzen.zenscript.codemodel.ssa.SSAVariableCollector;
import org.openzen.zenscript.codemodel.statement.VarStatement;
Expand All @@ -12,25 +13,16 @@
public class VariantOptionSwitchValue implements SwitchValue {
public final VariantOptionInstance option;
public final String[] parameters;
private final List<VarStatement> bindings;
private final List<VariableDefinition> bindings;

public VariantOptionSwitchValue(VariantOptionInstance option, String[] parameters) {
public VariantOptionSwitchValue(VariantOptionInstance option, List<VariableDefinition> bindings) {
this.option = option;
this.parameters = parameters;
this.bindings = new ArrayList<>();
for (int i = 0; i < option.types.length; i++) {
bindings.add(new VarStatement(
CodePosition.UNKNOWN,
new VariableID(),
parameters[i],
option.types[i],
null,
true));
}
this.parameters = bindings.stream().map(p -> p.name).toArray(String[]::new);
this.bindings = bindings;
}

@Override
public List<VarStatement> getBindings() {
public List<VariableDefinition> getBindings() {
return bindings;
}

Expand All @@ -46,6 +38,5 @@ public <C, R> R accept(C context, SwitchValueVisitorWithContext<C, R> visitor) {

@Override
public void collect(SSAVariableCollector collector) {

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import org.openzen.zencode.shared.CodePosition;
import org.openzen.zencode.shared.Tag;
import org.openzen.zenscript.codemodel.VariableDefinition;
import org.openzen.zenscript.codemodel.compilation.*;
import org.openzen.zenscript.codemodel.compilation.expression.AbstractCompilingExpression;
import org.openzen.zenscript.codemodel.definition.VariantDefinition;
Expand All @@ -14,7 +15,10 @@
import org.openzen.zenscript.codemodel.ssa.SSAVariableCollector;
import org.openzen.zenscript.codemodel.type.TypeID;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

public class VariantOptionInstance implements CompilableExpression, ResolvedType.SwitchMember {
public final TypeID variant;
Expand Down Expand Up @@ -78,8 +82,13 @@ public void linkVariables(CodeBlockStatement.VariableLinker linker) {}
}

@Override
public SwitchValue toSwitchValue(String[] bindingNames) {
return new VariantOptionSwitchValue(this, bindingNames);
public SwitchValue toSwitchValue(List<CompilingVariable> variables) {
List<VariableDefinition> bindings = new ArrayList<>();
for (int i = 0; i < variables.size(); i++) {
variables.get(i).inferredType = types[i];
bindings.add(variables.get(i).asType(types[i]));
}
return new VariantOptionSwitchValue(this, bindings);
}

private static class OptionCallable implements CompilingCallable {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.openzen.zenscript.javabytecode.compiler;

import org.objectweb.asm.Label;
import org.openzen.zenscript.codemodel.VariableDefinition;
import org.openzen.zenscript.codemodel.expression.switchvalue.*;
import org.openzen.zenscript.codemodel.statement.VarStatement;
import org.openzen.zenscript.javabytecode.JavaBytecodeContext;
Expand Down Expand Up @@ -57,7 +58,7 @@ public Void acceptVariantOption(VariantOptionSwitchValue key) {
javaWriter.checkCast(javaVariantOption.variantOptionClass.internalName);

int fieldNumber = 0;
for (VarStatement binding : key.getBindings()) {
for (VariableDefinition binding : key.getBindings()) {
javaWriter.dup();
javaWriter.getField(
javaVariantOption.variantOptionClass.internalName,
Expand All @@ -71,7 +72,7 @@ public Void acceptVariantOption(VariantOptionSwitchValue key) {
binding.name,
caseEnd
);
javaWriter.setLocalVariable(binding.variable, javaLocalVariableInfo);
javaWriter.setLocalVariable(binding.id, javaLocalVariableInfo);
javaWriter.store(javaLocalVariableInfo);
}
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;


public class JavaDefinitionVisitor implements DefinitionVisitor<byte[]> {
Expand Down Expand Up @@ -280,11 +281,12 @@ public byte[] visitVariant(VariantDefinition variant) {
{
StringBuilder builder = new StringBuilder();
//TODO check if this can be changed to what Stan was up to
builder.append("<");
for (final TypeID type : option.types) {
builder.append(javaTypeGenericVisitor.getSignatureWithBound(type));
if (Stream.of(option.types).anyMatch(TypeID::isGeneric)) {
builder.append("<");
Stream.of(option.types).filter(TypeID::isGeneric)
.forEach(it -> builder.append(javaTypeGenericVisitor.getSignatureWithBound(it)));
builder.append(">");
}
builder.append(">");
builder.append("L").append(class_.getInternalName()).append("<");

for (final TypeParameter genericParameter : variant.typeParameters) {
Expand All @@ -299,10 +301,8 @@ public byte[] visitVariant(VariantDefinition variant) {
}
if (t)
builder.append(javaTypeGenericVisitor.getGenericBounds(genericParameter.bounds));

}


signature = builder.append(">;").toString();
}

Expand All @@ -314,8 +314,8 @@ public byte[] visitVariant(VariantDefinition variant) {
for (int i = 0; i < types.length; ++i) {
final String descriptor = context.getDescriptor(types[i]);
optionInitDescBuilder.append(descriptor);
optionInitSignatureBuilder.append("T").append(((GenericTypeID) types[i]).parameter.name).append(";");
optionWriter.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, "field" + i, descriptor, "T" + ((GenericTypeID) types[i]).parameter.name + ";", null).visitEnd();
optionInitSignatureBuilder.append(context.getSignature(types[i]));
optionWriter.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, "field" + i, descriptor, context.getSignature(types[i]), null).visitEnd();
}
optionInitDescBuilder.append(")V");
optionInitSignatureBuilder.append(")V");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
import org.openzen.zenscript.codemodel.expression.switchvalue.SwitchValue;
import org.openzen.zenscript.codemodel.ssa.CodeBlockStatement;
import org.openzen.zenscript.codemodel.ssa.SSAVariableCollector;
import org.openzen.zenscript.codemodel.statement.VariableID;
import org.openzen.zenscript.codemodel.type.TypeID;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
Expand Down Expand Up @@ -75,26 +77,44 @@ public CompilingSwitchValue compileSwitchValue(ExpressionCompiler compiler) {
return type -> new ErrorSwitchValue(position, CompileErrors.invalidSwitchCaseExpression());
}

return type -> {
String name = ((ParsedExpressionVariable) receiver).name;
ResolvedType resolved = compiler.resolve(type);
Optional<ResolvedType.SwitchMember> maybeSwitchMember = resolved.findSwitchMember(name);
if (maybeSwitchMember.isPresent()) {
String[] values = new String[arguments.arguments.size()];
for (int i = 0; i < values.length; i++) {
CompilableExpression argument = arguments.arguments.get(i);
Optional<CompilableLambdaHeader.Parameter> lambdaHeader = argument.asLambdaHeaderParameter();
if (lambdaHeader.isPresent()) {
values[i] = lambdaHeader.get().getName();
} else {
return new ErrorSwitchValue(position, CompileErrors.invalidSwitchCaseExpression());
}
}

return maybeSwitchMember.get().toSwitchValue(values);
List<CompilingVariable> bindings = new ArrayList<>();
for (CompilableExpression argument : arguments.arguments) {
Optional<CompilableLambdaHeader.Parameter> lambdaHeader = argument.asLambdaHeaderParameter();
if (lambdaHeader.isPresent()) {
bindings.add(new CompilingVariable(new VariableID(), lambdaHeader.get().getName(), null, true));
} else {
return new ErrorSwitchValue(position, CompileErrors.invalidSwitchCaseExpression());
return type -> new ErrorSwitchValue(position, CompileErrors.invalidSwitchCaseExpression());
}
};
}

return new CompilingSwitchValue() {
@Override
public SwitchValue as(TypeID type) {
String name = ((ParsedExpressionVariable) receiver).name;
ResolvedType resolved = compiler.resolve(type);
Optional<ResolvedType.SwitchMember> maybeSwitchMember = resolved.findSwitchMember(name);
if (maybeSwitchMember.isPresent()) {
String[] values = new String[arguments.arguments.size()];
for (int i = 0; i < values.length; i++) {
CompilableExpression argument = arguments.arguments.get(i);
Optional<CompilableLambdaHeader.Parameter> lambdaHeader = argument.asLambdaHeaderParameter();
if (lambdaHeader.isPresent()) {
values[i] = lambdaHeader.get().getName();
} else {
return new ErrorSwitchValue(position, CompileErrors.invalidSwitchCaseExpression());
}
}

return maybeSwitchMember.get().toSwitchValue(bindings);
} else {
return new ErrorSwitchValue(position, CompileErrors.invalidSwitchCaseExpression());
}
}

@Override
public List<CompilingVariable> getBindings() {
return bindings;
}
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ public SwitchValue as(TypeID type) {
ResolvedType resolved = compiler.resolve(type);
Optional<ResolvedType.SwitchMember> switchMember = resolved.findSwitchMember(name);
if (switchMember.isPresent()) {
return switchMember.get().toSwitchValue(new String[0]);
return switchMember.get().toSwitchValue(Collections.emptyList());
} else {
return new ErrorSwitchValue(position, CompileErrors.invalidSwitchCaseExpression());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ public void collect(SSAVariableCollector collector) {
public void linkVariables(CodeBlockStatement.VariableLinker linker) {
value.linkVariables(linker);
for (CompilingCase case_ : cases) {
for (CompilingVariable variable : case_.name.getBindings()) {
variable.ssaCompilingVariable = linker.get(variable.id);
}
case_.value.linkVariables(linker);
}
}
Expand Down
Loading

0 comments on commit b2713f0

Please sign in to comment.