Last active
January 15, 2018 11:59
-
-
Save Bios-Marcel/e2ead9a51aa901254a7971c9a2806dc9 to your computer and use it in GitHub Desktop.
A brainfuck interpreter, takes a string without linebreaks as first argument
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
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