list arithmetic fully implemented
This commit is contained in:
parent
a7f89b0776
commit
e62816eff5
|
@ -3,6 +3,7 @@ package at.petrak.hexcasting.api.casting.arithmetic.operator;
|
|||
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate;
|
||||
import at.petrak.hexcasting.api.casting.iota.Iota;
|
||||
import at.petrak.hexcasting.api.casting.iota.IotaType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public abstract class Operator {
|
||||
public final int arity;
|
||||
|
@ -14,7 +15,7 @@ public abstract class Operator {
|
|||
this.accepts = accepts;
|
||||
}
|
||||
|
||||
public abstract Iterable<Iota> apply(Iterable<Iota> iotas);
|
||||
public abstract @NotNull Iterable<Iota> apply(@NotNull Iterable<Iota> iotas);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends Iota> T downcast(Iota iota, IotaType<T> iotaType) {
|
||||
|
|
|
@ -3,6 +3,7 @@ package at.petrak.hexcasting.api.casting.arithmetic.operator;
|
|||
|
||||
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate;
|
||||
import at.petrak.hexcasting.api.casting.iota.Iota;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.BinaryOperator;
|
||||
|
@ -16,7 +17,7 @@ public class OperatorBinary extends Operator {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Iota> apply(Iterable<Iota> iotas) {
|
||||
public @NotNull Iterable<Iota> apply(@NotNull Iterable<Iota> iotas) {
|
||||
var it = iotas.iterator();
|
||||
return List.of(inner.apply(it.next(), it.next()));
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package at.petrak.hexcasting.api.casting.arithmetic.operator;
|
|||
|
||||
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate;
|
||||
import at.petrak.hexcasting.api.casting.iota.Iota;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
@ -16,7 +17,7 @@ public class OperatorUnary extends Operator {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Iota> apply(Iterable<Iota> iotas) {
|
||||
public @NotNull Iterable<Iota> apply(@NotNull Iterable<Iota> iotas) {
|
||||
return List.of(inner.apply(iotas.iterator().next()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,75 +1,57 @@
|
|||
package at.petrak.hexcasting.common.casting.arithmetic;
|
||||
package at.petrak.hexcasting.common.casting.arithmetic
|
||||
|
||||
import at.petrak.hexcasting.api.casting.arithmetic.Arithmetic;
|
||||
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate;
|
||||
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaPredicate;
|
||||
import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator;
|
||||
import at.petrak.hexcasting.api.casting.iota.DoubleIota;
|
||||
import at.petrak.hexcasting.api.casting.iota.ListIota;
|
||||
import at.petrak.hexcasting.common.casting.arithmetic.operator.list.*;
|
||||
import at.petrak.hexcasting.api.casting.arithmetic.operator.OperatorUnary;
|
||||
import at.petrak.hexcasting.api.casting.math.HexPattern;
|
||||
import at.petrak.hexcasting.api.casting.SpellList
|
||||
import at.petrak.hexcasting.api.casting.arithmetic.Arithmetic
|
||||
import at.petrak.hexcasting.api.casting.arithmetic.Arithmetic.*
|
||||
import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator
|
||||
import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator.downcast
|
||||
import at.petrak.hexcasting.api.casting.arithmetic.operator.OperatorBinary
|
||||
import at.petrak.hexcasting.api.casting.arithmetic.operator.OperatorUnary
|
||||
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate.all
|
||||
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate.pair
|
||||
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaPredicate
|
||||
import at.petrak.hexcasting.api.casting.iota.DoubleIota
|
||||
import at.petrak.hexcasting.api.casting.iota.Iota
|
||||
import at.petrak.hexcasting.api.casting.iota.ListIota
|
||||
import at.petrak.hexcasting.api.casting.math.HexPattern
|
||||
import at.petrak.hexcasting.common.casting.arithmetic.operator.list.*
|
||||
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.LIST
|
||||
|
||||
import java.util.List;
|
||||
object ListArithmetic : Arithmetic {
|
||||
private val OPS = listOf(
|
||||
INDEX,
|
||||
SLICE,
|
||||
APPEND,
|
||||
UNAPPEND,
|
||||
ADD,
|
||||
ABS,
|
||||
REV,
|
||||
INDEX_OF,
|
||||
REMOVE,
|
||||
REPLACE,
|
||||
CONS,
|
||||
UNCONS
|
||||
)
|
||||
|
||||
import static at.petrak.hexcasting.api.casting.arithmetic.operator.Operator.downcast;
|
||||
import static at.petrak.hexcasting.common.lib.hex.HexIotaTypes.*;
|
||||
override fun arithName() = "list_ops"
|
||||
|
||||
public enum ListArithmetic implements Arithmetic {
|
||||
INSTANCE;
|
||||
override fun opTypes(): Iterable<HexPattern> = OPS
|
||||
|
||||
public static final List<HexPattern> OPS = List.of(
|
||||
INDEX,
|
||||
SLICE,
|
||||
APPEND,
|
||||
UNAPPEND,
|
||||
ADD,
|
||||
ABS,
|
||||
REV,
|
||||
INDEX_OF,
|
||||
REMOVE,
|
||||
REPLACE,
|
||||
CONS,
|
||||
UNCONS
|
||||
);
|
||||
|
||||
@Override
|
||||
public String arithName() {
|
||||
return "list_ops";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<HexPattern> opTypes() {
|
||||
return OPS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Operator getOperator(HexPattern pattern) {
|
||||
if (pattern.equals(INDEX)) {
|
||||
return OperatorIndex.INSTANCE;
|
||||
} else if (pattern.equals(SLICE)) {
|
||||
return OperatorSlice.INSTANCE;
|
||||
} else if (pattern.equals(APPEND)) {
|
||||
return OperatorAppend.INSTANCE;
|
||||
} else if (pattern.equals(UNAPPEND)) {
|
||||
return OperatorUnappend.INSTANCE;
|
||||
} else if (pattern.equals(ADD)) {
|
||||
return OperatorConcat.INSTANCE;
|
||||
} else if (pattern.equals(ABS)) {
|
||||
return new OperatorUnary(IotaMultiPredicate.any(IotaPredicate.ofType(LIST), IotaPredicate.ofType(LIST)), iota -> new DoubleIota(downcast(iota, LIST).getList().size()));
|
||||
} else if (pattern.equals(REV)) {
|
||||
return new OperatorUnary(IotaMultiPredicate.any(IotaPredicate.ofType(LIST), IotaPredicate.ofType(LIST)), iota -> new ListIota(downcast(iota, LIST).getList()));
|
||||
} else if (pattern.equals(INDEX_OF)) {
|
||||
return new OperatorUnary(IotaMultiPredicate.any(IotaPredicate.ofType(LIST), IotaPredicate.ofType(LIST)), iota -> iota);
|
||||
} else if (pattern.equals(REMOVE)) {
|
||||
return new OperatorUnary(IotaMultiPredicate.any(IotaPredicate.ofType(LIST), IotaPredicate.ofType(LIST)), iota -> iota);
|
||||
} else if (pattern.equals(REPLACE)) {
|
||||
return new OperatorUnary(IotaMultiPredicate.any(IotaPredicate.ofType(LIST), IotaPredicate.ofType(LIST)), iota -> iota);
|
||||
} else if (pattern.equals(CONS)) {
|
||||
return new OperatorUnary(IotaMultiPredicate.any(IotaPredicate.ofType(LIST), IotaPredicate.ofType(LIST)), iota -> iota);
|
||||
} else if (pattern.equals(UNCONS)) {
|
||||
return new OperatorUnary(IotaMultiPredicate.any(IotaPredicate.ofType(LIST), IotaPredicate.ofType(LIST)), iota -> iota);
|
||||
override fun getOperator(pattern: HexPattern): Operator? {
|
||||
return when (pattern) {
|
||||
INDEX -> OperatorIndex
|
||||
SLICE -> OperatorSlice
|
||||
APPEND -> OperatorAppend
|
||||
UNAPPEND -> OperatorUnappend
|
||||
ADD -> OperatorConcat
|
||||
ABS -> OperatorUnary(all(IotaPredicate.ofType(LIST))) { iota: Iota -> DoubleIota(downcast(iota, LIST).list.size().toDouble()) }
|
||||
REV -> OperatorUnary(all(IotaPredicate.ofType(LIST))) { iota: Iota -> ListIota(downcast(iota, LIST).list.toList().asReversed()) }
|
||||
INDEX_OF -> OperatorIndexOf
|
||||
REMOVE -> OperatorRemove
|
||||
REPLACE -> OperatorReplace
|
||||
CONS -> OperatorBinary(pair(IotaPredicate.ofType(LIST), IotaPredicate.TRUE)) { list, iota -> ListIota(SpellList.LPair(iota, downcast(list, LIST).list)) }
|
||||
UNCONS -> OperatorUnCons
|
||||
else -> null
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,29 @@ fun Iterator<IndexedValue<Iota>>.nextList(argc: Int = 0): SpellList {
|
|||
throw MishapInvalidIota.ofType(x, if (argc == 0) idx else argc - (idx + 1), "list")
|
||||
}
|
||||
}
|
||||
fun Iterator<IndexedValue<Iota>>.nextInt(argc: Int = 0): Int {
|
||||
val (idx, x) = this.next()
|
||||
if (x is DoubleIota) {
|
||||
val double = x.double
|
||||
val rounded = double.roundToInt()
|
||||
if (abs(double - rounded) <= DoubleIota.TOLERANCE) {
|
||||
return rounded
|
||||
}
|
||||
}
|
||||
throw MishapInvalidIota.of(x, if (argc == 0) idx else argc - (idx + 1), "int")
|
||||
}
|
||||
|
||||
fun Iterator<IndexedValue<Iota>>.nextPositiveIntUnder(max: Int, argc: Int = 0): Int {
|
||||
val (idx, x) = this.next()
|
||||
if (x is DoubleIota) {
|
||||
val double = x.double
|
||||
val rounded = double.roundToInt()
|
||||
if (abs(double - rounded) <= DoubleIota.TOLERANCE && rounded in 0 until max) {
|
||||
return rounded
|
||||
}
|
||||
}
|
||||
throw MishapInvalidIota.of(x, if (argc == 0) idx else argc - (idx + 1), "int.positive.less.equal", max)
|
||||
}
|
||||
|
||||
fun Iterator<IndexedValue<Iota>>.nextPositiveIntUnderInclusive(max: Int, argc: Int = 0): Int {
|
||||
val (idx, x) = this.next()
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
package at.petrak.hexcasting.common.casting.arithmetic.operator.list
|
||||
|
||||
import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator
|
||||
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate
|
||||
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaPredicate
|
||||
import at.petrak.hexcasting.api.casting.asActionResult
|
||||
import at.petrak.hexcasting.api.casting.iota.Iota
|
||||
import at.petrak.hexcasting.common.casting.arithmetic.operator.nextList
|
||||
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.*
|
||||
|
||||
object OperatorIndexOf : Operator(2, IotaMultiPredicate.pair(IotaPredicate.ofType(LIST), IotaPredicate.TRUE)) {
|
||||
override fun apply(iotas: Iterable<Iota>): Iterable<Iota> {
|
||||
val it = iotas.iterator().withIndex()
|
||||
val list = it.nextList(arity).toList()
|
||||
return list.indexOf(it.next().value).asActionResult
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package at.petrak.hexcasting.common.casting.arithmetic.operator.list
|
||||
|
||||
import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator
|
||||
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate
|
||||
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaPredicate
|
||||
import at.petrak.hexcasting.api.casting.asActionResult
|
||||
import at.petrak.hexcasting.api.casting.iota.Iota
|
||||
import at.petrak.hexcasting.common.casting.arithmetic.operator.nextInt
|
||||
import at.petrak.hexcasting.common.casting.arithmetic.operator.nextList
|
||||
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.*
|
||||
|
||||
object OperatorRemove : Operator(2, IotaMultiPredicate.pair(IotaPredicate.ofType(LIST), IotaPredicate.ofType(DOUBLE))) {
|
||||
override fun apply(iotas: Iterable<Iota>): Iterable<Iota> {
|
||||
val it = iotas.iterator().withIndex()
|
||||
val list = it.nextList(arity).toMutableList()
|
||||
val index = it.nextInt(arity)
|
||||
if (index < 0 || index >= list.size)
|
||||
return list.asActionResult
|
||||
list.removeAt(index)
|
||||
return list.asActionResult
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package at.petrak.hexcasting.common.casting.arithmetic.operator.list
|
||||
|
||||
import at.petrak.hexcasting.api.casting.SpellList
|
||||
import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator
|
||||
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate
|
||||
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaPredicate
|
||||
import at.petrak.hexcasting.api.casting.asActionResult
|
||||
import at.petrak.hexcasting.api.casting.iota.Iota
|
||||
import at.petrak.hexcasting.common.casting.arithmetic.operator.nextList
|
||||
import at.petrak.hexcasting.common.casting.arithmetic.operator.nextPositiveIntUnder
|
||||
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.*
|
||||
|
||||
object OperatorReplace : Operator(3, IotaMultiPredicate.triple(IotaPredicate.ofType(LIST), IotaPredicate.ofType(DOUBLE), IotaPredicate.TRUE)) {
|
||||
override fun apply(iotas: Iterable<Iota>): Iterable<Iota> {
|
||||
val it = iotas.iterator().withIndex()
|
||||
val list = it.nextList(arity)
|
||||
val index = it.nextPositiveIntUnder(list.size(), arity)
|
||||
val iota = it.next().value
|
||||
return list.modifyAt(index) { SpellList.LPair(iota, it.cdr) }.asActionResult
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package at.petrak.hexcasting.common.casting.arithmetic.operator.list
|
||||
|
||||
import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator
|
||||
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate
|
||||
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaPredicate
|
||||
import at.petrak.hexcasting.api.casting.iota.Iota
|
||||
import at.petrak.hexcasting.api.casting.iota.ListIota
|
||||
import at.petrak.hexcasting.api.casting.iota.NullIota
|
||||
import at.petrak.hexcasting.common.casting.arithmetic.operator.nextList
|
||||
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.LIST
|
||||
|
||||
object OperatorUnCons : Operator(1, IotaMultiPredicate.all(IotaPredicate.ofType(LIST))) {
|
||||
override fun apply(iotas: Iterable<Iota>): Iterable<Iota> {
|
||||
val it = iotas.iterator().withIndex()
|
||||
val list = it.nextList(arity)
|
||||
if (list.nonEmpty) {
|
||||
return listOf(ListIota(list.cdr), list.car)
|
||||
}
|
||||
return listOf(ListIota(list), NullIota())
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ import at.petrak.hexcasting.api.casting.iota.Iota;
|
|||
import at.petrak.hexcasting.api.casting.iota.Vec3Iota;
|
||||
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -19,7 +20,7 @@ public class OperatorPack extends Operator {
|
|||
public static OperatorPack INSTANCE = new OperatorPack();
|
||||
|
||||
@Override
|
||||
public Iterable<Iota> apply(Iterable<Iota> iotas) {
|
||||
public @NotNull Iterable<Iota> apply(@NotNull Iterable<Iota> iotas) {
|
||||
var it = iotas.iterator();
|
||||
return List.of(new Vec3Iota(new Vec3(
|
||||
downcast(it.next(), HexIotaTypes.DOUBLE).getDouble(),
|
||||
|
|
|
@ -7,6 +7,7 @@ import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator;
|
|||
import at.petrak.hexcasting.api.casting.iota.DoubleIota;
|
||||
import at.petrak.hexcasting.api.casting.iota.Iota;
|
||||
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -20,7 +21,7 @@ public class OperatorUnpack extends Operator {
|
|||
public static OperatorUnpack INSTANCE = new OperatorUnpack();
|
||||
|
||||
@Override
|
||||
public Iterable<Iota> apply(Iterable<Iota> iotas) {
|
||||
public @NotNull Iterable<Iota> apply(@NotNull Iterable<Iota> iotas) {
|
||||
var it = iotas.iterator();
|
||||
var vec = downcast(it.next(), VEC3).getVec3();
|
||||
return List.of(new DoubleIota(vec.x), new DoubleIota(vec.y), new DoubleIota(vec.z));
|
||||
|
|
|
@ -11,6 +11,7 @@ import at.petrak.hexcasting.api.casting.iota.Iota;
|
|||
import at.petrak.hexcasting.api.casting.iota.Vec3Iota;
|
||||
import at.petrak.hexcasting.api.casting.math.HexPattern;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
@ -29,7 +30,7 @@ public class OperatorVec3Delegating extends Operator {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Iota> apply(Iterable<Iota> iotas) {
|
||||
public @NotNull Iterable<Iota> apply(@NotNull Iterable<Iota> iotas) {
|
||||
var it = iotas.iterator();
|
||||
var left = it.next();
|
||||
var right = it.next();
|
||||
|
|
Loading…
Reference in a new issue