Skip to content
This repository has been archived by the owner on Jul 17, 2024. It is now read-only.

Commit

Permalink
feat: Add expand, concat, consecutive collector, collectAndThen colle…
Browse files Browse the repository at this point in the history
…ctor (#5)
  • Loading branch information
Christopher-Chianelli authored Mar 4, 2024
1 parent ce4e8fe commit 632a092
Show file tree
Hide file tree
Showing 53 changed files with 1,971 additions and 666 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
*
* ex: a.__add__(b)
*/
public enum PythonBinaryOperators {
public enum PythonBinaryOperator {
// Comparable operations ( from https://docs.python.org/3/reference/datamodel.html#object.__lt__ )
LESS_THAN("<", "__lt__", "__gt__", true),
LESS_THAN_OR_EQUAL("<=", "__le__", "__ge__", true),
Expand All @@ -34,19 +34,19 @@ public enum PythonBinaryOperators {
OR("|", "__or__", "__ror__"),

// In-place numeric binary operations variations
INPLACE_POWER("**=", "__ipow__", PythonBinaryOperators.POWER),
INPLACE_MULTIPLY("*=", "__imul__", PythonBinaryOperators.MULTIPLY),
INPLACE_MATRIX_MULTIPLY("@=", "__imatmul__", PythonBinaryOperators.MATRIX_MULTIPLY),
INPLACE_FLOOR_DIVIDE("//=", "__ifloordiv__", PythonBinaryOperators.FLOOR_DIVIDE),
INPLACE_TRUE_DIVIDE("/=", "__itruediv__", PythonBinaryOperators.TRUE_DIVIDE),
INPLACE_MODULO("%=", "__imod__", PythonBinaryOperators.MODULO),
INPLACE_ADD("+=", "__iadd__", PythonBinaryOperators.ADD),
INPLACE_SUBTRACT("-=", "__isub__", PythonBinaryOperators.SUBTRACT),
INPLACE_LSHIFT("<<=", "__ilshift__", PythonBinaryOperators.LSHIFT),
INPLACE_RSHIFT(">>=", "__irshift__", PythonBinaryOperators.RSHIFT),
INPLACE_AND("&=", "__iand__", PythonBinaryOperators.AND),
INPLACE_XOR("^=", "__ixor__", PythonBinaryOperators.XOR),
INPLACE_OR("|=", "__ior__", PythonBinaryOperators.OR),
INPLACE_POWER("**=", "__ipow__", PythonBinaryOperator.POWER),
INPLACE_MULTIPLY("*=", "__imul__", PythonBinaryOperator.MULTIPLY),
INPLACE_MATRIX_MULTIPLY("@=", "__imatmul__", PythonBinaryOperator.MATRIX_MULTIPLY),
INPLACE_FLOOR_DIVIDE("//=", "__ifloordiv__", PythonBinaryOperator.FLOOR_DIVIDE),
INPLACE_TRUE_DIVIDE("/=", "__itruediv__", PythonBinaryOperator.TRUE_DIVIDE),
INPLACE_MODULO("%=", "__imod__", PythonBinaryOperator.MODULO),
INPLACE_ADD("+=", "__iadd__", PythonBinaryOperator.ADD),
INPLACE_SUBTRACT("-=", "__isub__", PythonBinaryOperator.SUBTRACT),
INPLACE_LSHIFT("<<=", "__ilshift__", PythonBinaryOperator.LSHIFT),
INPLACE_RSHIFT(">>=", "__irshift__", PythonBinaryOperator.RSHIFT),
INPLACE_AND("&=", "__iand__", PythonBinaryOperator.AND),
INPLACE_XOR("^=", "__ixor__", PythonBinaryOperator.XOR),
INPLACE_OR("|=", "__ior__", PythonBinaryOperator.OR),

// List operations
// https://docs.python.org/3/reference/datamodel.html#object.__getitem__
Expand Down Expand Up @@ -81,33 +81,33 @@ public enum PythonBinaryOperators {
public final String dunderMethod;
public final String rightDunderMethod;
public final boolean isComparisonMethod;
public final PythonBinaryOperators fallbackOperation;
public final PythonBinaryOperator fallbackOperation;

PythonBinaryOperators(String operatorSymbol, String dunderMethod) {
PythonBinaryOperator(String operatorSymbol, String dunderMethod) {
this.operatorSymbol = operatorSymbol;
this.dunderMethod = dunderMethod;
this.rightDunderMethod = null;
this.isComparisonMethod = false;
this.fallbackOperation = null;
}

PythonBinaryOperators(String operatorSymbol, String dunderMethod, String rightDunderMethod) {
PythonBinaryOperator(String operatorSymbol, String dunderMethod, String rightDunderMethod) {
this.operatorSymbol = operatorSymbol;
this.dunderMethod = dunderMethod;
this.rightDunderMethod = rightDunderMethod;
this.isComparisonMethod = false;
this.fallbackOperation = null;
}

PythonBinaryOperators(String operatorSymbol, String dunderMethod, String rightDunderMethod, boolean isComparisonMethod) {
PythonBinaryOperator(String operatorSymbol, String dunderMethod, String rightDunderMethod, boolean isComparisonMethod) {
this.operatorSymbol = operatorSymbol;
this.dunderMethod = dunderMethod;
this.rightDunderMethod = rightDunderMethod;
this.isComparisonMethod = isComparisonMethod;
this.fallbackOperation = null;
}

PythonBinaryOperators(String operatorSymbol, String dunderMethod, PythonBinaryOperators fallbackOperation) {
PythonBinaryOperator(String operatorSymbol, String dunderMethod, PythonBinaryOperator fallbackOperation) {
this.operatorSymbol = operatorSymbol;
this.dunderMethod = dunderMethod;
this.rightDunderMethod = null;
Expand Down Expand Up @@ -135,69 +135,69 @@ public boolean isComparisonMethod() {
return isComparisonMethod;
}

public Optional<PythonBinaryOperators> getFallbackOperation() {
public Optional<PythonBinaryOperator> getFallbackOperation() {
return Optional.ofNullable(fallbackOperation);
}

public static PythonBinaryOperators lookup(int instructionArg) {
public static PythonBinaryOperator lookup(int instructionArg) {
// As defined by https://github.com/python/cpython/blob/0faa0ba240e815614e5a2900e48007acac41b214/Python/ceval.c#L299

// Binary operations are in alphabetical order (note: CPython refer to Modulo as Remainder),
// and are followed by the inplace operations in the same order
switch (instructionArg) {
case 0:
return PythonBinaryOperators.ADD;
return PythonBinaryOperator.ADD;
case 1:
return PythonBinaryOperators.AND;
return PythonBinaryOperator.AND;
case 2:
return PythonBinaryOperators.FLOOR_DIVIDE;
return PythonBinaryOperator.FLOOR_DIVIDE;
case 3:
return PythonBinaryOperators.LSHIFT;
return PythonBinaryOperator.LSHIFT;
case 4:
return PythonBinaryOperators.MATRIX_MULTIPLY;
return PythonBinaryOperator.MATRIX_MULTIPLY;
case 5:
return PythonBinaryOperators.MULTIPLY;
return PythonBinaryOperator.MULTIPLY;
case 6:
return PythonBinaryOperators.MODULO;
return PythonBinaryOperator.MODULO;
case 7:
return PythonBinaryOperators.OR;
return PythonBinaryOperator.OR;
case 8:
return PythonBinaryOperators.POWER;
return PythonBinaryOperator.POWER;
case 9:
return PythonBinaryOperators.RSHIFT;
return PythonBinaryOperator.RSHIFT;
case 10:
return PythonBinaryOperators.SUBTRACT;
return PythonBinaryOperator.SUBTRACT;
case 11:
return PythonBinaryOperators.TRUE_DIVIDE;
return PythonBinaryOperator.TRUE_DIVIDE;
case 12:
return PythonBinaryOperators.XOR;
return PythonBinaryOperator.XOR;

case 13:
return PythonBinaryOperators.INPLACE_ADD;
return PythonBinaryOperator.INPLACE_ADD;
case 14:
return PythonBinaryOperators.INPLACE_AND;
return PythonBinaryOperator.INPLACE_AND;
case 15:
return PythonBinaryOperators.INPLACE_FLOOR_DIVIDE;
return PythonBinaryOperator.INPLACE_FLOOR_DIVIDE;
case 16:
return PythonBinaryOperators.INPLACE_LSHIFT;
return PythonBinaryOperator.INPLACE_LSHIFT;
case 17:
return PythonBinaryOperators.INPLACE_MATRIX_MULTIPLY;
return PythonBinaryOperator.INPLACE_MATRIX_MULTIPLY;
case 18:
return PythonBinaryOperators.INPLACE_MULTIPLY;
return PythonBinaryOperator.INPLACE_MULTIPLY;
case 19:
return PythonBinaryOperators.INPLACE_MODULO;
return PythonBinaryOperator.INPLACE_MODULO;
case 20:
return PythonBinaryOperators.INPLACE_OR;
return PythonBinaryOperator.INPLACE_OR;
case 21:
return PythonBinaryOperators.INPLACE_POWER;
return PythonBinaryOperator.INPLACE_POWER;
case 22:
return PythonBinaryOperators.INPLACE_RSHIFT;
return PythonBinaryOperator.INPLACE_RSHIFT;
case 23:
return PythonBinaryOperators.INPLACE_SUBTRACT;
return PythonBinaryOperator.INPLACE_SUBTRACT;
case 24:
return PythonBinaryOperators.INPLACE_TRUE_DIVIDE;
return PythonBinaryOperator.INPLACE_TRUE_DIVIDE;
case 25:
return PythonBinaryOperators.INPLACE_XOR;
return PythonBinaryOperator.INPLACE_XOR;

default:
throw new IllegalArgumentException("Unknown binary op id: " + instructionArg);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -633,7 +633,7 @@ private static void generateAdvanceGeneratorMethodForYieldFrom(ClassWriter class
"sentValue",
Type.getDescriptor(PythonLikeObject.class));
FunctionImplementor.callBinaryMethod(methodVisitor,
PythonBinaryOperators.SEND.dunderMethod);
PythonBinaryOperator.SEND.dunderMethod);
break;
}
case 2: { // throw
Expand Down Expand Up @@ -687,7 +687,7 @@ private static void generateAdvanceGeneratorMethodForYieldFrom(ClassWriter class
// Swap so it Generator, Throwable instead of Throwable, Generator
methodVisitor.visitInsn(Opcodes.SWAP);
FunctionImplementor.callBinaryMethod(methodVisitor,
PythonBinaryOperators.THROW.dunderMethod);
PythonBinaryOperator.THROW.dunderMethod);
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,9 @@ default PythonLikeType __getGenericType() {
PythonLikeType type = __getType();
PythonLikeObject typeResult = type.__getAttributeOrNull(name);
if (typeResult != null) {
PythonLikeObject maybeDescriptor = typeResult.__getAttributeOrNull(PythonTernaryOperators.GET.dunderMethod);
PythonLikeObject maybeDescriptor = typeResult.__getAttributeOrNull(PythonTernaryOperator.GET.dunderMethod);
if (maybeDescriptor == null) {
maybeDescriptor = typeResult.__getType().__getAttributeOrNull(PythonTernaryOperators.GET.dunderMethod);
maybeDescriptor = typeResult.__getType().__getAttributeOrNull(PythonTernaryOperator.GET.dunderMethod);
}

if (maybeDescriptor != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*
* ex: a.__setitem__(key, value)
*/
public enum PythonTernaryOperators {
public enum PythonTernaryOperator {
// Descriptor operations
// https://docs.python.org/3/howto/descriptor.html
GET("__get__"),
Expand All @@ -21,7 +21,7 @@ public enum PythonTernaryOperators {

public final String dunderMethod;

PythonTernaryOperators(String dunderMethod) {
PythonTernaryOperator(String dunderMethod) {
this.dunderMethod = dunderMethod;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import java.util.List;
import java.util.Map;

import ai.timefold.jpyinterpreter.PythonBinaryOperators;
import ai.timefold.jpyinterpreter.PythonBinaryOperator;
import ai.timefold.jpyinterpreter.PythonLikeObject;
import ai.timefold.jpyinterpreter.types.PythonLikeFunction;
import ai.timefold.jpyinterpreter.types.PythonString;
Expand All @@ -12,19 +12,19 @@
public class BinaryDunderBuiltin implements PythonLikeFunction {
private final String DUNDER_METHOD_NAME;

public static final BinaryDunderBuiltin DIVMOD = new BinaryDunderBuiltin(PythonBinaryOperators.DIVMOD);
public static final BinaryDunderBuiltin ADD = new BinaryDunderBuiltin(PythonBinaryOperators.ADD);
public static final BinaryDunderBuiltin LESS_THAN = new BinaryDunderBuiltin(PythonBinaryOperators.LESS_THAN);
public static final BinaryDunderBuiltin GET_ITEM = new BinaryDunderBuiltin(PythonBinaryOperators.GET_ITEM);
public static final BinaryDunderBuiltin GET_ATTRIBUTE = new BinaryDunderBuiltin(PythonBinaryOperators.GET_ATTRIBUTE);
public static final BinaryDunderBuiltin POWER = new BinaryDunderBuiltin(PythonBinaryOperators.POWER);
public static final BinaryDunderBuiltin FORMAT = new BinaryDunderBuiltin(PythonBinaryOperators.FORMAT);
public static final BinaryDunderBuiltin DIVMOD = new BinaryDunderBuiltin(PythonBinaryOperator.DIVMOD);
public static final BinaryDunderBuiltin ADD = new BinaryDunderBuiltin(PythonBinaryOperator.ADD);
public static final BinaryDunderBuiltin LESS_THAN = new BinaryDunderBuiltin(PythonBinaryOperator.LESS_THAN);
public static final BinaryDunderBuiltin GET_ITEM = new BinaryDunderBuiltin(PythonBinaryOperator.GET_ITEM);
public static final BinaryDunderBuiltin GET_ATTRIBUTE = new BinaryDunderBuiltin(PythonBinaryOperator.GET_ATTRIBUTE);
public static final BinaryDunderBuiltin POWER = new BinaryDunderBuiltin(PythonBinaryOperator.POWER);
public static final BinaryDunderBuiltin FORMAT = new BinaryDunderBuiltin(PythonBinaryOperator.FORMAT);

public BinaryDunderBuiltin(String dunderMethodName) {
DUNDER_METHOD_NAME = dunderMethodName;
}

public BinaryDunderBuiltin(PythonBinaryOperators operator) {
public BinaryDunderBuiltin(PythonBinaryOperator operator) {
DUNDER_METHOD_NAME = operator.getDunderMethod();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
import java.util.stream.IntStream;
import java.util.stream.StreamSupport;

import ai.timefold.jpyinterpreter.PythonBinaryOperators;
import ai.timefold.jpyinterpreter.PythonBinaryOperator;
import ai.timefold.jpyinterpreter.PythonBytecodeToJavaBytecodeTranslator;
import ai.timefold.jpyinterpreter.PythonInterpreter;
import ai.timefold.jpyinterpreter.PythonLikeObject;
Expand Down Expand Up @@ -1377,7 +1377,7 @@ public static PythonLikeObject reversed(List<PythonLikeObject> positionalArgs,
}

if (sequenceType.__getAttributeOrNull(PythonUnaryOperator.LENGTH.getDunderMethod()) != null &&
sequenceType.__getAttributeOrNull(PythonBinaryOperators.GET_ITEM.getDunderMethod()) != null) {
sequenceType.__getAttributeOrNull(PythonBinaryOperator.GET_ITEM.getDunderMethod()) != null) {
PythonInteger length = (PythonInteger) UnaryDunderBuiltin.LENGTH.invoke(sequence);
Iterator<PythonLikeObject> reversedIterator = new Iterator<>() {
PythonInteger current = length.subtract(PythonInteger.ONE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import java.util.Map;

import ai.timefold.jpyinterpreter.PythonLikeObject;
import ai.timefold.jpyinterpreter.PythonTernaryOperators;
import ai.timefold.jpyinterpreter.PythonTernaryOperator;
import ai.timefold.jpyinterpreter.types.PythonLikeFunction;
import ai.timefold.jpyinterpreter.types.PythonString;
import ai.timefold.jpyinterpreter.types.errors.ValueError;
Expand All @@ -13,14 +13,14 @@ public class TernaryDunderBuiltin implements PythonLikeFunction {
private final String DUNDER_METHOD_NAME;

public static final TernaryDunderBuiltin POWER = new TernaryDunderBuiltin("__pow__");
public static final TernaryDunderBuiltin SETATTR = new TernaryDunderBuiltin(PythonTernaryOperators.SET_ATTRIBUTE);
public static final TernaryDunderBuiltin GET_DESCRIPTOR = new TernaryDunderBuiltin(PythonTernaryOperators.GET);
public static final TernaryDunderBuiltin SETATTR = new TernaryDunderBuiltin(PythonTernaryOperator.SET_ATTRIBUTE);
public static final TernaryDunderBuiltin GET_DESCRIPTOR = new TernaryDunderBuiltin(PythonTernaryOperator.GET);

public TernaryDunderBuiltin(String dunderMethodName) {
DUNDER_METHOD_NAME = dunderMethodName;
}

public TernaryDunderBuiltin(PythonTernaryOperators operator) {
public TernaryDunderBuiltin(PythonTernaryOperator operator) {
DUNDER_METHOD_NAME = operator.getDunderMethod();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@

import ai.timefold.jpyinterpreter.FunctionMetadata;
import ai.timefold.jpyinterpreter.LocalVariableHelper;
import ai.timefold.jpyinterpreter.PythonBinaryOperators;
import ai.timefold.jpyinterpreter.PythonBinaryOperator;
import ai.timefold.jpyinterpreter.PythonBytecodeInstruction;
import ai.timefold.jpyinterpreter.PythonLikeObject;
import ai.timefold.jpyinterpreter.PythonTernaryOperators;
import ai.timefold.jpyinterpreter.PythonTernaryOperator;
import ai.timefold.jpyinterpreter.PythonUnaryOperator;
import ai.timefold.jpyinterpreter.StackMetadata;
import ai.timefold.jpyinterpreter.types.PythonSlice;
Expand Down Expand Up @@ -481,7 +481,7 @@ public static void containsOperator(MethodVisitor methodVisitor, StackMetadata s
DunderOperatorImplementor.binaryOperator(methodVisitor, stackMetadata
.pop(2)
.push(stackMetadata.getTOSValueSource())
.push(stackMetadata.getValueSourceForStackIndex(1)), PythonBinaryOperators.CONTAINS);
.push(stackMetadata.getValueSourceForStackIndex(1)), PythonBinaryOperator.CONTAINS);
// TODO: implement fallback on __iter__ if __contains__ does not exist
if (instruction.arg == 1) {
PythonBuiltinOperatorImplementor.performNotOnTOS(methodVisitor);
Expand All @@ -501,7 +501,7 @@ public static void setItem(FunctionMetadata functionMetadata, StackMetadata stac
DunderOperatorImplementor.ternaryOperator(functionMetadata, stackMetadata.pop(3)
.push(stackMetadata.getValueSourceForStackIndex(1))
.push(stackMetadata.getValueSourceForStackIndex(0))
.push(stackMetadata.getValueSourceForStackIndex(2)), PythonTernaryOperators.SET_ITEM);
.push(stackMetadata.getValueSourceForStackIndex(2)), PythonTernaryOperator.SET_ITEM);
StackManipulationImplementor.popTOS(methodVisitor);
}

Expand Down
Loading

0 comments on commit 632a092

Please sign in to comment.