Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -164,31 +164,29 @@ public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelaye
} else { // first needs converting
// attempt to convert <first> to types that make valid operations with <second>
Class<?> secondClass = second.getReturnType();
Class[] leftTypes = Arithmetics.getOperations(operator).stream()
.filter(info -> info.getRight().isAssignableFrom(secondClass))
.map(OperationInfo::getLeft)
.toArray(Class[]::new);
if (leftTypes.length == 0) { // no known operations with second's type
List<? extends OperationInfo<?, ?, ?>> operations = Arithmetics.lookupRightOperations(operator, secondClass);
if (operations.isEmpty()) { // no known operations with second's type
if (secondClass != Object.class) // there won't be any operations
return error(first.getReturnType(), secondClass);
first = (Expression<L>) first.getConvertedExpression(Object.class);
} else {
first = (Expression<L>) first.getConvertedExpression(leftTypes);
first = (Expression<L>) first.getConvertedExpression(operations.stream()
.map(OperationInfo::getLeft)
.toArray(Class[]::new));
}
}
} else if (second instanceof UnparsedLiteral) { // second needs converting
// attempt to convert <second> to types that make valid operations with <first>
Class<?> firstClass = first.getReturnType();
List<? extends OperationInfo<?, ?, ?>> operations = Arithmetics.getOperations(operator, firstClass);
List<? extends OperationInfo<?, ?, ?>> operations = Arithmetics.lookupLeftOperations(operator, firstClass);
if (operations.isEmpty()) { // no known operations with first's type
if (firstClass != Object.class) // there won't be any operations
return error(firstClass, second.getReturnType());
second = (Expression<R>) second.getConvertedExpression(Object.class);
} else {
second = (Expression<R>) second.getConvertedExpression(operations.stream()
.map(OperationInfo::getRight)
.toArray(Class[]::new)
);
.toArray(Class[]::new));
}
}

Expand Down Expand Up @@ -223,14 +221,13 @@ public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelaye
Class<?>[] returnTypes = null;
if (!(firstClass == Object.class && secondClass == Object.class)) { // both aren't object
if (firstClass == Object.class) {
returnTypes = Arithmetics.getOperations(operator).stream()
.filter(info -> info.getRight().isAssignableFrom(secondClass))
returnTypes = Arithmetics.lookupRightOperations(operator, secondClass).stream()
.map(OperationInfo::getReturnType)
.toArray(Class[]::new);
} else { // secondClass is Object
returnTypes = Arithmetics.getOperations(operator, firstClass).stream()
.map(OperationInfo::getReturnType)
.toArray(Class[]::new);
returnTypes = Arithmetics.lookupLeftOperations(operator, firstClass).stream()
.map(OperationInfo::getReturnType)
.toArray(Class[]::new);
}
}
if (returnTypes == null) { // both are object; can't determine anything
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import java.util.List;
import java.util.Map;
import java.util.Collection;
import java.util.Objects;
import java.util.Set;
import java.util.HashSet;
import java.util.function.Supplier;
Expand Down Expand Up @@ -83,6 +84,47 @@ public static boolean operationExists(Operator operator, Class<?> leftClass, Cla
.collect(Collectors.toList());
}

/**
* Returns all valid operations from {@code operator} and {@code leftClass}.
* Unlike {@link #getOperations(Operator, Class)}, this method considers Converters.
* @param operator The operator for the desired operations
* @param leftClass Class representing the desired left-hand argument type
* @return A list containing all valid operations from {@code operator} and {@code leftClass}.
* @param <L> The type of the left-hand argument
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public static <L> List<OperationInfo<L, ?, ?>> lookupLeftOperations(Operator operator, Class<L> leftClass) {
return (List) getOperations(operator).stream()
.map(info -> {
if (info.getLeft().isAssignableFrom(leftClass)) {
return info;
}
return info.getConverted(leftClass, info.getRight(), info.getReturnType());
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
}

/**
* Returns all valid operations from {@code operator} and {@code rightClass}.
* @param operator The operator for the desired operations
* @param rightClass Class representing the desired right-hand argument type
* @return A list containing all valid operations from {@code operator} and {@code rightClass}.
* @param <R> The type of the right-hand argument
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public static <R> List<OperationInfo<?, R, ?>> lookupRightOperations(Operator operator, Class<R> rightClass) {
return (List) getOperations(operator).stream()
.map(info -> {
if (info.getRight().isAssignableFrom(rightClass)) {
return info;
}
return info.getConverted(info.getLeft(), rightClass, info.getReturnType());
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
}

@Nullable
@SuppressWarnings("unchecked")
public static <L, R, T> OperationInfo<L, R, T> getOperationInfo(Operator operator, Class<L> leftClass, Class<R> rightClass, Class<T> returnType) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,3 +278,10 @@ test "arithmetic type switcheroo":
loop 2 times:
set {_x} to {_a} + {_b}
set {_b} to 5

local function arithmetic_xp() returns experience:
return 5 xp

test "arithmetic parse time conversion":
set {_x} to arithmetic_xp() + 5
assert {_x} is 10 with "failed to calculate experience + number"