From e9a3972974245bdd7f96a6fe2d74917df3f34601 Mon Sep 17 00:00:00 2001 From: Aly Date: Sun, 10 May 2026 13:39:14 -0600 Subject: [PATCH 1/3] move all ops to use TreeList --- .../hexcasting/common/casting/actions/lists/OpSplat.kt | 2 +- .../common/casting/actions/spells/OpMakePackagedSpell.kt | 2 +- .../hexcasting/common/casting/arithmetic/ListArithmetic.kt | 4 ++-- .../common/casting/arithmetic/ListSetArithmetic.kt | 2 +- .../casting/arithmetic/operator/list/OperatorAppend.kt | 5 ++--- .../casting/arithmetic/operator/list/OperatorIndex.kt | 2 +- .../casting/arithmetic/operator/list/OperatorIndexOf.kt | 2 +- .../casting/arithmetic/operator/list/OperatorRemove.kt | 6 +++--- .../casting/arithmetic/operator/list/OperatorSlice.kt | 4 ++-- .../casting/arithmetic/operator/list/OperatorUnappend.kt | 6 +++--- 10 files changed, 17 insertions(+), 18 deletions(-) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpSplat.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpSplat.kt index f35f0d8ac3..cf46c476c6 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpSplat.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpSplat.kt @@ -10,5 +10,5 @@ object OpSplat : ConstMediaAction { get() = 1 override fun execute(args: List, env: CastingEnvironment): List = - args.getList(0, argc).toList() + args.getList(0, argc) } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpMakePackagedSpell.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpMakePackagedSpell.kt index b1af0cbf47..b574726a88 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpMakePackagedSpell.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpMakePackagedSpell.kt @@ -31,7 +31,7 @@ class OpMakePackagedSpell(val isValid: Predicate, val expectedTypeDes env: CastingEnvironment ): SpellAction.Result { val entity = args.getItemEntity(env.world, 0, argc) - val patterns = args.getList(1, argc).toList() + val patterns = args.getList(1, argc) val (handStack) = env.getHeldItemToOperateOn { val hexHolder = IXplatAbstractions.INSTANCE.findHexHolder(it) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/ListArithmetic.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/ListArithmetic.kt index 38ae7dfa2a..b4f852fb15 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/ListArithmetic.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/ListArithmetic.kt @@ -46,7 +46,7 @@ object ListArithmetic : Arithmetic { UNAPPEND -> OperatorUnappend ADD -> make2 { list0, list1 -> list0 + list1 } ABS -> OperatorUnary(all(IotaPredicate.ofType(LIST.get()))) { iota: Iota -> DoubleIota(downcast(iota, LIST.get()).list.size.toDouble()) } - REV -> OperatorUnary(all(IotaPredicate.ofType(LIST.get()))) { iota: Iota -> ListIota(downcast(iota, LIST.get()).list.toList().asReversed()) } + REV -> OperatorUnary(all(IotaPredicate.ofType(LIST.get()))) { iota: Iota -> ListIota(downcast(iota, LIST.get()).list.reversed()) } INDEX_OF -> OperatorIndexOf REMOVE -> OperatorRemove REPLACE -> OperatorReplace @@ -58,6 +58,6 @@ object ListArithmetic : Arithmetic { private fun make2(op: BinaryOperator>): OperatorBinary = OperatorBinary(all(IotaPredicate.ofType(LIST.get()))) { i: Iota, j: Iota -> ListIota( - op.apply(downcast(i, LIST.get()).list.toList(), downcast(j, LIST.get()).list.toList()) + op.apply(downcast(i, LIST.get()).list, downcast(j, LIST.get()).list) ) } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/ListSetArithmetic.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/ListSetArithmetic.kt index f20b1659a4..4c1481e1e9 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/ListSetArithmetic.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/ListSetArithmetic.kt @@ -38,6 +38,6 @@ object ListSetArithmetic : Arithmetic { private fun make2(op: BinaryOperator>): OperatorBinary = OperatorBinary(all(IotaPredicate.ofType(LIST.get()))) { i: Iota, j: Iota -> ListIota( - op.apply(downcast(i, LIST.get()).list.toList(), downcast(j, LIST.get()).list.toList()) + op.apply(downcast(i, LIST.get()).list, downcast(j, LIST.get()).list) ) } } \ No newline at end of file diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorAppend.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorAppend.kt index dae4257ffc..85288f8978 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorAppend.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorAppend.kt @@ -12,8 +12,7 @@ import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.LIST object OperatorAppend : OperatorBasic(2, IotaMultiPredicate.pair(IotaPredicate.ofType(LIST.get()), IotaPredicate.TRUE)) { override fun apply(iotas: Iterable, env: CastingEnvironment): Iterable { val it = iotas.iterator().withIndex() - val list = it.nextList(arity).toMutableList() - list.add(it.next().value) - return list.asActionResult + val list = it.nextList(arity) + return list.appended(it.next().value).asActionResult } } \ No newline at end of file diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorIndex.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorIndex.kt index a3c378b9ce..88bb27de70 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorIndex.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorIndex.kt @@ -13,7 +13,7 @@ import kotlin.math.roundToInt object OperatorIndex : OperatorBasic(2, IotaMultiPredicate.pair(IotaPredicate.ofType(LIST.get()), IotaPredicate.ofType(DOUBLE.get()))) { override fun apply(iotas: Iterable, env: CastingEnvironment): Iterable { val it = iotas.iterator() - val list = downcast(it.next(), LIST.get()).list.toMutableList() + val list = downcast(it.next(), LIST.get()).list val index = downcast(it.next(), DOUBLE.get()).double val x = list.getOrElse(index.roundToInt()) { NullIota() } return listOf(x) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorIndexOf.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorIndexOf.kt index 3f797ad49d..18510e051a 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorIndexOf.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorIndexOf.kt @@ -12,7 +12,7 @@ import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.LIST object OperatorIndexOf : OperatorBasic(2, IotaMultiPredicate.pair(IotaPredicate.ofType(LIST.get()), IotaPredicate.TRUE)) { override fun apply(iotas: Iterable, env: CastingEnvironment): Iterable { val it = iotas.iterator().withIndex() - val list = it.nextList(arity).toList() + val list = it.nextList(arity) val toFind = it.next().value return list.indexOfFirst { Iota.tolerates(toFind, it) }.asActionResult } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorRemove.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorRemove.kt index df7902db6f..8e24a32f2f 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorRemove.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorRemove.kt @@ -14,11 +14,11 @@ import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.LIST object OperatorRemove : OperatorBasic(2, IotaMultiPredicate.pair(IotaPredicate.ofType(LIST.get()), IotaPredicate.ofType(DOUBLE.get()))) { override fun apply(iotas: Iterable, env: CastingEnvironment): Iterable { val it = iotas.iterator().withIndex() - val list = it.nextList(arity).toMutableList() + val list = it.nextList(arity) val index = it.nextInt(arity) if (index < 0 || index >= list.size) return list.asActionResult - list.removeAt(index) - return list.asActionResult + + return list.take(index).appendedAll(list.drop(index + 1)).asActionResult } } \ No newline at end of file diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorSlice.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorSlice.kt index 6e687906fb..caa3a1e9d8 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorSlice.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorSlice.kt @@ -16,12 +16,12 @@ import kotlin.math.min object OperatorSlice : OperatorBasic(3, IotaMultiPredicate.triple(IotaPredicate.ofType(LIST.get()), IotaPredicate.ofType(DOUBLE.get()), IotaPredicate.ofType(DOUBLE.get()))) { override fun apply(iotas: Iterable, env: CastingEnvironment): Iterable { val it = iotas.iterator().withIndex() - val list = it.nextList(arity).toList() + val list = it.nextList(arity) val index0 = it.nextPositiveIntUnderInclusive(list.size, arity) val index1 = it.nextPositiveIntUnderInclusive(list.size, arity) if (index0 == index1) return emptyList().asActionResult - return list.subList(min(index0, index1), max(index0, index1)).asActionResult + return list.slice(min(index0, index1), max(index0, index1)).asActionResult } } \ No newline at end of file diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorUnappend.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorUnappend.kt index ba4b8f407e..5c00fa837a 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorUnappend.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorUnappend.kt @@ -13,8 +13,8 @@ import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.LIST object OperatorUnappend : OperatorBasic(1, IotaMultiPredicate.all(IotaPredicate.ofType(LIST.get()))) { override fun apply(iotas: Iterable, env: CastingEnvironment): Iterable { val it = iotas.iterator().withIndex() - val list = it.nextList(arity).toMutableList() - val last = list.removeLastOrNull() ?: NullIota() - return listOf(ListIota(list), last) + val list = it.nextList(arity) + val last = if(list.isEmpty()) NullIota() else list.last() + return listOf(ListIota(list.init()), last) } } \ No newline at end of file From 4061f1edc44c3265e5f8ad596a25e4901dfd2f4d Mon Sep 17 00:00:00 2001 From: Aly Date: Thu, 11 Jun 2026 20:01:21 -0600 Subject: [PATCH 2/3] add changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1be5e139fb..80658710f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). - SpellList has been removed ([#1032](https://github.com/FallingColors/HexMod/pull/1032)) @s5bug - Casting Image and Casting Frames now store iotas in a TreeList ([#1033](https://github.com/FallingColors/HexMod/pull/1033)) @s5bug - Changed resource registration to use the IXplatRegister system ([#1212](https://github.com/FallingColors/HexMod/pull/1212)) @Olfi01 +- Operations and actions now accept the old stack and produce the new stack through a TreeList ([#1038](https://github.com/FallingColors/HexMod/pull/1038)) @s5bug ## `0.11.3` - 2025-11-22 From d6a30ff9c17bf00481f57b3ce7dc7cdbefff9e98 Mon Sep 17 00:00:00 2001 From: Aly Date: Sat, 8 Aug 2026 12:55:55 -0600 Subject: [PATCH 3/3] fix crash when empty list applied to unappend --- .../casting/arithmetic/operator/list/OperatorUnappend.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorUnappend.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorUnappend.kt index 5c00fa837a..b1215d98c6 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorUnappend.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorUnappend.kt @@ -14,7 +14,8 @@ object OperatorUnappend : OperatorBasic(1, IotaMultiPredicate.all(IotaPredicate. override fun apply(iotas: Iterable, env: CastingEnvironment): Iterable { val it = iotas.iterator().withIndex() val list = it.nextList(arity) - val last = if(list.isEmpty()) NullIota() else list.last() - return listOf(ListIota(list.init()), last) + if (!list.isEmpty()) + return listOf(ListIota(list.init()), list.last()) + return listOf(ListIota(list), NullIota()) } } \ No newline at end of file