2025-09-15 12:24:18 +10:00
|
|
|
# A Brainfuck interpreter in Ground (https://git.maxwellj.xyz/ground/ground) (https://en.wikipedia.org/wiki/Brainfuck)
|
|
|
|
|
2025-09-13 10:10:21 +10:00
|
|
|
stdout "Brainf*ck Code: "
|
|
|
|
stdin &str
|
|
|
|
stdout "Input: "
|
|
|
|
stdin &input
|
|
|
|
set &idx 0
|
|
|
|
setlist *cells 0
|
|
|
|
setlist *startloop
|
|
|
|
set &loopdepth 0
|
|
|
|
set &ignore false
|
|
|
|
set &selectedcell 0
|
|
|
|
set &inputidx 0
|
|
|
|
getstrsize $str &len
|
|
|
|
|
|
|
|
setlist *ascii ' ' '!' '"' '#' '$' '%' '&' "'" '(' ')' '*' '+' ',' '-' '.' '/' '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' ':' ';' '<' '=' '>' '?' '@' 'A' 'B' 'C' 'D' 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M' 'N' 'O' 'P' 'Q' 'R' 'S' 'T' 'U' 'V' 'W' 'X' 'Y' 'Z' '[' '\' ']' '^' '_' '`' 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 'u' 'v' 'w' 'x' 'y' 'z' '{' '|' '}' '~'
|
|
|
|
|
|
|
|
@loop
|
|
|
|
equal $idx $len &store
|
|
|
|
if $store %end
|
|
|
|
|
|
|
|
getstrcharat $str $idx &idxchar
|
|
|
|
|
|
|
|
equal $idxchar '+' &store
|
|
|
|
if $store %plus
|
|
|
|
|
|
|
|
equal $idxchar '-' &store
|
|
|
|
if $store %minus
|
|
|
|
|
|
|
|
equal $idxchar '>' &store
|
|
|
|
if $store %right
|
|
|
|
|
|
|
|
equal $idxchar '<' &store
|
|
|
|
if $store %left
|
|
|
|
|
|
|
|
equal $idxchar '[' &store
|
|
|
|
if $store %leftbracket
|
|
|
|
|
|
|
|
equal $idxchar ']' &store
|
|
|
|
if $store %rightbracket
|
|
|
|
|
|
|
|
equal $idxchar ',' &store
|
|
|
|
if $store %input
|
|
|
|
|
|
|
|
equal $idxchar '.' &store
|
|
|
|
if $store %output
|
|
|
|
|
|
|
|
jump %increment
|
|
|
|
|
|
|
|
@plus
|
|
|
|
if $ignore %increment
|
|
|
|
lesser $selectedcell 0 &store
|
|
|
|
if $store %rangeerror
|
|
|
|
getlistat *cells $selectedcell &store
|
|
|
|
add $store 1 &store
|
|
|
|
setlistat *cells $selectedcell $store
|
|
|
|
inequal $store 256 &store
|
|
|
|
if $store %increment
|
|
|
|
setlistat *cells $selectedcell 0
|
|
|
|
jump %increment
|
|
|
|
|
|
|
|
@minus
|
|
|
|
if $ignore %increment
|
|
|
|
lesser $selectedcell 0 &store
|
|
|
|
if $store %rangeerror
|
|
|
|
getlistat *cells $selectedcell &store
|
|
|
|
subtract $store 1 &store
|
|
|
|
setlistat *cells $selectedcell $store
|
|
|
|
inequal $store -1 &store
|
|
|
|
if $store %increment
|
|
|
|
setlistat *cells $selectedcell 255
|
|
|
|
jump %increment
|
|
|
|
|
|
|
|
@right
|
|
|
|
if $ignore %increment
|
|
|
|
add $selectedcell 1 &selectedcell
|
|
|
|
|
|
|
|
# Check if new cell needs to be added
|
|
|
|
getlistsize *cells &store
|
|
|
|
lesser $selectedcell $store &store
|
|
|
|
if $store %increment
|
|
|
|
listappend *cells 0
|
|
|
|
jump %increment
|
|
|
|
|
|
|
|
@left
|
|
|
|
if $ignore %increment
|
|
|
|
subtract $selectedcell 1 &selectedcell
|
|
|
|
jump %increment
|
|
|
|
|
|
|
|
@leftbracket
|
|
|
|
if $ignore %customignoreleft
|
|
|
|
listappend *startloop 0
|
|
|
|
setlistat *startloop $loopdepth $idx
|
|
|
|
set &ignoreidx $loopdepth
|
|
|
|
add $loopdepth 1 &loopdepth
|
|
|
|
|
|
|
|
getlistat *cells $selectedcell &store
|
|
|
|
inequal $store 0 &store
|
|
|
|
if $store %increment
|
|
|
|
|
|
|
|
# If selected cell is 0, jump to the matching right bracket (by ignoring all other instructions)
|
|
|
|
set &ignore true
|
|
|
|
jump %increment
|
|
|
|
|
|
|
|
@customignoreleft
|
|
|
|
add $loopdepth 1 &loopdepth
|
|
|
|
jump %increment
|
|
|
|
|
|
|
|
@rightbracket
|
|
|
|
subtract $loopdepth 1 &loopdepth
|
|
|
|
if $ignore %continue
|
|
|
|
getlistat *startloop $loopdepth &store
|
|
|
|
set &idx $store
|
|
|
|
# Don't increment
|
|
|
|
jump %loop
|
|
|
|
|
|
|
|
@continue
|
|
|
|
inequal $loopdepth $ignoreidx &store
|
|
|
|
if $store %increment
|
|
|
|
set &ignore false
|
|
|
|
jump %increment
|
|
|
|
|
|
|
|
@input
|
|
|
|
if $ignore %increment
|
|
|
|
lesser $selectedcell 0 &store
|
|
|
|
if $store %rangeerror
|
|
|
|
|
|
|
|
getstrsize $input &store
|
|
|
|
equal $inputidx $store &store
|
|
|
|
if $store %inputzero
|
|
|
|
|
|
|
|
getstrcharat $input $inputidx &inputstore
|
|
|
|
tostring $inputstore &store
|
|
|
|
equal $store "'" &store
|
|
|
|
if $store %singlequote
|
|
|
|
set &asciiidx 0
|
|
|
|
@findascii
|
|
|
|
getlistsize *ascii &store
|
|
|
|
equal $store $asciiidx &store
|
|
|
|
if $store %noascii
|
|
|
|
|
|
|
|
equal $asciiidx 7 &store
|
|
|
|
if $store %asciiincrement
|
|
|
|
getlistat *ascii $asciiidx &store
|
|
|
|
equal $store $inputstore &store
|
|
|
|
if $store %exitascii
|
|
|
|
@asciiincrement
|
|
|
|
add $asciiidx 1 &asciiidx
|
|
|
|
jump %findascii
|
|
|
|
|
|
|
|
@exitascii
|
|
|
|
add $asciiidx 32 &asciiidx
|
|
|
|
setlistat *cells $selectedcell $asciiidx
|
|
|
|
|
|
|
|
add $inputidx 1 &inputidx
|
|
|
|
jump %increment
|
|
|
|
|
|
|
|
@singlequote
|
|
|
|
setlistat *cells $selectedcell 39
|
|
|
|
add $inputidx 1 &inputidx
|
|
|
|
jump %increment
|
|
|
|
|
|
|
|
@inputzero
|
|
|
|
setlistat *cells $selectedcell 0
|
|
|
|
add $inputidx 1 &inputidx
|
|
|
|
jump %increment
|
|
|
|
|
|
|
|
@noascii
|
|
|
|
error "Error: Invalid ASCII output code"
|
|
|
|
|
|
|
|
@output
|
|
|
|
if $ignore %increment
|
|
|
|
lesser $selectedcell 0 &store
|
|
|
|
if $store %rangeerror
|
|
|
|
|
|
|
|
# 0-31 is not doing anything, except for 10 which is newline
|
|
|
|
getlistat *cells $selectedcell &store
|
|
|
|
equal $store 10 &store
|
|
|
|
if $store %newline
|
|
|
|
|
|
|
|
getlistat *cells $selectedcell &store
|
|
|
|
lesser $store 32 &store
|
|
|
|
if $store %blank
|
|
|
|
|
|
|
|
getlistat *cells $selectedcell &store
|
|
|
|
greater $store 126 &store
|
|
|
|
if $store %blank
|
|
|
|
|
|
|
|
getlistat *cells $selectedcell &store
|
|
|
|
subtract $store 32 &store
|
|
|
|
getlistat *ascii $store &store
|
|
|
|
stdout $store
|
|
|
|
jump %increment
|
|
|
|
|
|
|
|
@newline
|
|
|
|
stdlnout ""
|
|
|
|
jump %increment
|
|
|
|
|
|
|
|
@blank
|
|
|
|
stdout " "
|
|
|
|
jump %increment
|
|
|
|
|
|
|
|
|
|
|
|
@increment
|
|
|
|
add $idx 1 &idx
|
|
|
|
jump %loop
|
|
|
|
|
|
|
|
@rangeerror
|
|
|
|
error "Cannot edit garbage data (negative cell index)"
|
|
|
|
@end
|
|
|
|
|
|
|
|
# Output list
|
|
|
|
stdlnout ""
|
|
|
|
getlistsize *cells &listlen
|
|
|
|
set &idx 0
|
|
|
|
stdout "["
|
|
|
|
@stdoutloop
|
|
|
|
getlistat *cells $idx &store
|
|
|
|
stdout $store
|
|
|
|
add $idx 1 &idx
|
|
|
|
equal $idx $listlen &store
|
|
|
|
if $store %trueend
|
|
|
|
stdout ", "
|
|
|
|
jump %stdoutloop
|
|
|
|
|
|
|
|
@trueend
|
|
|
|
stdout "]"
|