list arithmetic fully implemented

This commit is contained in:
Talia-12 2023-05-31 20:38:19 +10:00
parent a7f89b0776
commit e62816eff5
12 changed files with 165 additions and 73 deletions

View file

@ -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) {

View file

@ -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()));
}

View file

@ -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()));
}
}

View file

@ -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;
}
}

View file

@ -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()

View file

@ -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
}
}

View file

@ -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
}
}

View file

@ -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
}
}

View file

@ -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())
}
}

View file

@ -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(),

View file

@ -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));

View file

@ -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();