Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import at.petrak.hexcasting.api.casting.iota.*
import at.petrak.hexcasting.api.casting.math.HexPattern
import at.petrak.hexcasting.api.casting.mishaps.MishapInvalidIota
import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughArgs
import at.petrak.hexcasting.api.utils.TreeList
import at.petrak.hexcasting.api.utils.asTranslatedComponent
import com.mojang.datafixers.util.Either
import net.minecraft.core.BlockPos
Expand Down Expand Up @@ -41,7 +42,7 @@ fun List<Iota>.getEntity(idx: Int, argc: Int = 0): Entity {
}
}

fun List<Iota>.getList(idx: Int, argc: Int = 0): SpellList {
fun List<Iota>.getList(idx: Int, argc: Int = 0): TreeList<Iota> {
val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) }
if (x is ListIota) {
return x.list
Expand Down Expand Up @@ -269,7 +270,7 @@ fun List<Iota>.getNumOrVec(idx: Int, argc: Int = 0): Either<Double, Vec3> {
}
}

fun List<Iota>.getLongOrList(idx: Int, argc: Int = 0): Either<Long, SpellList> {
fun List<Iota>.getLongOrList(idx: Int, argc: Int = 0): Either<Long, TreeList<Iota>> {
val datum = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) }
if (datum is DoubleIota) {
val double = datum.double
Expand All @@ -287,7 +288,7 @@ fun List<Iota>.getLongOrList(idx: Int, argc: Int = 0): Either<Long, SpellList> {
)
}

