2. Uxn Eval
Tuesday 28th July 2026
We have two stacks and some basic logic, 'all' we need now is an evaluate function that processes instructions held in the ram object and manipulates the two stacks.
eval(vector)
A main evaluate method (would be better called execute as it doesn't return? but we'll stick with the Uxn C reference naming). The vector argument specifies where in ram to start executing instructions.
fun eval(vector: Int) {
//A vector of 0 represents a no-op, no handler ever exists at 0
if (vector == 0) return
programCounter = vector
while (true) {
//fetch next instruction
val instruction: Int = ram[programCounter]
//advance to next, wrap at 16bits so we never try and access an index outside of ram
programCounter = (programCounter + 1) and 0xffff
//We've added some Int extension methods for convenience:
val opcode = instruction.opcode()
val isKeep = instruction.isKeep()
val isReturn = instruction.isReturn()
val isShort = instruction.isShort()
//Determine stack:
sourceStack = if (isReturn) returnStack else workingStack
destinationStack = if (isReturn) workingStack else returnStack
sourceStack.beginInstruction(isKeep)
//process opcode:
...
}
Int/opcode extensions
const val FLAG_SHORT = 0x20 // 2
const val FLAG_RETURN = 0x40 // r
const val FLAG_KEEP = 0x80 // k
fun Int.isShort(): Boolean = this and FLAG_SHORT != 0
fun Int.isReturn(): Boolean = this and FLAG_RETURN != 0
fun Int.isKeep(): Boolean = this and FLAG_KEEP != 0
fun Int.opcode(): Int = this and 0x1f
Process an opcode
fun eval(vector: Int) {
...
sourceStack.beginInstruction(isKeep)
when (opcode) {
ADD -> {
val b = sourceStack.pop(isShort)
val a = sourceStack.pop(isShort)
sourceStack.push(a + b, isShort)
}
}
}