Skip to content

Instantly share code, notes, and snippets.

@Bios-Marcel
Last active January 15, 2018 11:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Bios-Marcel/e2ead9a51aa901254a7971c9a2806dc9 to your computer and use it in GitHub Desktop.
Save Bios-Marcel/e2ead9a51aa901254a7971c9a2806dc9 to your computer and use it in GitHub Desktop.
A brainfuck interpreter, takes a string without linebreaks as first argument
import kotlinx.cinterop.*
import platform.posix.*
fun main(args: Array<String>) {
if(args.size >= 1) {
if(args[0].equals("-file", true) || args[0].equals("-f", true)) {
val fileName = args[1]
val file = fopen(fileName, "r")
if (file == null) {
print("cannot open input file $fileName")
}
else
{
var brainfuck = ""
try {
memScoped {
val bufferLength = 64 * 1024
val buffer = allocArray<ByteVar>(bufferLength)
while(true) {
val nextLine = fgets(buffer, bufferLength, file)?.toKString()
if (nextLine == null || nextLine.isEmpty()) {
break
}
brainfuck += nextLine
}
}
} finally {
fclose(file)
}
println("Interpreting Brainfuck code")
BrainfuckInterpreter.interpret(brainfuck)
println("Interpretation of Brainfuck code complete.")
}
}
else {
println("Interpreting Brainfuck code")
BrainfuckInterpreter.interpret(args[0])
println("Interpretation of Brainfuck code complete.")
}
}
}
object BrainfuckInterpreter {
fun interpret(brainfuck: String) {
var bfState = BFState()
interpret(brainfuck, bfState)
}
fun interpret(brainfuck: String, bfState: BFState) {
val chars = brainfuck.toCharArray();
var i = 0
while(i < chars.size) {
val c = chars[i]
when(c) {
'>' -> bfState.pointer++
'<' -> bfState.pointer--
'+' -> bfState.memory[bfState.pointer]++
'-' -> bfState.memory[bfState.pointer]--
'.' -> print(bfState.memory[bfState.pointer].toChar())
',' -> bfState.memory[bfState.pointer]=readLine()?.first()?.toInt() ?: 0
'[' -> {
val loopContent = brainfuck.substring(i+1, indexNextCorrectClosing(brainfuck, i+1))
i+=loopContent.length
while(bfState.memory[bfState.pointer] != 0) {
interpret(loopContent, bfState)
}
}
}
i++
}
}
fun indexNextCorrectClosing(brainfuck: String, start: Int): Int {
val chars = brainfuck.toCharArray()
var skip = 0
for(i in start until chars.size) {
val char = chars[i]
if(char == ']') {
if(skip == 0)
return i;
skip--
}
else if(char == '[') {
skip++
}
}
return chars.size-1;
}
}
class BFState {
public var memory = IntArray(63000)
public var pointer = 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment