diff --git a/befunge/src/main/kotlin/befide/befunge/b93/Befunge93.kt b/befunge/src/main/kotlin/befide/befunge/b93/Befunge93.kt index 0ed12e1..045b94d 100644 --- a/befunge/src/main/kotlin/befide/befunge/b93/Befunge93.kt +++ b/befunge/src/main/kotlin/befide/befunge/b93/Befunge93.kt @@ -2,23 +2,20 @@ package befide.befunge.b93 import befide.befunge.b93.state.* import befide.befunge.core.* -import befide.befunge.core.events.IpChange -import befide.befunge.core.events.StackChange import befide.befunge.core.util.readAll -import befide.befunge.core.util.Event import java.io.PipedReader import java.io.PipedWriter import java.util.* class Interpreter93(stdinSrc: PipedWriter, stdoutDest: PipedReader) - : MutableInterpreter() { + : MutableInterpreter() { override val ip = Pointer93() override val funge = Funge93() - override val stack = Stack() + override val stack = Stack() - override fun stackDefault() = LongData.ZERO + override fun stackDefault() = Data93.ZERO override val stdin: PipedReader = PipedReader(stdinSrc) override val stdout: PipedWriter = PipedWriter(stdoutDest) @@ -32,16 +29,20 @@ fun main(args: Array) { val int = Interpreter93(stdinSrc, stdoutDest) -// int.onIpChange += { -// println(it.to.pos) -// } + int.funge.onChange += { (pos, from, to) -> + println("$pos from $from to $to") + } -// int.funge.src = """2>:3g" "-!v\ g30 < -// |!`"O":+1_:.:03p>03g+:"O"`| -// @ ^ p3\" ":< -//2 234567890123456789012345678901234567890123456789012345678901234567890123456789""" + int.onIpChange += { (_, to) -> + println("ip to ${to.pos}") + } - int.funge.src = """fedc;ba9876;54321>:#._@""" + int.funge.src = """2>:3g" "-!v\ g30 < + |!`"O":+1_:.:03p>03g+:"O"`| + @ ^ p3\" ":< +2 234567890123456789012345678901234567890123456789012345678901234567890123456789""" + +// int.funge.src = """fedc;ba9876;54321>:#._@""" while (int.ip.mode != PointerMode.Terminated) { int.step() diff --git a/befunge/src/main/kotlin/befide/befunge/b93/Instructions.kt b/befunge/src/main/kotlin/befide/befunge/b93/Instructions.kt index 4420e31..a5b1b11 100644 --- a/befunge/src/main/kotlin/befide/befunge/b93/Instructions.kt +++ b/befunge/src/main/kotlin/befide/befunge/b93/Instructions.kt @@ -1,14 +1,14 @@ package befide.befunge.b93 -import befide.befunge.b93.state.LongData +import befide.befunge.b93.state.Data93 import befide.befunge.b93.state.PointerMode import befide.befunge.b93.state.Vec2 import befide.befunge.core.InstructionSet import befide.befunge.core.MutableInterpreter import befide.befunge.core.util.chooseOne -class B93Instructions : InstructionSet { - override fun MutableInterpreter.handle(): Boolean { +class B93Instructions : InstructionSet { + override fun MutableInterpreter.handle(): Boolean { when (mode) { PointerMode.Terminated -> return true PointerMode.String -> when (instr.char) { @@ -19,15 +19,15 @@ class B93Instructions : InstructionSet { PointerMode.Normal -> when (instr.char) { null -> return false - in "0123456789" -> push(LongData(instr.char.toString().toLong(16))) + in "0123456789" -> push(Data93(instr.char.toString().toLong(16))) '+' -> pop(2).let { (b, a) -> push(a + b) } '-' -> pop(2).let { (b, a) -> push(a - b) } '*' -> pop(2).let { (b, a) -> push(a * b) } '/' -> pop(2).let { (b, a) -> push(a / b) } '%' -> pop(2).let { (b, a) -> push(a mod b) } - '!' -> pop(1).let { (n) -> push(LongData(if (n.data == 0L) 1L else 0L)) } - '`' -> pop(2).let { (b, a) -> push(LongData(if (a.data > b.data) 1L else 0L)) } + '!' -> pop(1).let { (n) -> push(Data93(if (n.data == 0L) 1L else 0L)) } + '`' -> pop(2).let { (b, a) -> push(Data93(if (a.data > b.data) 1L else 0L)) } '>' -> delta = Vec2.RIGHT '<' -> delta = Vec2.LEFT @@ -51,13 +51,13 @@ class B93Instructions : InstructionSet { 'p' -> pop(3).let { (y, x, n) -> funge[Vec2(x.data.toInt(), y.data.toInt())] = n } 'g' -> pop(2).let { (y, x) -> push(funge[Vec2(x.data.toInt(), y.data.toInt())]) } - '~' -> push(LongData(stdin.read().toLong())) + '~' -> push(Data93(stdin.read().toLong())) '&' -> { val chars = generateSequence { stdin.read().takeIf { it.toChar().isDigit() } } val long = chars.joinToString("").toLong() - push(LongData(long)) + push(Data93(long)) } '@' -> mode = PointerMode.Terminated @@ -70,15 +70,15 @@ class B93Instructions : InstructionSet { } } -class B93Extras : InstructionSet { - override fun MutableInterpreter.handle(): Boolean { +class B93Extras : InstructionSet { + override fun MutableInterpreter.handle(): Boolean { when (mode) { PointerMode.Terminated -> return true PointerMode.String -> return false PointerMode.Normal -> when (instr.char) { null -> return false - in "0123456789abcdef" -> push(LongData(instr.char.toString().toLong(16))) + in "0123456789abcdef" -> push(Data93(instr.char.toString().toLong(16))) '\'' -> { move() diff --git a/befunge/src/main/kotlin/befide/befunge/b93/state/Data93.kt b/befunge/src/main/kotlin/befide/befunge/b93/state/Data93.kt new file mode 100644 index 0000000..7521379 --- /dev/null +++ b/befunge/src/main/kotlin/befide/befunge/b93/state/Data93.kt @@ -0,0 +1,26 @@ +package befide.befunge.b93.state + +import befide.befunge.core.state.Data +import befide.befunge.core.util.mod + +data class Data93(val data: Long) + : Data { + companion object { + val SPACE = Data93(' ') + val ZERO = Data93(0) + } + + override val char = data.toChar().takeUnless { it.isISOControl() } + + constructor(char: Char) : this(char.toLong()) + + operator fun plus(o: Data93) = Data93(data + o.data) + operator fun minus(o: Data93) = Data93(data - o.data) + operator fun times(o: Data93) = Data93(data * o.data) + operator fun div(o: Data93) = Data93(data / o.data) + operator fun unaryMinus() = Data93(-data) + + infix fun mod(o: Data93) = Data93(data mod o.data) + + override fun toString() = "${char ?: '\u2022'} ($data)" +} \ No newline at end of file diff --git a/befunge/src/main/kotlin/befide/befunge/b93/state/LongData.kt b/befunge/src/main/kotlin/befide/befunge/b93/state/LongData.kt deleted file mode 100644 index a5b5fb8..0000000 --- a/befunge/src/main/kotlin/befide/befunge/b93/state/LongData.kt +++ /dev/null @@ -1,26 +0,0 @@ -package befide.befunge.b93.state - -import befide.befunge.core.state.Data -import befide.befunge.core.util.mod - -data class LongData(val data: Long) - : Data { - companion object { - val SPACE = LongData(' ') - val ZERO = LongData(0) - } - - override val char = data.toChar().takeUnless { it.isISOControl() } - - constructor(char: Char) : this(char.toLong()) - - operator fun plus(o: LongData) = LongData(data + o.data) - operator fun minus(o: LongData) = LongData(data - o.data) - operator fun times(o: LongData) = LongData(data * o.data) - operator fun div(o: LongData) = LongData(data / o.data) - operator fun unaryMinus() = LongData(-data) - - infix fun mod(o: LongData) = LongData(data mod o.data) - - override fun toString() = "${char ?: '\u2022'} ($data)" -} \ No newline at end of file diff --git a/befunge/src/main/kotlin/befide/befunge/b93/state/Vec2.kt b/befunge/src/main/kotlin/befide/befunge/b93/state/Vec2.kt index a654756..6c60b33 100644 --- a/befunge/src/main/kotlin/befide/befunge/b93/state/Vec2.kt +++ b/befunge/src/main/kotlin/befide/befunge/b93/state/Vec2.kt @@ -27,4 +27,13 @@ data class Vec2(val x: Int, val y: Int) { operator fun unaryMinus() = Vec2(-x, -y) infix fun mod(o: Vec2) = Vec2(x mod o.x, y mod o.y) -} \ No newline at end of file + + operator fun rangeTo(o: Vec2) = Bounds2(x..o.x, y..o.y) + infix fun until(o: Vec2) = Bounds2(x until o.x, y until o.y) +} + +data class Bounds2(val x: IntRange, val y: IntRange) { + override fun toString(): String = "($x, $y)" + + operator fun contains(o: Vec2): Boolean = o.x in x && o.y in y +} diff --git a/befunge/src/main/kotlin/befide/befunge/core/events/FungeChange.kt b/befunge/src/main/kotlin/befide/befunge/core/events/FungeChange.kt index 6edd2d1..87ed55b 100644 --- a/befunge/src/main/kotlin/befide/befunge/core/events/FungeChange.kt +++ b/befunge/src/main/kotlin/befide/befunge/core/events/FungeChange.kt @@ -4,7 +4,6 @@ import befide.befunge.core.state.Data import befide.befunge.core.state.Funge data class FungeChange -(val funge: Funge, - val pos: V, +(val pos: V, val from: D, val to: D) \ No newline at end of file diff --git a/befunge/src/main/kotlin/befide/befunge/core/state/Funge.kt b/befunge/src/main/kotlin/befide/befunge/core/state/Funge.kt index 84c6358..994cc3a 100644 --- a/befunge/src/main/kotlin/befide/befunge/core/state/Funge.kt +++ b/befunge/src/main/kotlin/befide/befunge/core/state/Funge.kt @@ -9,9 +9,6 @@ interface Funge { val data: Map val src: String - fun defaultData(): D - fun defaultChar(): Char - fun next(pos: V, delta: V): V operator fun get(pos: V): D diff --git a/befunge/src/main/kotlin/befide/befunge/core/state/MutableFunge.kt b/befunge/src/main/kotlin/befide/befunge/core/state/MutableFunge.kt index aa93dda..260b690 100644 --- a/befunge/src/main/kotlin/befide/befunge/core/state/MutableFunge.kt +++ b/befunge/src/main/kotlin/befide/befunge/core/state/MutableFunge.kt @@ -1,12 +1,25 @@ package befide.befunge.core.state -interface MutableFunge +import befide.befunge.core.events.FungeChange +import befide.befunge.core.util.Event + +abstract class MutableFunge : Funge { - override var data: Map - override var src: String + abstract override var data: Map + abstract override var src: String - operator fun set(pos: V, data: D) + override val onChange = Event>() - fun clear() + fun notify(pos: V, op: () -> Unit) { + val from = this[pos] + op() + val to = this[pos] + + onChange(FungeChange(pos, from, to)) + } + + abstract operator fun set(pos: V, data: D) + + abstract fun clear() } \ No newline at end of file