fun evaluatable(datum: Iota, reverseIdx: Int): Either<Iota, SpellList> =
fun evaluatable(datum: Iota, reverseIdx: Int): Either<Iota, TreeList<Iota>> =
when (datum) {
is ListIota -> Either.right(datum.list)
else -> if (datum.executable()) Either.left(datum) else throw MishapInvalidIota(
Expand All @@ -312,7 +313,7 @@ inline val Boolean.asActionResult get() = listOf(BooleanIota(this))
inline val Double.asActionResult get() = listOf(DoubleIota(this))
inline val Number.asActionResult get() = listOf(DoubleIota(this.toDouble()))

inline val SpellList.asActionResult get() = listOf(ListIota(this))
inline val TreeList<Iota>.asActionResult get() = listOf(ListIota(this))
inline val List<Iota>.asActionResult get() = listOf(ListIota(this))

inline val BlockPos.asActionResult get() = listOf(Vec3Iota(Vec3.atCenterOf(this)))
Expand Down
93 changes: 0 additions & 93 deletions Common/src/main/java/at/petrak/hexcasting/api/casting/SpellList.kt

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ abstract class OperatorBasic(arity: Int, accepts: IotaMultiPredicate) : Operator

@Throws(Mishap::class)
override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult {
val stack = image.stack.toMutableList()
val args = stack.takeLast(arity)
repeat(arity) { stack.removeLast() }
val stack = image.stack
val args = stack.takeRight(arity)
val stackWithoutArgs = stack.dropRight(arity)

val ret = apply(args, env)
ret.forEach(Consumer { e: Iota -> stack.add(e) })
val stackWithResult = stackWithoutArgs.appendedAll(ret)

val image2 = image.copy(stack = stack, opsConsumed = image.opsConsumed + 1)
val image2 = image.copy(stack = stackWithResult, opsConsumed = image.opsConsumed + 1)
return OperationResult(image2, listOf(), continuation, HexEvalSounds.NORMAL_EXECUTE)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,21 @@ interface ConstMediaAction : Action {
}

override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult {
val stack = image.stack.toMutableList()
val stack = image.stack

if (this.argc > stack.size)
throw MishapNotEnoughArgs(this.argc, stack.size)
val args = stack.takeLast(this.argc)
repeat(this.argc) { stack.removeLast() }
val args = stack.takeRight(this.argc)
val stackWithoutArgs = stack.dropRight(this.argc)
val result = this.executeWithOpCount(args, env)
stack.addAll(result.resultStack)
val stackWithResult = stackWithoutArgs.appendedAll(result.resultStack)

if (env.extractMedia(this.mediaCost, true) > 0)
throw MishapNotEnoughMedia(this.mediaCost)

val sideEffects = mutableListOf<OperatorSideEffect>(OperatorSideEffect.ConsumeMedia(this.mediaCost))

val image2 = image.copy(stack = stack, opsConsumed = image.opsConsumed + result.opCount)
val image2 = image.copy(stack = stackWithResult, opsConsumed = image.opsConsumed + result.opCount)
return OperationResult(image2, sideEffects, continuation, HexEvalSounds.NORMAL_EXECUTE)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ interface SpellAction : Action {
}

override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult {
val stack = image.stack.toMutableList()
val stack = image.stack

if (this.argc > stack.size)
throw MishapNotEnoughArgs(this.argc, stack.size)
val args = stack.takeLast(this.argc)
for (_i in 0 until this.argc) stack.removeLast()
val args = stack.takeRight(this.argc)
val stackWithoutArgs = stack.dropRight(this.argc)

// execute!
val userDataMut = image.userData.copy()
Expand All @@ -65,7 +65,7 @@ interface SpellAction : Action {
for (spray in result.particles)
sideEffects.add(OperatorSideEffect.Particles(spray))

val image2 = image.copy(stack = stack, opsConsumed = image.opsConsumed + result.opCount, userData = userDataMut)
val image2 = image.copy(stack = stackWithoutArgs, opsConsumed = image.opsConsumed + result.opCount, userData = userDataMut)

val sound = if (this.hasCastingSound(env)) HexEvalSounds.SPELL else HexEvalSounds.MUTE
return OperationResult(image2, sideEffects, continuation, sound)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ sealed class OperatorSideEffect {
)
)

harness.image = harness.image.copy(stack = mishap.executeReturnStack(harness.env, errorCtx, harness.image.stack.toMutableList()))
harness.image = harness.image.copy(stack = mishap.execute(harness.env, errorCtx, harness.image.stack))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,16 @@ import net.minecraft.world.entity.Entity
* The state of a casting VM, containing the stack and all
*/
data class CastingImage private constructor(
val stack: List<Iota>,
val stack: TreeList<Iota>,

val parenCount: Int,
val parenthesized: List<ParenthesizedIota>,
val parenthesized: TreeList<ParenthesizedIota>,
val escapeNext: Boolean,
val opsConsumed: Long,

val userData: CompoundTag
) {
constructor() : this(listOf(), 0, listOf(), false, 0, CompoundTag())
constructor() : this(TreeList.empty(), 0, TreeList.empty(), false, 0, CompoundTag())

data class ParenthesizedIota(val iota: Iota, val escaped: Boolean) {
companion object {
Expand Down Expand Up @@ -70,7 +70,7 @@ data class CastingImage private constructor(
/**
* Returns a copy of this with escape/paren-related fields cleared.
*/
fun withResetEscape() = this.copy(parenCount = 0, parenthesized = listOf(), escapeNext = false)
fun withResetEscape() = this.copy(parenCount = 0, parenthesized = TreeList.empty(), escapeNext = false)

fun serializeToNbt() = NBTBuilder {
TAG_STACK %= stack.serializeToNBT()
Expand Down Expand Up @@ -120,7 +120,7 @@ data class CastingImage private constructor(
val escapeNext = tag.getBoolean(TAG_ESCAPE_NEXT)
val opsUsed = tag.getLong(TAG_OPS_CONSUMED)

CastingImage(stack, parenCount, parenthesized, escapeNext, opsUsed, userData)
CastingImage(TreeList.from(stack), parenCount, TreeList.from(parenthesized), escapeNext, opsUsed, userData)
} catch (exn: Exception) {
HexAPI.LOGGER.warn("error while loading a CastingImage", exn)
CastingImage()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package at.petrak.hexcasting.api.casting.eval.vm

import at.petrak.hexcasting.api.HexAPI
import at.petrak.hexcasting.api.casting.PatternShapeMatch.*
import at.petrak.hexcasting.api.casting.SpellList
import at.petrak.hexcasting.api.casting.eval.*
import at.petrak.hexcasting.api.casting.eval.sideeffects.OperatorSideEffect
import at.petrak.hexcasting.api.casting.eval.vm.CastingImage.ParenthesizedIota
Expand Down Expand Up @@ -40,7 +39,7 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) {
*/
fun queueExecuteAndWrapIotas(iotas: List<Iota>, world: ServerLevel): ExecutionClientView {
// Initialize the continuation stack to a single top-level eval for all iotas.
var continuation = SpellContinuation.Done.pushFrame(FrameEvaluate(SpellList.LList(0, iotas), false))
var continuation = SpellContinuation.Done.pushFrame(FrameEvaluate(TreeList.from(iotas), false))
// Begin aggregating info
val info = TempControllerInfo(earlyExit = false)
var lastResolutionType = ResolvedPatternType.UNRESOLVED
Expand Down Expand Up @@ -185,8 +184,7 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) {

val out = if (displayDepth > 0) {
if (this.image.escapeNext) {
val newParens = this.image.parenthesized.toMutableList()
newParens.add(ParenthesizedIota(iota, true))
val newParens = this.image.parenthesized.appended(ParenthesizedIota(iota, true))
this.image.copy(
escapeNext = false,
parenthesized = newParens
Expand All @@ -201,8 +199,8 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) {
}

SpecialPatterns.EVANITION.angles -> {
val newParens = this.image.parenthesized.toMutableList()
val last = newParens.removeLastOrNull()
val newParens = this.image.parenthesized.init()
val last = this.image.parenthesized.lastOrNull()
val newParenCount = this.image.parenCount + if (last == null || last.escaped || last.iota !is PatternIota) 0 else when (last.iota.pattern) {
SpecialPatterns.INTROSPECTION -> -1
SpecialPatterns.RETROSPECTION -> 1
Expand All @@ -213,8 +211,7 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) {

SpecialPatterns.INTROSPECTION.angles -> {
// we have escaped the parens onto the stack; we just also record our count.
val newParens = this.image.parenthesized.toMutableList()
newParens.add(ParenthesizedIota(iota, false))
val newParens = this.image.parenthesized.appended(ParenthesizedIota(iota, false))
this.image.copy(
parenthesized = newParens,
parenCount = this.image.parenCount + 1
Expand All @@ -225,20 +222,18 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) {
val newParenCount = this.image.parenCount - 1
displayDepth--
if (newParenCount == 0) {
val newStack = this.image.stack.toMutableList()
newStack.add(ListIota(this.image.parenthesized.toList().map { it.iota }))
val newStack = this.image.stack.appended(ListIota(this.image.parenthesized.map { it.iota }))
this.image.copy(
stack = newStack,
parenCount = newParenCount,
parenthesized = listOf()
parenthesized = TreeList.empty()
) to ResolvedPatternType.EVALUATED
} else if (newParenCount < 0) {
throw MishapTooManyCloseParens()
} else {
// we have this situation: "(()"
// we need to add the close paren
val newParens = this.image.parenthesized.toMutableList()
newParens.add(ParenthesizedIota(iota, false))
val newParens = this.image.parenthesized.appended(ParenthesizedIota(iota, false))
this.image.copy(
parenCount = newParenCount,
parenthesized = newParens
Expand All @@ -247,17 +242,15 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) {
}

else -> {
val newParens = this.image.parenthesized.toMutableList()
newParens.add(ParenthesizedIota(iota, false))
val newParens = this.image.parenthesized.appended(ParenthesizedIota(iota, false))
this.image.copy(
parenthesized = newParens
) to ResolvedPatternType.ESCAPED
}
}
}
} else if (this.image.escapeNext) {
val newStack = this.image.stack.toMutableList()
newStack.add(iota)
val newStack = this.image.stack.appended(iota)
this.image.copy(
stack = newStack,
escapeNext = false,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package at.petrak.hexcasting.api.casting.eval.vm

import at.petrak.hexcasting.api.casting.SpellList
import at.petrak.hexcasting.api.casting.eval.CastResult
import at.petrak.hexcasting.api.casting.iota.Iota
import at.petrak.hexcasting.api.utils.TreeList
import at.petrak.hexcasting.common.lib.hex.HexContinuationTypes
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.Tag
Expand Down Expand Up @@ -35,7 +35,7 @@ interface ContinuationFrame {
* In other words, we should consume Evaluate frames until we hit a FinishEval or Thoth frame.
* @return whether the break should stop here, alongside the new stack state (e.g. for finalizing a Thoth)
*/
fun breakDownwards(stack: List<Iota>): Pair<Boolean, List<Iota>>
fun breakDownwards(stack: TreeList<Iota>): Pair<Boolean, TreeList<Iota>>

/**
* Serializes this frame. Used for things like delays, where we pause execution.
Expand All @@ -60,10 +60,10 @@ interface ContinuationFrame {
*/
@JvmStatic
fun fromNBT(tag: CompoundTag, world: ServerLevel): ContinuationFrame {
val type = getTypeFromTag(tag) ?: return FrameEvaluate(SpellList.LList(0, listOf()), false)
val type = getTypeFromTag(tag) ?: return FrameEvaluate(TreeList.empty(), false)

return (tag.get(HexContinuationTypes.KEY_DATA) as? CompoundTag)?.let { type.deserializeFromNBT(it, world) }
?: FrameEvaluate(SpellList.LList(0, listOf()), false)
?: FrameEvaluate(TreeList.empty(), false)
}

/**
Expand Down
Loading
Loading