Skip to content

Instantly share code, notes, and snippets.

@dumptruckman
Created July 26, 2018 23:41
Show Gist options
  • Save dumptruckman/e02e447b1f151e1a31f292565f054b6e to your computer and use it in GitHub Desktop.
Save dumptruckman/e02e447b1f151e1a31f292565f054b6e to your computer and use it in GitHub Desktop.
A0A0 Interpreter in Kotlin
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