Created
July 26, 2018 23:41
-
-
Save dumptruckman/e02e447b1f151e1a31f292565f054b6e to your computer and use it in GitHub Desktop.
A0A0 Interpreter in Kotlin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.dumptruckman.a0a0 | |
import java.util.LinkedList | |
import java.util.Scanner | |
fun main(args: Array<String>) { | |
// Example usage with cat program | |
Interpreter.interpret("A0 A0\n" + | |
"A0 C3 G1 G1 A0\n" + | |
"A0 I0 V0 P0 A0\n" + | |
"A0 A1 G-3 G-3 A0\n" + | |
"G-3") | |
} | |
class Interpreter(code: String) { | |
val lines = code.lines().map { LinkedList(it.split("\\s+".toRegex()).filter { "\\w-?\\d+".toRegex().matches(it) }) }.toMutableList() | |
var currentLine = 0 | |
val line | |
get() = lines[currentLine] | |
fun operand(modify: (Int) -> Int) { | |
val vIndex = line.map { it[0] }.indexOf('V') | |
if (vIndex != -1) { | |
line[vIndex] = line[vIndex].replace("-?\\d+".toRegex(), { modify(it.value.toInt()).toString() }) | |
} | |
} | |
fun run() { | |
val scanner = Scanner(System.`in`) | |
loop@ while (currentLine < lines.size && line.isNotEmpty()) { | |
if (DEBUG) debug() | |
val instruction = line.poll() ?: break | |
val op = instruction[0] | |
val arg = instruction.substring(1).toInt() | |
when (op) { | |
'A' -> lines.ensureGet(currentLine + arg).addAll(line) | |
'C' -> lines.ensureGet(currentLine + arg).clear() | |
'G' -> { currentLine += arg; continue@loop } | |
'V' -> line[0] = line[0].replace("-?\\d+".toRegex(), arg.toString()) | |
'O' -> print(arg) | |
'P' -> print((arg % 256).toChar()) | |
'I' -> operand { | |
if (arg == 0) { | |
scanner.nextInt() | |
} else { | |
System.`in`.read() | |
} | |
} | |
'S', 'D', 'M', 'L' -> operand { OPS[op]!!.invoke(it, arg) } | |
} | |
currentLine++ | |
} | |
} | |
fun debug() { | |
println() | |
lines.forEachIndexed({ | |
i, p -> println("* $i: $p") | |
}) | |
} | |
companion object { | |
const val DEBUG = false | |
val OPS: Map<Char, (Int, Int) -> Int> = mapOf('S' to { x, y -> x + y }, | |
'D' to { x, y -> x - y }, | |
'M' to { x, y -> x * y }, | |
'L' to { x, y -> when { // This is probably wrong | |
x > y -> 1 | |
x < y -> -1 | |
else -> 0 | |
}}) | |
fun interpret(code: String) { | |
Interpreter(code).run() | |
} | |
} | |
fun MutableList<LinkedList<String>>.ensureGet(index: Int): LinkedList<String> { | |
while (index >= this.size) { | |
this.add(LinkedList()) | |
} | |
return this[index] | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment