From d7948e639cd7bb8ccdd962d19764786923bf8f46 Mon Sep 17 00:00:00 2001 From: Jacob Date: Thu, 15 Nov 2018 15:22:33 -0500 Subject: [PATCH] Minor fixes Add '%' operation (accidentally omitted) Add strMode function to properly handle String mode (broken before) Change null checks to use null say let Add peek function to handle peeking an empty stack (returns 0) Fix '\' operation (broken, did not swap top 2 stack elements) Add temporary output handling for testing Add temporary input handling for testing Add '0' - '9' operations (unintentionally omitted before) Fix skipping spaces while in String mode Step returns whether pointer is inactive or not; whether the program has terminated --- .../befide/befunge/b93/B93Interpreter.kt | 74 +++++++++++++------ 1 file changed, 52 insertions(+), 22 deletions(-) diff --git a/befunge/src/main/kotlin/befide/befunge/b93/B93Interpreter.kt b/befunge/src/main/kotlin/befide/befunge/b93/B93Interpreter.kt index 6db61d9..d887514 100644 --- a/befunge/src/main/kotlin/befide/befunge/b93/B93Interpreter.kt +++ b/befunge/src/main/kotlin/befide/befunge/b93/B93Interpreter.kt @@ -33,10 +33,11 @@ class B93Interpreter : Interpreter { private fun pop(): Value { val v = _pop() - if (v != null) { - stackChanged(StackEvent(StackAction.Pop, listOf(v))) - } - return Value(0) + val ret = v?.let { + stackChanged(StackEvent(StackAction.Pop, listOf(it))) + it + } ?: Value(0) + return ret } private fun pop(num: Int): List { @@ -59,6 +60,13 @@ class B93Interpreter : Interpreter { stackChanged.invoke(StackEvent(StackAction.Push, vs)) } + private fun peek(): Value { + if (!stack.empty()) { + return stack.peek() + } + return Value(0) + } + private fun binop(bop: Char) { val (vb, va) = pop(2) val a = va.value @@ -68,10 +76,11 @@ class B93Interpreter : Interpreter { '-' -> a - b '*' -> a * b '/' -> a / b + '%' -> a % b '`' -> if (a > b) 1L else 0L else -> null } - if (res != null) { + res?.let { val vres = Value(res) push(vres) } @@ -84,8 +93,8 @@ class B93Interpreter : Interpreter { '!' -> if (v == 0L) 1L else 0L else -> null } - if (res != null) { - val vres = Value(res) + res?.let { + val vres = Value(it) push(vres) } } @@ -98,8 +107,8 @@ class B93Interpreter : Interpreter { 'v' -> DOWN else -> null } - if (newDelta != null) { - ip.delta = newDelta + newDelta?.let { + ip.delta = it } } @@ -117,8 +126,8 @@ class B93Interpreter : Interpreter { '_' -> if (cond) RIGHT else LEFT else -> null } - if (newDelta != null) { - ip.delta = newDelta + newDelta?.let { + ip.delta = it } } @@ -134,12 +143,12 @@ class B93Interpreter : Interpreter { private fun stackop(sop: Char) { when (sop) { ':' -> { - val vc = stack.peek().copy() + val vc = peek().copy() push(vc) } '\\' -> { val (v2, v1) = pop(2) - push(listOf(v1, v2)) + push(listOf(v2, v1)) } '$' -> { pop() @@ -151,10 +160,11 @@ class B93Interpreter : Interpreter { val vv = pop() val v = vv.value val out = when (type) { - '.' -> v.toString().toCharArray() + '.' -> v.toString().toCharArray() + ' ' ',' -> charArrayOf(v.toChar()) else -> charArrayOf() } + print(out) //TEMPORARY //TODO output {out} chararray } @@ -163,9 +173,13 @@ class B93Interpreter : Interpreter { // No ipChanged here, shown in execInstr } - private fun input() { - val inp = 0L //TODO get input - val vinp = Value(inp) + private fun input(type: Char) { + val inp = readLine() + val vinp = Value(when(type) { + '&' -> inp?.toLong() ?: 0L + '~' -> inp?.get(0)?.toLong() ?: 0L + else -> 0L + }) push(vinp) } @@ -198,6 +212,11 @@ class B93Interpreter : Interpreter { ip.mode = IpMode.Inactive } + private fun pushDig(dig: Char) { + val num = dig.toLong() - '0'.toLong() + push(Value(num)) + } + private fun noOp() {} private fun execInstr(instr: Value) { @@ -215,29 +234,40 @@ class B93Interpreter : Interpreter { '#' -> stepIP() 'g' -> fget() 'p' -> fput() - '&', '~' -> input() + '&', '~' -> input(car) '@' -> terminate() + in '0'..'9' -> pushDig(car) else -> noOp() } } + private fun strMode(instr: Value) { + if (instr.asChar == '"') { + toggleStrmode() + return + } + push(instr) + } + override fun step(): Boolean { val instr = funge[ip.pos] val currIP = ip.copy() when (ip.mode) { IpMode.Inactive -> noOp() IpMode.Normal -> execInstr(instr) - IpMode.String -> push(instr) + IpMode.String -> strMode(instr) } if (ip.mode != IpMode.Inactive) { stepIP() - while (funge[ip.pos].asChar == ' ') { - stepIP() + if (ip.mode != IpMode.String) { + while (funge[ip.pos].asChar == ' ') { + stepIP() + } } val newIP = ip.copy() ipChanged(IpEvent(currIP, newIP)) } - return true + return ip.mode != IpMode.Inactive } override fun reset() {