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
This commit is contained in:
Jacob
2018-11-15 15:22:33 -05:00
parent 247d9d4d52
commit d7948e639c

View File

@@ -33,10 +33,11 @@ class B93Interpreter : Interpreter {
private fun pop(): Value { private fun pop(): Value {
val v = _pop() val v = _pop()
if (v != null) { val ret = v?.let {
stackChanged(StackEvent(StackAction.Pop, listOf(v))) stackChanged(StackEvent(StackAction.Pop, listOf(it)))
} it
return Value(0) } ?: Value(0)
return ret
} }
private fun pop(num: Int): List<Value> { private fun pop(num: Int): List<Value> {
@@ -59,6 +60,13 @@ class B93Interpreter : Interpreter {
stackChanged.invoke(StackEvent(StackAction.Push, vs)) stackChanged.invoke(StackEvent(StackAction.Push, vs))
} }
private fun peek(): Value {
if (!stack.empty()) {
return stack.peek()
}
return Value(0)
}
private fun binop(bop: Char) { private fun binop(bop: Char) {
val (vb, va) = pop(2) val (vb, va) = pop(2)
val a = va.value val a = va.value
@@ -68,10 +76,11 @@ class B93Interpreter : Interpreter {
'-' -> a - b '-' -> a - b
'*' -> a * b '*' -> a * b
'/' -> a / b '/' -> a / b
'%' -> a % b
'`' -> if (a > b) 1L else 0L '`' -> if (a > b) 1L else 0L
else -> null else -> null
} }
if (res != null) { res?.let {
val vres = Value(res) val vres = Value(res)
push(vres) push(vres)
} }
@@ -84,8 +93,8 @@ class B93Interpreter : Interpreter {
'!' -> if (v == 0L) 1L else 0L '!' -> if (v == 0L) 1L else 0L
else -> null else -> null
} }
if (res != null) { res?.let {
val vres = Value(res) val vres = Value(it)
push(vres) push(vres)
} }
} }
@@ -98,8 +107,8 @@ class B93Interpreter : Interpreter {
'v' -> DOWN 'v' -> DOWN
else -> null else -> null
} }
if (newDelta != null) { newDelta?.let {
ip.delta = newDelta ip.delta = it
} }
} }
@@ -117,8 +126,8 @@ class B93Interpreter : Interpreter {
'_' -> if (cond) RIGHT else LEFT '_' -> if (cond) RIGHT else LEFT
else -> null else -> null
} }
if (newDelta != null) { newDelta?.let {
ip.delta = newDelta ip.delta = it
} }
} }
@@ -134,12 +143,12 @@ class B93Interpreter : Interpreter {
private fun stackop(sop: Char) { private fun stackop(sop: Char) {
when (sop) { when (sop) {
':' -> { ':' -> {
val vc = stack.peek().copy() val vc = peek().copy()
push(vc) push(vc)
} }
'\\' -> { '\\' -> {
val (v2, v1) = pop(2) val (v2, v1) = pop(2)
push(listOf(v1, v2)) push(listOf(v2, v1))
} }
'$' -> { '$' -> {
pop() pop()
@@ -151,10 +160,11 @@ class B93Interpreter : Interpreter {
val vv = pop() val vv = pop()
val v = vv.value val v = vv.value
val out = when (type) { val out = when (type) {
'.' -> v.toString().toCharArray() '.' -> v.toString().toCharArray() + ' '
',' -> charArrayOf(v.toChar()) ',' -> charArrayOf(v.toChar())
else -> charArrayOf() else -> charArrayOf()
} }
print(out) //TEMPORARY
//TODO output {out} chararray //TODO output {out} chararray
} }
@@ -163,9 +173,13 @@ class B93Interpreter : Interpreter {
// No ipChanged here, shown in execInstr // No ipChanged here, shown in execInstr
} }
private fun input() { private fun input(type: Char) {
val inp = 0L //TODO get input val inp = readLine()
val vinp = Value(inp) val vinp = Value(when(type) {
'&' -> inp?.toLong() ?: 0L
'~' -> inp?.get(0)?.toLong() ?: 0L
else -> 0L
})
push(vinp) push(vinp)
} }
@@ -198,6 +212,11 @@ class B93Interpreter : Interpreter {
ip.mode = IpMode.Inactive ip.mode = IpMode.Inactive
} }
private fun pushDig(dig: Char) {
val num = dig.toLong() - '0'.toLong()
push(Value(num))
}
private fun noOp() {} private fun noOp() {}
private fun execInstr(instr: Value) { private fun execInstr(instr: Value) {
@@ -215,29 +234,40 @@ class B93Interpreter : Interpreter {
'#' -> stepIP() '#' -> stepIP()
'g' -> fget() 'g' -> fget()
'p' -> fput() 'p' -> fput()
'&', '~' -> input() '&', '~' -> input(car)
'@' -> terminate() '@' -> terminate()
in '0'..'9' -> pushDig(car)
else -> noOp() else -> noOp()
} }
} }
private fun strMode(instr: Value) {
if (instr.asChar == '"') {
toggleStrmode()
return
}
push(instr)
}
override fun step(): Boolean { override fun step(): Boolean {
val instr = funge[ip.pos] val instr = funge[ip.pos]
val currIP = ip.copy() val currIP = ip.copy()
when (ip.mode) { when (ip.mode) {
IpMode.Inactive -> noOp() IpMode.Inactive -> noOp()
IpMode.Normal -> execInstr(instr) IpMode.Normal -> execInstr(instr)
IpMode.String -> push(instr) IpMode.String -> strMode(instr)
} }
if (ip.mode != IpMode.Inactive) { if (ip.mode != IpMode.Inactive) {
stepIP() stepIP()
while (funge[ip.pos].asChar == ' ') { if (ip.mode != IpMode.String) {
stepIP() while (funge[ip.pos].asChar == ' ') {
stepIP()
}
} }
val newIP = ip.copy() val newIP = ip.copy()
ipChanged(IpEvent(currIP, newIP)) ipChanged(IpEvent(currIP, newIP))
} }
return true return ip.mode != IpMode.Inactive
} }
override fun reset() { override fun reset() {