give Arithmetic operators access to the casting env (to be used in MoreIotas for the ExtractItemType operator, needed to get the item type of the block at a position)

This commit is contained in:
Talia-12 2023-07-09 21:15:39 +10:00
parent 0a90b0eda2
commit aaae2e5020
18 changed files with 42 additions and 24 deletions

View file

@ -2,6 +2,7 @@ package at.petrak.hexcasting.api.casting.arithmetic.engine;
import at.petrak.hexcasting.api.casting.arithmetic.Arithmetic;
import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator;
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment;
import at.petrak.hexcasting.api.casting.iota.Iota;
import at.petrak.hexcasting.api.casting.math.HexPattern;
import at.petrak.hexcasting.api.casting.mishaps.Mishap;
@ -65,10 +66,11 @@ public class ArithmeticEngine {
* @param pattern The pattern that was drawn, used to determine which operators are candidates.
* @param iotas The current stack.
* @param startingLength The length of the stack before the operator executes (used for errors).
* @param env The casting environment.
* @return The iotas to be added to the stack.
* @throws Mishap mishaps if invalid input to the operators is given by the caster.
*/
public Iterable<Iota> run(HexPattern pattern, Stack<Iota> iotas, int startingLength) throws Mishap {
public Iterable<Iota> run(HexPattern pattern, Stack<Iota> iotas, int startingLength, CastingEnvironment env) throws Mishap {
var candidates = operators.get(pattern);
if (candidates == null)
throw new InvalidOperatorException("the pattern " + pattern + " is not an operator."); //
@ -84,7 +86,7 @@ public class ArithmeticEngine {
}
Collections.reverse(args);
var op = resolveCandidates(args, hash, candidates);
return op.apply(args);
return op.apply(args, env);
}
private Operator resolveCandidates(List<Iota> args, HashCons hash, OpCandidates candidates) {

View file

@ -1,6 +1,7 @@
package at.petrak.hexcasting.api.casting.arithmetic.operator;
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate;
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment;
import at.petrak.hexcasting.api.casting.iota.Iota;
import at.petrak.hexcasting.api.casting.iota.IotaType;
import at.petrak.hexcasting.api.casting.mishaps.Mishap;
@ -36,10 +37,11 @@ public abstract class Operator {
/**
* The method called when this Operator is actually acting on the stack, for real.
* @param iotas An iterable of iotas with {@link Operator#arity} elements that satisfied {@link Operator#accepts}.
* @param env The casting environment, to make use of if this operator needs it.
* @return the iotas that this operator will return to the stack (with the first element of the returned iterable being placed deepest into the stack, and the last element on top of the stack).
* @throws Mishap if the Operator mishaps for any reason it will be passed up the chain.
*/
public abstract @NotNull Iterable<Iota> apply(@NotNull Iterable<Iota> iotas) throws Mishap;
public abstract @NotNull Iterable<Iota> apply(@NotNull Iterable<Iota> iotas, @NotNull CastingEnvironment env) throws Mishap;
/**
* A helper method to take an iota that you know is of iotaType and returning it as an iota of that type.

View file

@ -2,6 +2,7 @@ package at.petrak.hexcasting.api.casting.arithmetic.operator;
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate;
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment;
import at.petrak.hexcasting.api.casting.iota.Iota;
import org.jetbrains.annotations.NotNull;
@ -20,7 +21,7 @@ public class OperatorBinary extends Operator {
}
@Override
public @NotNull Iterable<Iota> apply(@NotNull Iterable<Iota> iotas) {
public @NotNull Iterable<Iota> apply(@NotNull Iterable<Iota> iotas, @NotNull CastingEnvironment env) {
var it = iotas.iterator();
return List.of(inner.apply(it.next(), it.next()));
}

View file

@ -2,6 +2,7 @@ package at.petrak.hexcasting.api.casting.arithmetic.operator;
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate;
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment;
import at.petrak.hexcasting.api.casting.iota.Iota;
import org.jetbrains.annotations.NotNull;
@ -20,7 +21,7 @@ public class OperatorUnary extends Operator {
}
@Override
public @NotNull Iterable<Iota> apply(@NotNull Iterable<Iota> iotas) {
public @NotNull Iterable<Iota> apply(@NotNull Iterable<Iota> iotas, @NotNull CastingEnvironment env) {
return List.of(inner.apply(iotas.iterator().next()));
}
}

View file

@ -24,7 +24,7 @@ data class OperationAction(val pattern: HexPattern) : Action {
stack.addAll(stackList)
val startingLength = stackList.size
return try {
val ret: Iterable<Iota> = HexArithmetics.getEngine().run(pattern, stack, startingLength)
val ret: Iterable<Iota> = HexArithmetics.getEngine().run(pattern, stack, startingLength, env)
ret.forEach(Consumer { e: Iota -> stack.add(e) })
val image2 = image.copy(stack = stack, opsConsumed = image.opsConsumed + 1) // TODO: maybe let operators figure out how many ops to consume?
OperationResult(image2, listOf(), continuation, HexEvalSounds.NORMAL_EXECUTE)

View file

@ -4,13 +4,14 @@ 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.eval.CastingEnvironment
import at.petrak.hexcasting.api.casting.iota.Iota
import at.petrak.hexcasting.api.casting.mishaps.MishapDivideByZero
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.DOUBLE
import kotlin.math.log
object OperatorLog : Operator(2, IotaMultiPredicate.all(IotaPredicate.ofType(DOUBLE))) {
override fun apply(iotas: Iterable<Iota>): Iterable<Iota> {
override fun apply(iotas: Iterable<Iota>, env : CastingEnvironment): Iterable<Iota> {
val it = iotas.iterator().withIndex()
val value = it.nextDouble(arity)
val base = it.nextDouble(arity)

View file

@ -4,12 +4,13 @@ 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.eval.CastingEnvironment
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 OperatorAppend : Operator(2, IotaMultiPredicate.pair(IotaPredicate.ofType(LIST), IotaPredicate.TRUE)) {
override fun apply(iotas: Iterable<Iota>): Iterable<Iota> {
override fun apply(iotas: Iterable<Iota>, env: CastingEnvironment): Iterable<Iota> {
val it = iotas.iterator().withIndex()
val list = it.nextList(arity).toMutableList()
list.add(it.next().value)

View file

@ -3,13 +3,14 @@ package at.petrak.hexcasting.common.casting.arithmetic.operator.list
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.eval.CastingEnvironment
import at.petrak.hexcasting.api.casting.iota.Iota
import at.petrak.hexcasting.api.casting.iota.NullIota
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.*
import kotlin.math.roundToInt
object OperatorIndex : Operator(2, IotaMultiPredicate.pair(IotaPredicate.ofType(LIST), IotaPredicate.ofType(DOUBLE))) {
override fun apply(iotas: Iterable<Iota>): Iterable<Iota> {
override fun apply(iotas: Iterable<Iota>, env: CastingEnvironment): Iterable<Iota> {
val it = iotas.iterator()
val list = downcast(it.next(), LIST).list.toMutableList()
val index = downcast(it.next(), DOUBLE).double

View file

@ -4,12 +4,13 @@ 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.eval.CastingEnvironment
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> {
override fun apply(iotas: Iterable<Iota>, env: CastingEnvironment): Iterable<Iota> {
val it = iotas.iterator().withIndex()
val list = it.nextList(arity).toList()
return list.indexOf(it.next().value).asActionResult

View file

@ -4,13 +4,14 @@ 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.eval.CastingEnvironment
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> {
override fun apply(iotas: Iterable<Iota>, env: CastingEnvironment): Iterable<Iota> {
val it = iotas.iterator().withIndex()
val list = it.nextList(arity).toMutableList()
val index = it.nextInt(arity)

View file

@ -5,13 +5,14 @@ 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.eval.CastingEnvironment
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> {
override fun apply(iotas: Iterable<Iota>, env: CastingEnvironment): Iterable<Iota> {
val it = iotas.iterator().withIndex()
val list = it.nextList(arity)
val index = it.nextPositiveIntUnder(list.size(), arity)

View file

@ -4,6 +4,7 @@ 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.asActionResult
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment
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.nextPositiveIntUnderInclusive
@ -12,7 +13,7 @@ import kotlin.math.max
import kotlin.math.min
object OperatorSlice : Operator(3, IotaMultiPredicate.triple(IotaPredicate.ofType(LIST), IotaPredicate.ofType(DOUBLE), IotaPredicate.ofType(DOUBLE))) {
override fun apply(iotas: Iterable<Iota>): Iterable<Iota> {
override fun apply(iotas: Iterable<Iota>, env: CastingEnvironment): Iterable<Iota> {
val it = iotas.iterator().withIndex()
val list = it.nextList(arity).toList()
val index0 = it.nextPositiveIntUnderInclusive(list.size, arity)

View file

@ -3,6 +3,7 @@ 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.eval.CastingEnvironment
import at.petrak.hexcasting.api.casting.iota.Iota
import at.petrak.hexcasting.api.casting.iota.ListIota
import at.petrak.hexcasting.api.casting.iota.NullIota
@ -10,12 +11,11 @@ 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> {
override fun apply(iotas: Iterable<Iota>, env: CastingEnvironment): Iterable<Iota> {
val it = iotas.iterator().withIndex()
val list = it.nextList(arity)
if (list.nonEmpty) {
if (list.nonEmpty)
return listOf(ListIota(list.cdr), list.car)
}
return listOf(ListIota(list), NullIota())
}
}

View file

@ -3,6 +3,7 @@ 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.eval.CastingEnvironment
import at.petrak.hexcasting.api.casting.iota.Iota
import at.petrak.hexcasting.api.casting.iota.ListIota
import at.petrak.hexcasting.api.casting.iota.NullIota
@ -10,7 +11,7 @@ import at.petrak.hexcasting.common.casting.arithmetic.operator.nextList
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.*
object OperatorUnappend : Operator(1, IotaMultiPredicate.all(IotaPredicate.ofType(LIST))) {
override fun apply(iotas: Iterable<Iota>): Iterable<Iota> {
override fun apply(iotas: Iterable<Iota>, env: CastingEnvironment): Iterable<Iota> {
val it = iotas.iterator().withIndex()
val list = it.nextList(arity).toMutableList()
val last = list.removeLastOrNull() ?: NullIota()

View file

@ -4,13 +4,14 @@ 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.eval.CastingEnvironment
import at.petrak.hexcasting.api.casting.iota.Iota
import at.petrak.hexcasting.common.casting.arithmetic.operator.nextList
import at.petrak.hexcasting.common.casting.actions.math.bit.OpToSet
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.LIST
object OperatorUnique : Operator(1, IotaMultiPredicate.all(IotaPredicate.ofType(LIST))) {
override fun apply(iotas: Iterable<Iota>): Iterable<Iota> {
override fun apply(iotas: Iterable<Iota>, env: CastingEnvironment): Iterable<Iota> {
val it = iotas.iterator().withIndex()
val list = it.nextList(OpToSet.argc)
val out = mutableListOf<Iota>()

View file

@ -4,6 +4,7 @@ package at.petrak.hexcasting.common.casting.arithmetic.operator.vec;
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.eval.CastingEnvironment;
import at.petrak.hexcasting.api.casting.iota.Iota;
import at.petrak.hexcasting.api.casting.iota.Vec3Iota;
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes;
@ -20,7 +21,7 @@ public class OperatorPack extends Operator {
public static OperatorPack INSTANCE = new OperatorPack();
@Override
public @NotNull Iterable<Iota> apply(@NotNull Iterable<Iota> iotas) {
public @NotNull Iterable<Iota> apply(@NotNull Iterable<Iota> iotas, @NotNull CastingEnvironment env) {
var it = iotas.iterator();
return List.of(new Vec3Iota(new Vec3(
downcast(it.next(), HexIotaTypes.DOUBLE).getDouble(),

View file

@ -4,6 +4,7 @@ package at.petrak.hexcasting.common.casting.arithmetic.operator.vec;
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.eval.CastingEnvironment;
import at.petrak.hexcasting.api.casting.iota.DoubleIota;
import at.petrak.hexcasting.api.casting.iota.Iota;
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes;
@ -21,7 +22,7 @@ public class OperatorUnpack extends Operator {
public static OperatorUnpack INSTANCE = new OperatorUnpack();
@Override
public @NotNull Iterable<Iota> apply(@NotNull Iterable<Iota> iotas) {
public @NotNull Iterable<Iota> apply(@NotNull Iterable<Iota> iotas, @NotNull CastingEnvironment env) {
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

@ -5,6 +5,7 @@ import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaPredicate;
import at.petrak.hexcasting.api.casting.arithmetic.IterPair;
import at.petrak.hexcasting.api.casting.arithmetic.TripleIterable;
import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator;
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment;
import at.petrak.hexcasting.api.casting.mishaps.Mishap;
import at.petrak.hexcasting.api.casting.mishaps.MishapDivideByZero;
import at.petrak.hexcasting.common.casting.arithmetic.DoubleArithmetic;
@ -32,7 +33,7 @@ public class OperatorVec3Delegating extends Operator {
}
@Override
public @NotNull Iterable<Iota> apply(@NotNull Iterable<Iota> iotas) throws Mishap {
public @NotNull Iterable<Iota> apply(@NotNull Iterable<Iota> iotas, @NotNull CastingEnvironment env) throws Mishap {
var it = iotas.iterator();
var left = it.next();
var right = it.next();
@ -43,9 +44,9 @@ public class OperatorVec3Delegating extends Operator {
var lh = left instanceof Vec3Iota l ? l.getVec3() : triplicate(downcast(left, DOUBLE).getDouble());
var rh = right instanceof Vec3Iota r ? r.getVec3() : triplicate(downcast(right, DOUBLE).getDouble());
return new TripleIterable<>(
fb.apply(new IterPair<>(new DoubleIota(lh.x()), new DoubleIota(rh.x()))),
fb.apply(new IterPair<>(new DoubleIota(lh.y()), new DoubleIota(rh.y()))),
fb.apply(new IterPair<>(new DoubleIota(lh.z()), new DoubleIota(rh.z()))),
fb.apply(new IterPair<>(new DoubleIota(lh.x()), new DoubleIota(rh.x())), env),
fb.apply(new IterPair<>(new DoubleIota(lh.y()), new DoubleIota(rh.y())), env),
fb.apply(new IterPair<>(new DoubleIota(lh.z()), new DoubleIota(rh.z())), env),
(x, y, z) -> new Vec3Iota(new Vec3(downcast(x, DOUBLE).getDouble(), downcast(y, DOUBLE).getDouble(), downcast(z, DOUBLE).getDouble()))
);
} catch (MishapDivideByZero e) {