Created
January 25, 2018 19:56
-
-
Save mildsunrise/60a516da83d448ba1363a7deac361515 to your computer and use it in GitHub Desktop.
A Brainfuck interpreter, written in Whitespace π
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
* | |
* | |
This is a Brainfuck interpreter written in the Whitespace programming language. | |
Any visible characters are comments, just there for easier understanding of the code. | |
Usage: | |
Run this program and supply the Brainfuck code *in one line* (for now). | |
The brainfuck code will run and a final status message will be displayed with the VM state: | |
- Status code (reason for ending, see section below) | |
- Offset (byte number of the last loaded instruction, -1 -> none) | |
- Ptr (value of the pointer to memory) | |
Status codes: | |
0 -> Successful exit, reached end of script | |
1 -> Out-of-bounds memory access | |
2 -> Invalid closing bracket | |
3 -> Unclosed opening bracket | |
Brainfuck implementation details: | |
Infinite array, valid indexes start at 0 (pointer initial value). | |
The pointer can be decremented or incremented freely, but accessing | |
memory when it's negative will cause VM to exit. | |
Array can hold big integers, never overflows. | |
I/O is inherited from Whitespace's character I/O, look there for details | |
about outputting invalid integers, EOF when inputting, etc. | |
* | |
* | |
* | |
* | |
Print initial prompt | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
; <-Save_code_at_0x10 | |
<-Label000 | |
dump | |
read | |
store increment | |
TODO:better_test_for_end_condition_before_jumping | |
jump_back_to_Label000 | |
END_LOOP | |
<-Label001 | |
save_end_at_0x0 | |
saved!_Print_dash_line | |
<-Label010 | |
output | |
increment | |
jump_if_< | |
24: | |
END_LOOP | |
end_dash_line|INTERPRETER!!!_initialize_state_(0x1->code=0x10,0x2->ptr=0,0x3->current=-1) | |
; | |
; | |
MAIN_LOOP_(call_vm_step()_as_long_as_code_is_valid) | |
<-Label011 | |
jump_if_0 | |
vm_step() | |
jump_to_loop | |
<-Label0111 | |
vm_exit(0) | |
ROUTINES!!! | |
<-Label1000_=_op_move_left() | |
RET | |
<-Label1001_=_op_move_right() | |
RET | |
<-Label1010_=_op_decrement() | |
vm_test_mem()_called; | |
RET | |
<-Label1011_=_op_increment() | |
vm_test_mem()_called; | |
RET | |
<-Label1100_=_op_loop_open() | |
vm_test_mem()_called; | |
RET | |
<-Label01100000 | |
START_BRACKET_FIND | |
LOOP_START | |
<-Label01100001 | |
increment | |
test_end_jump | |
LOOP_BODY:test_'[' | |
->Label01100011 | |
test_']' | |
->Label01100100 | |
jump_loop_start | |
->Label01100011 | |
<-Label01100011 | |
jump_loop_start | |
->Label01100011 | |
<-Label01100100 | |
jump_if_counter_zero | |
->Label01100101 | |
jump_loop_start | |
->Label01100011 | |
LOOP_END | |
<-Label01100010 | |
call_vm_exit(3) | |
<-Label01100101 | |
RET | |
<-Label1101_=_op_loop_close() | |
vm_test_mem()_called; | |
START_BRACKET_FIND | |
LOOP_START | |
<-Label01101001 | |
decrement | |
test_start_jump | |
LOOP_BODY:test_'[' | |
->Label01101011 | |
test_']' | |
->Label01101100 | |
jump_loop_start | |
->Label01101011 | |
<-Label01101011 | |
jump_if_counter_zero | |
->Label01101101 | |
jump_loop_start | |
->Label01101011 | |
<-Label01101100 | |
jump_loop_start | |
->Label01101011 | |
LOOP_END | |
<-Label01101010 | |
call_vm_exit(2) | |
<-Label01101101 | |
RET | |
<-Label01101000 | |
RET | |
<-Label1110_=_op_output() | |
vm_test_mem()_called; | |
RET | |
<-Label1111_=_op_input() | |
vm_test_mem()_called; | |
RET | |
<-Label10000_=_vm_step() | |
load_code_and_increment | |
save_copy_in_current | |
load_char jump_for_'<' | |
; | |
; ->Label010000000 | |
jump_for_'>' | |
; | |
; ->Label010000001 | |
jump_for_'-' | |
; | |
; ->Label010000010 | |
jump_for_'+' | |
; | |
; ->Label010000011 | |
jump_for_'[' | |
; | |
; ->Label010000100 | |
jump_for_']' | |
; | |
; ->Label010000101 | |
jump_for_'.' | |
; | |
; ->Label010000110 | |
jump_for_',' | |
; | |
; ->Label010000111 | |
RET;__now_labels_for_each_branch._to_make_things_easier_we_jump_to_routines_instead_of_calling | |
<-Label010000000 | |
jump_to_op_move_left() | |
<-Label010000001 | |
jump_to_op_move_right() | |
<-Label010000010 | |
jump_to_op_decrement() | |
<-Label010000011 | |
jump_to_op_increment() | |
<-Label010000100 | |
jump_to_op_loop_open() | |
<-Label010000101 | |
jump_to_op_loop_close() | |
<-Label010000110 | |
jump_to_op_output() | |
<-Label010000111 | |
jump_to_op_input() | |
<-Label10001_=_vm_exit(status) | |
'[' | |
'V' | |
'M' | |
']' | |
SP | |
'E' | |
'x' | |
'i' | |
't' | |
'.' | |
SP | |
'S' | |
't' | |
'a' | |
't' | |
'u' | |
's' | |
':' | |
SP | |
(status) | |
SP | |
SP | |
'O' | |
'f' | |
'f' | |
's' | |
'e' | |
't' | |
':' | |
SP | |
(current-0x10) | |
SP | |
SP | |
'P' | |
't' | |
'r' | |
':' | |
SP | |
(ptr) | |
'\n' | |
exit | |
<-Label10010_=_vm_test_mem()_->_addr | |
jump_if_< | |
RET | |
<-Label01001000 | |
vm_exit(1) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment