39 lines
978 B
Scala
39 lines
978 B
Scala
package aoc.y2019.intcode
|
|
|
|
import cats.data.{Kleisli, State}
|
|
|
|
case class OperandMode(get: Kleisli[Operation, BigInt, BigInt], set: Kleisli[Operation, (BigInt, BigInt), Unit])
|
|
|
|
object OperandMode {
|
|
|
|
val position: OperandMode = OperandMode(
|
|
Kleisli(Machine.get),
|
|
Kleisli { case (address, value) => Machine.set(address, value) }
|
|
)
|
|
val immediate: OperandMode = OperandMode(
|
|
Kleisli(State.pure),
|
|
Kleisli(_ => throw new IllegalArgumentException("Cannot set in immediate mode!"))
|
|
)
|
|
val relative: OperandMode = OperandMode(
|
|
Kleisli { address =>
|
|
for {
|
|
offset <- Machine.getOffset
|
|
value <- Machine.get(address + offset)
|
|
} yield value
|
|
},
|
|
Kleisli { case (address, value) =>
|
|
for {
|
|
offset <- Machine.getOffset
|
|
set <- Machine.set(address + offset, value)
|
|
} yield set
|
|
}
|
|
)
|
|
|
|
val defaultOperandModes: Map[Int, OperandMode] = Map(
|
|
0 -> position,
|
|
1 -> immediate,
|
|
2 -> relative,
|
|
)
|
|
|
|
}
|