Skip to content

Commit

Permalink
Merge pull request #171 from ZenCodeLang/feature/refactor-fix-more-stuff
Browse files Browse the repository at this point in the history
Feature/refactor fix more stuff
  • Loading branch information
stanhebben authored Sep 6, 2024
2 parents 0f207fd + e7278c6 commit 5eb14f6
Show file tree
Hide file tree
Showing 76 changed files with 1,398 additions and 737 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,7 @@ public ExpressionString visitPlatformSpecific(Expression expression) {
}

@Override
public ExpressionString visitPostCall(PostCallExpression expression) {
public ExpressionString visitModification(ModificationExpression expression) {
MethodID.Operator operator = (MethodID.Operator) expression.member.getID();
return unaryPostfix(expression.target, ZenScriptOperator.INCREMENT, operator.operator == OperatorType.INCREMENT ? "++" : "--");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public CastedExpression of(Expression value) {
if (value.type.equals(type) || type == BasicTypeID.UNDETERMINED)
return new CastedExpression(CastedExpression.Level.EXACT, value);
if (value.type.isInvalid())
return CastedExpression.invalid(value);
return CastedExpression.invalid(value.position, ((InvalidExpression)value).error);

ResolvedType resolvedTargetType = compiler.resolve(type);

Expand Down Expand Up @@ -77,18 +77,18 @@ public CastedExpression of(Expression value) {
return new CastedExpression(CastedExpression.Level.EXPLICIT, casted.get());
}

return CastedExpression.invalid(compiler.at(position).invalid(CompileErrors.cannotCast(value.type, type, explicit)));
return CastedExpression.invalid(position, CompileErrors.cannotCast(value.type, type, explicit));
}

public CastedExpression of(CastedExpression.Level level, Expression value) {
if (level == CastedExpression.Level.EXPLICIT && !explicit)
return CastedExpression.invalid(compiler.at(position).invalid(CompileErrors.cannotCast(value.type, type, explicit)));
return CastedExpression.invalid(position, CompileErrors.cannotCast(value.type, type, explicit));

CastedExpression casted = of(value);
return new CastedExpression(level.max(casted.level), casted.value);
}

public CastedExpression invalid(CompileError error) {
return CastedExpression.invalid(compiler.at(position).invalid(error, type));
return CastedExpression.invalid(position, error);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package org.openzen.zenscript.codemodel.compilation;

import org.openzen.zencode.shared.CodePosition;
import org.openzen.zencode.shared.CompileError;
import org.openzen.zenscript.codemodel.expression.Expression;
import org.openzen.zenscript.codemodel.expression.InvalidExpression;
import org.openzen.zenscript.codemodel.type.BasicTypeID;

public class CastedExpression {
public enum Level {
Expand Down Expand Up @@ -31,16 +35,28 @@ public static CastedExpression explicit(Expression value) {
return new CastedExpression(Level.EXPLICIT, value);
}

public static CastedExpression invalid(Expression value) {
return new CastedExpression(Level.INVALID, value);
public static CastedExpression invalid(CodePosition position, CompileError error) {
return new CastedExpression(position, error);
}

public static CastedExpression invalid(Expression expression) {
return new CastedExpression(Level.INVALID, expression);
}

public final Level level;
public final Expression value;
public final CompileError error;

public CastedExpression(Level level, Expression value) {
this.level = level;
this.value = value;
this.error = level == Level.INVALID ? ((InvalidExpression)value).error : null;
}

public CastedExpression(CodePosition position, CompileError error) {
this.level = Level.INVALID;
this.value = new InvalidExpression(position, BasicTypeID.INVALID, error);
this.error = error;
}

public boolean isFailed() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,7 @@ public Expression compare(Expression left, CompilingExpression right, CompareTyp
return b;
}
})
.orElseGet(() -> CastedExpression.invalid(compiler.at(position).invalid(
CompileErrors.noOperatorInType(left.type, OperatorType.COMPARE), //TODO Make error message more descriptive and include target type.
BasicTypeID.BOOL)));
.orElseGet(() -> CastedExpression.invalid(position, CompileErrors.noOperatorInType(left.type, OperatorType.COMPARE)));
return result.value;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ public static CompileError overrideWithoutBase() {
}

public static CompileError overriddenMethodNotFound(MethodID method, FunctionHeader header) {
return new CompileError(CompileExceptionCode.OVERRIDEN_METHOD_NOT_FOUND, "Could not find the base method for " + method + header);
return new CompileError(CompileExceptionCode.OVERRIDDEN_METHOD_NOT_FOUND, "Could not find the base method for " + method + header);
}

public static CompileError fieldWithoutType() {
Expand Down Expand Up @@ -543,4 +543,20 @@ public static CompileError invalidNumberOfTypeArguments(int expectedTypeArgument
public static CompileError parseError(String message) {
return new CompileError(CompileExceptionCode.PARSE_ERROR, message);
}

public static CompileError invalidModificationTarget() {
return new CompileError(CompileExceptionCode.INVALID_MODIFICATION_TARGET, "Invalid target for increment or decrement operators");
}

public static CompileError invalidPropertyGetter(TypeID type, String name) {
return new CompileError(CompileExceptionCode.INVALID_PROPERTY_GETTER, "Invalid getter for property " + name + " in type " + type);
}

public static CompileError invalidPropertySetter(TypeID type, String name) {
return new CompileError(CompileExceptionCode.INVALID_PROPERTY_SETTER, "Invalid setter for property " + name + " in type " + type);
}

public static CompileError invalidPropertyPair(TypeID type, String name) {
return new CompileError(CompileExceptionCode.INVALID_PROPERTY_PAIR, "Setter and getter of property " + name + " in type " + type + " have different types");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import org.openzen.zencode.shared.CodePosition;
import org.openzen.zenscript.codemodel.GenericName;
import org.openzen.zenscript.codemodel.expression.Expression;
import org.openzen.zenscript.codemodel.expression.ModificationExpression;
import org.openzen.zenscript.codemodel.expression.modifiable.ModifiableExpression;
import org.openzen.zenscript.codemodel.ssa.CodeBlockStatement;
import org.openzen.zenscript.codemodel.ssa.SSAVariableCollector;
import org.openzen.zenscript.codemodel.type.TypeID;
Expand Down Expand Up @@ -43,6 +45,10 @@ public interface CompilingExpression {
*/
Optional<CompilingCallable> call();

default Optional<ModifiableExpression> asModifiable() {
return Optional.empty();
}

/**
* Finds a member from this expression.
* Returns an invalid expression if none could be found.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@
import org.openzen.zenscript.codemodel.FunctionParameter;
import org.openzen.zenscript.codemodel.VariableDefinition;
import org.openzen.zenscript.codemodel.expression.*;
import org.openzen.zenscript.codemodel.expression.modifiable.ModifiableExpression;
import org.openzen.zenscript.codemodel.identifiers.instances.FieldInstance;
import org.openzen.zenscript.codemodel.identifiers.instances.MethodInstance;
import org.openzen.zenscript.codemodel.member.ref.ImplementationMemberInstance;
import org.openzen.zenscript.codemodel.ssa.SSAVariable;
import org.openzen.zenscript.codemodel.statement.Statement;
import org.openzen.zenscript.codemodel.statement.VarStatement;
import org.openzen.zenscript.codemodel.type.ArrayTypeID;
import org.openzen.zenscript.codemodel.type.AssocTypeID;
import org.openzen.zenscript.codemodel.type.GenericMapTypeID;
Expand All @@ -28,8 +27,6 @@ public interface ExpressionBuilder {

Expression callSuper(MethodInstance method, Expression target, CallArguments arguments);

Expression callPostfix(MethodInstance method, Expression target);

Expression coalesce(Expression left, Expression right);

Expression compare(Expression left, CompilingExpression right, CompareType type);
Expand Down Expand Up @@ -80,6 +77,8 @@ public interface ExpressionBuilder {

Expression match(Expression value, TypeID resultingType, MatchExpression.Case[] cases);

Expression modification(ModifiableExpression target, MethodInstance operator, ModificationExpression.Modification modification);

Expression orOr(Expression left, Expression right);

Expression panic(TypeID type, Expression value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import org.openzen.zenscript.codemodel.compilation.impl.BoundInstanceCallable;
import org.openzen.zenscript.codemodel.expression.CallArguments;
import org.openzen.zenscript.codemodel.expression.Expression;
import org.openzen.zenscript.codemodel.expression.ModificationExpression;
import org.openzen.zenscript.codemodel.expression.modifiable.ModifiableExpression;
import org.openzen.zenscript.codemodel.identifiers.instances.MethodInstance;
import org.openzen.zenscript.codemodel.type.TypeID;

Expand Down Expand Up @@ -72,11 +74,11 @@ private static Expression applyWideningIfNecessary(ExpressionCompiler compiler,
return instance;
}

public Expression callPostfix(ExpressionBuilder builder, Expression instance) {
public Expression callModification(ExpressionBuilder builder, ModifiableExpression instance, ModificationExpression.Modification modification) {
if (overloads.size() != 1) {
return builder.invalid(CompileErrors.invalidPostfix());
} else {
return overloads.get(0).callPostfix(builder, instance);
return overloads.get(0).callModification(builder, instance, modification);
}
}

Expand Down Expand Up @@ -107,4 +109,11 @@ public Optional<MethodInstance> findOverriddenMethod(TypeResolver resolver, Func

return Optional.empty();
}

public Optional<MethodInstance> asSingleMethod() {
if (overloads.size() != 1)
return Optional.empty();

return overloads.get(0).asMethod();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
import org.openzen.zenscript.codemodel.Modifiers;
import org.openzen.zenscript.codemodel.expression.CallArguments;
import org.openzen.zenscript.codemodel.expression.Expression;
import org.openzen.zenscript.codemodel.expression.ModificationExpression;
import org.openzen.zenscript.codemodel.expression.modifiable.ModifiableExpression;

public interface InstanceCallableMethod extends AnyMethod {
Modifiers getModifiers();

Expression call(ExpressionBuilder builder, Expression instance, CallArguments arguments);

default Expression callPostfix(ExpressionBuilder builder, Expression instance) {
default Expression callModification(ExpressionBuilder builder, ModifiableExpression instance, ModificationExpression.Modification modification) {
return builder.invalid(CompileErrors.invalidPostfix());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ public static <T extends AnyMethod> MatchedCallArguments<T> match(
}
}

return methodsGroupedByMatchLevel.getOrDefault(CastedExpression.Level.INVALID, Collections.emptyList()).stream().findFirst()
return methodsGroupedByMatchLevel.getOrDefault(CastedExpression.Level.INVALID, Collections.emptyList()).stream()
.findFirst()
.orElseGet(() -> {
List<FunctionHeader> headers = overloads.stream().map(AnyMethod::getHeader).collect(Collectors.toList());
List<TypeID> types = Arrays.stream(arguments).map(CompilingExpression::eval).map(it -> it.type).collect(Collectors.toList());
Expand Down Expand Up @@ -80,6 +81,12 @@ private MatchedCallArguments(CompileError error) {
this.error = error;
}

private MatchedCallArguments(CompileError error, CallArguments arguments) {
this.method = null;
this.arguments = arguments;
this.error = error;
}

public boolean requiresWidenedInstance(TypeID instanceType) {
return method != null && method.hasWideningConversions() && method.asMethod().map(method -> !method.getTarget().equals(instanceType)).orElse(false);
}
Expand All @@ -98,7 +105,7 @@ public Expression eval(ExpressionBuilder builder, CallEvaluator<T> evaluator) {

public CastedExpression cast(ExpressionBuilder builder, CastedEval eval, CallEvaluator<T> evaluator) {
if (this.error != null) {
return eval.invalid(error);
return CastedExpression.invalid(builder.invalid(error));
} else {
return eval.of(evaluator.eval(builder, method, arguments));
}
Expand Down Expand Up @@ -237,7 +244,7 @@ private static <T extends AnyMethod> MatchedCallArguments<T> matchNormal(
argument = new WrappedCompilingExpression(compiler, header.getParameter(false, i).defaultValue);
} else {
// invalid
return CastedExpression.invalid(compiler.at(position).invalid(CompileErrors.missingParameter(header.getParameter(false, i).name)));
return CastedExpression.invalid(position, CompileErrors.missingParameter(header.getParameter(false, i).name));
}
return argument.cast(CastedEval.implicit(compiler, position, header.getParameterType(false, i)));
})
Expand All @@ -248,6 +255,16 @@ private static <T extends AnyMethod> MatchedCallArguments<T> matchNormal(
.max(Comparator.naturalOrder())
.orElse(CastedExpression.Level.EXACT);

if (level == CastedExpression.Level.INVALID) {
CastedExpression firstInvalid = Stream.of(providedArguments)
.filter(e -> e.level == CastedExpression.Level.INVALID)
.findFirst()
.orElseThrow(() -> new IllegalStateException("Should never happen"));

return new MatchedCallArguments<>(firstInvalid.error,
new CallArguments(CastedExpression.Level.INVALID, expansionTypeArguments, typeArguments, Expression.NONE));
}

return new MatchedCallArguments<>(
instancedMethod,
new CallArguments(level, expansionTypeArguments, typeArguments, Stream.of(providedArguments).map(casted -> casted.value).toArray(Expression[]::new))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
import org.openzen.zencode.shared.CodePosition;
import org.openzen.zenscript.codemodel.compilation.expression.AbstractCompilingExpression;
import org.openzen.zenscript.codemodel.expression.Expression;
import org.openzen.zenscript.codemodel.expression.MemoizedExpression;
import org.openzen.zenscript.codemodel.ssa.CodeBlockStatement;
import org.openzen.zenscript.codemodel.ssa.SSAVariableCollector;

public class MemoizedCompilingExpression extends AbstractCompilingExpression {
private final CompilingExpression expression;
private Expression result;
private MemoizedExpression result;

public MemoizedCompilingExpression(ExpressionCompiler compiler, CodePosition position, CompilingExpression expression) {
super(compiler, position);
Expand All @@ -18,8 +19,11 @@ public MemoizedCompilingExpression(ExpressionCompiler compiler, CodePosition pos

@Override
public Expression eval() {
if (result == null)
result = expression.eval();
if (result == null) {
result = new MemoizedExpression(expression.eval());
} else {
result.markAccessedMoreThanOnce();
}
return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
import org.openzen.zencode.shared.CodePosition;
import org.openzen.zenscript.codemodel.GenericName;
import org.openzen.zenscript.codemodel.expression.Expression;
import org.openzen.zenscript.codemodel.expression.GetFieldExpression;
import org.openzen.zenscript.codemodel.expression.modifiable.ModifiableExpression;
import org.openzen.zenscript.codemodel.expression.modifiable.ModifiableInvalidExpression;
import org.openzen.zenscript.codemodel.expression.modifiable.ModifiablePropertyExpression;
import org.openzen.zenscript.codemodel.identifiers.instances.MethodInstance;
import org.openzen.zenscript.codemodel.ssa.CodeBlockStatement;
import org.openzen.zenscript.codemodel.ssa.SSAVariableCollector;
import org.openzen.zenscript.codemodel.type.TypeID;
Expand All @@ -29,10 +32,19 @@ public Expression eval() {
return compiler.at(position).invalid(CompileErrors.typeArgumentsNotAllowedHere());

Expression instance = this.instance.eval();
return compiler.resolve(instance.type)
ResolvedType resolve = compiler.resolve(instance.type);

Optional<Expression> byGetter = resolve
.findGetter(name.name)
.map(getter -> getter.call(compiler, position, instance, TypeID.NONE, CompilingExpression.NONE))
.orElseGet(() -> compiler.at(position).invalid(CompileErrors.noMemberInType(instance.type, name.name)));
.map(getter -> getter.call(compiler, position, instance, TypeID.NONE, CompilingExpression.NONE));

return byGetter.orElseGet(() -> resolve
.findField(name.name)
.map(field -> field.get(compiler.at(position), instance))
.orElseGet(
() -> compiler.at(position).invalid(CompileErrors.noMemberInType(instance.type, name.name))
));

}

@Override
Expand Down Expand Up @@ -66,6 +78,27 @@ public Optional<CompilingCallable> call() {
return Optional.of(result.orElseGet(() -> new InvalidCompilingExpression(compiler, position, CompileErrors.noMemberInType(instance.type, name.name))));
}

@Override
public Optional<ModifiableExpression> asModifiable() {
Expression instance = this.instance.eval();
ResolvedType resolvedType = compiler.resolve(instance.type);
Optional<InstanceCallable> getter = resolvedType.findGetter(name.name);
Optional<InstanceCallable> setter = resolvedType.findSetter(name.name);
if (getter.isPresent() && setter.isPresent()) {
Optional<MethodInstance> getterMethod = getter.get().asSingleMethod();
if (!getterMethod.isPresent()) {
return Optional.of(new ModifiableInvalidExpression(position, instance.type, CompileErrors.invalidPropertyGetter(instance.type, name.name)));
}
Optional<MethodInstance> setterMethod = setter.get().asSingleMethod();
if (!setterMethod.isPresent()) {
return Optional.of(new ModifiableInvalidExpression(position, instance.type, CompileErrors.invalidPropertySetter(instance.type, name.name)));
}
return Optional.of(new ModifiablePropertyExpression(instance, getterMethod.get(), setterMethod.get()));
} else {
return Optional.empty();
}
}

@Override
public CompilingExpression assign(CompilingExpression value) {
return new CompilingAssignment(compiler, position, instance, name, value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,6 @@ public Expression call(CodePosition position, CompilingExpression[] arguments) {

@Override
public CastedExpression casted(CodePosition position, CastedEval cast, CompilingExpression[] arguments) {
return CastedExpression.invalid(compiler.at(position).invalid(error));
return CastedExpression.invalid(position, error);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public Expression eval() {

@Override
public CastedExpression cast(CastedEval cast) {
return CastedExpression.invalid(eval());
return CastedExpression.invalid(position, CompileErrors.cannotUseTypeAsValue());
}

@Override
Expand Down
Loading

0 comments on commit 5eb14f6

Please sign in to comment.