-
-
Save cbpudding/91e0da9ea7cd0c69123328e6671d1089 to your computer and use it in GitHub Desktop.
A small brainf*** interpreter written in MIPS Assembly
This file contains hidden or 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
.data | |
buffer: .space 65536 | |
memory: .space 256 | |
.text | |
main: | |
la $a0, buffer # Get the source code to execute | |
li $a1, 65536 | |
li $v0, 8 | |
syscall | |
la $a0, memory # Initialize memory | |
la $a1, memory | |
addi $a1, $a1, 256 | |
memset.loop: | |
sb $zero, ($a0) | |
addi $a0, $a0, 1 | |
bne $a0, $a1, memset.loop | |
memset.end: | |
la $a0, buffer # Start executing the string as BF code | |
li $s0, 0 | |
li $s3, 0 | |
loop: | |
lb $s1, ($a0) # Read a byte from the code | |
addi $a0, $a0, 1 | |
addi $s0, $s0, 1 | |
li $s2, '+' # Is it an increment? | |
beq $s1, $s2, increment | |
li $s2, '-' # Is it a decrement? | |
beq $s1, $s2, decrement | |
li $s2, '>' # Is it a right? | |
beq $s1, $s2, right | |
li $s2, '<' # Is it a left? | |
beq $s1, $s2, left | |
li $s2, '.' # Is it a out? | |
beq $s1, $s2, out | |
li $s2, ',' # Is it a in? | |
beq $s1, $s2, in | |
li $s2, '[' # Is it a jump if zero? | |
beq $s1, $s2, jz | |
li $s2, ']' # Is if a jump is not zero? | |
beq $s1, $s2, jnz | |
beq $s1, $zero, done # Are we done? | |
ble $s0, $zero, done | |
b loop # If it's nothing we know, skip over it. | |
increment: | |
la $a1, memory # Pull that byte from memory | |
add $a1, $a1, $s3 | |
lb $s1, ($a1) | |
addi $s1, $s1, 1 # Increment the byte | |
sb $s1, ($a1) # Put it back | |
b loop # Back to the loop | |
decrement: | |
la $a1, memory # Pull that byte from memory | |
add $a1, $a1, $s3 | |
lb $s1, ($a1) | |
subiu $s1, $s1, 1 # Decrement the byte | |
sb $s1, ($a1) # Put it back | |
b loop # Back to the loop | |
right: | |
addi $s3, $s3, 1 # Increment the memory index | |
andi $s3, $s3, 255 # Keep the index within the bounds | |
b loop # Back to the loop | |
left: | |
subiu $s3, $s3, 1 # Decrement the memory index | |
andi $s3, $s3, 255 # Keep the index within the bounds | |
b loop # Back to the loop | |
out: | |
la $a1, memory # Pull that byte from memory | |
add $a1, $a1, $s3 | |
lb $s1, ($a1) | |
move $a0, $s1 # Print the character | |
li $v0, 11 | |
syscall | |
la $a0, buffer # Fix $a0 | |
add $a0, $a0, $s0 | |
b loop # Back to the loop | |
in: | |
la $a1, memory # Get the memory location | |
add $a1, $a1, $s3 | |
li $v0, 12 # Get a character from the console | |
syscall | |
sb $v0, ($a1) # Store the byte | |
b loop # Back to the loop | |
jz: | |
la $a1, memory # Pull the byte from memory | |
add $a1, $a1, $s3 | |
lb $s1, ($a1) | |
bne $s1, $zero, loop # Skip if the cell isn't zero | |
li $s1, 1 | |
jz.loop: | |
lb $s4, ($a0) # Read the next instruction | |
addi $a0, $a0, 1 | |
addi $s0, $s0, 1 | |
li $s2, '[' # Is this a [? | |
beq $s4, $s2, jz.jz | |
li $s2, ']' # Is this a ]? | |
beq $s4, $s2, jz.jnz | |
beq $s4, $zero, done # Are we done? | |
b jz.loop | |
jz.jz: | |
addi $s1, $s1, 1 # Increment the depth variable | |
b jz.loop | |
jz.jnz: | |
subi $s1, $s1, 1 # Decrement the depth variable | |
beq $s1, $zero, loop # Is this the matching bracket? | |
b jz.loop | |
jnz: | |
la $a1, memory # Pull the byte from memory | |
add $a1, $a1, $s3 | |
lb $s1, ($a1) | |
beq $s1, $zero, loop # Skip if the cell is zero | |
li $s1, 1 | |
subi $a0, $a0, 1 | |
subi $s0, $s0, 1 | |
jnz.loop: | |
subi $a0, $a0, 1 # Seek to the previous instruction | |
subi $s0, $s0, 1 | |
blt $s0, $zero, done # Are we done? | |
lb $s4, ($a0) # Read the previous instruction | |
li $s2, '[' # Is this a [? | |
beq $s4, $s2, jnz.jz | |
li $s2, ']' # Is this a ]? | |
beq $s4, $s2, jnz.jnz | |
b jnz.loop | |
jnz.jz: | |
subi $s1, $s1, 1 # Decrement the depth variable | |
beq $s1, $zero, jnz.done# Is this the matching bracket? | |
b jnz.loop | |
jnz.jnz: | |
addi $s1, $s1, 1 # Increment the depth variable | |
b jnz.loop | |
jnz.done: | |
addi $a0, $a0, 1 # Fix a0 and s0 | |
addi $s0, $s0, 1 | |
b loop | |
done: | |
li $v0, 10 # Exit gracefully | |
syscall |
Wow, I can almost read this.
Almost eh? How would I make it more readable?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Wow, I can almost read this.