Textile/brainfuck
Jump to navigation
Jump to search
GET_PTR: { #get the memory address the pointer points to
push $FF,$FE
read
push $FF,$FF
read
}
GET_PTR_VAL: {
[GET_PTR]
read
}
POP: {
push
mul
add
}
DUPE_PTR: {
#store pc lo
push $FF,$FB
write
#store pc hi
add*2
[POP]
push $FF,$FA
write
#restore lo
push 1
add
read
#dupe hi
push $FF,$FA
read
#dupe lo
push $FF,$FB
read
}
#-------------------------------------------------
MAIN: {
jump GET_INPUT_POS
}
#--------------------------------
GET_INPUT_POS: { #get the first byte where input is
#is \0 or ";" then set input pos
input
push
equal INC_INPUT_POS
push ";"
add
equal INC_INPUT_POS
#neither; increment read byte
add
[POP]
#increment lo byte
push 1
add
#byte overflow
push
equal INPUT_POS_OVERFLOW
#loop
add
jump GET_INPUT_POS
}
INPUT_POS_OVERFLOW: {
push 1
add*3
push
jump GET_INPUT_POS
}
###############################
INC_INPUT_POS: {
add
[POP]
#increment
push 1
add
#overflow :skull:
push
equal INPUT_SET_OVERFLOW
add
jump SET_INPUT_POS
}
INPUT_SET_OVERFLOW: {
push 1
add*3
push
jump SET_INPUT_POS
}
SET_INPUT_POS: {
#set lo byte
push $FF,$FD
write
#pop
add*2
[POP]
#set hi byte
push $FF,$FC
write
#pop
add*2
[POP]
jump CHECK_INPUT #enter main program loop
}
#----------------------------------------------
CHECK_INPUT: { #compare input to characters
input
push "+"
equal INC
push 2
add # "-"
equal DEC
push 15
add # "<"
equal LEFT
push 2
add # ">"
equal RIGHT
push 16
sub # "."
equal OUT
push 2
sub # ","
equal INPUT
push 47
add # "["
equal LOOP_OPEN
push 2
add # "]"
equal LOOP_CLOSED
#end of program check
push
mul
equal EXIT
push ";"
add
equal EXIT
#no match, jump to increment
add
[POP]
jump PC_INC
}
#---------------------------
INC: { #push memory address at pointer, increment
[GET_PTR_VAL]
push 1
add
jump INC_DEC
}
DEC: { #push memory address at pointer, decrement
[GET_PTR_VAL]
push 1
sub
jump INC_DEC
}
INC_DEC: {
[GET_PTR]
write
add*4
[POP]
jump PC_INC
}
#--------------------------------------------------
RIGHT: {
#increment the pointer
[GET_PTR]
push 1
add
#address overflow
push
equal PTR_OVERFLOW
#check for $FFFA
push $FA
add
equal BYPASS_RIGHT_LO
[POP]
jump LEFT_RIGHT
}
PTR_OVERFLOW: {
push 1
add*3
push
jump LEFT_RIGHT
}
BYPASS_RIGHT_LO: {
#get to hi byte
add
[POP]
#check FF
push $FF
equal BYPASS_RIGHT_HI
#if it isn't FF
[POP]
push $FA
jmp LEFT_RIGHT
}
BYPASS_RIGHT_HI: { #ptr is FFFA, set to 0000
add
[POP]
push*2
jmp LEFT_RIGHT
}
###############
LEFT: {
#decrement pointer
[GET_PTR]
push 1
sub
#address underflow
push $FF
equal PTR_UNDERFLOW
push 1
add*2
jump LEFT_RIGHT
}
PTR_UNDERFLOW: {
#get to hi ptr byte and decrement
add
[POP]
push 1
sub
push $FF
#if we're on $FFFF
equal BYPASS_LEFT
jump LEFT_RIGHT
}
BYPASS_LEFT: { #set PTR to $FFF9
push 6
sub
jump LEFT_RIGHT
}
###############
LEFT_RIGHT: {
#set $FFFF to top stack
push $FF,$FF
write
#pop 3
add*2
[POP]
#set $FFFE to 2nd top stack
push $FF,$FE
write
add*4
[POP]
jump PC_INC
}
#---------------------------------------
OUT: {
[GET_PTR_VAL]
out
add
[POP]
jump PC_INC
}
#---------------------------------------
INPUT: {
#push address in memory starting on $FFFC
push $FF,$FC
read
push $FF,$FD
read
#push input
input
#store to pointer
[GET_PTR]
write
#increment input pos
push $FF,$FC
read
push $FF,$FD
read
push 1
add
#more overflow
push
equal INPUT_OVERFLOW
add
jump FINISH_INPUT
}
INPUT_OVERFLOW: {
push 1
add*3
push
jump FINISH_INPUT
}
FINISH_INPUT: {
#write to input pos bytes
#set lo byte
push $FF,$FD
write
#pop
add*2
[POP]
#set hi byte
push $FF,$FC
write
#pop
add*9
[POP]
jump PC_INC
}
#----------------------------------------
LOOP_OPEN: {
#compare ptr to 0
[GET_PTR_VAL]
push
equal JMP_BRACE
#pop from stack to get to PC values
add*3
[POP]
[DUPE_PTR]
#loop over
jump PC_INC
}
################
JMP_BRACE: {
#pop 4
add*3
[POP]
#write 1 to $FFFB
push 1,$FF,$FB
write
add*2
[POP]
jump MATCH_BRACE
}
MATCH_BRACE: {
#increment PC
push 1
add
#OVERFLOW
push
equal MATCH_OVERFLOW
add
jump MATCH_CHECK
}
MATCH_OVERFLOW: {
push 1
add*3
push
jump MATCH_CHECK
}
MATCH_CHECK: {
#input and check for either brackets or end
input
push "["
equal MATCH_INC
push 2
add #"]"
equal MATCH_DEC
#the brackets could be uneven
push
mul #"\0"
equal EXIT
push ";"
add #";"
equal EXIT
#none match, loop over
add
[POP]
jump MATCH_BRACE
}
MATCH_INC: {
#increment $FFFB
push 1,$FF,$FB
read
add
push $FF,$FB
write
#pop and loop
add*4
[POP]
jump MATCH_BRACE
}
MATCH_DEC: {
#decrement $FFFB
push $FF,$FB
read
push 1
sub
#if FFFB == 0 then exit this loop
push
equal END_MATCH
#if FFFB != 0
add
push $FF,$FB
write
#pop and loop
add*4
[POP]
jump MATCH_BRACE
}
END_MATCH: {
add*3
[POP]
jump PC_INC
}
#----------------------------------------
LOOP_CLOSED: {
[GET_PTR_VAL]
#compare to 0
push
equal EXIT_LOOP
#not 0, loop over
add*5
[POP]
[DUPE_PTR]
jump PC_INC
}
EXIT_LOOP: {
#pop 4
add*3
[POP]
#store ptr
push $FF,$FB
write
add*2
[POP]
push $FF,$FA
write
#pop from loop stack
add*4
[POP]
#restore ptr
push $FF,$FA
read
push $FF,$FB
read
jump PC_INC
}
#----------------------------------------
PC_INC: { #stack should be on pc_lo
#inc
push 1
add
#pc overflow
push
equal PC_OVERFLOW
add
jump CHECK_INPUT
}
PC_OVERFLOW: {
#pop 2, adding 1 to PC_hi
push 1
add*3
push #restore PC_lo
jump CHECK_INPUT
}
EXIT: {
debug
}
#memory map
#0000 - FFF9 : brainfuck memory
#FFFA : temp byte hi
#FFFB : temp byte lo
#FFFC : input pos hi byte
#FFFD : input pos lo byte
#FFFE : ptr hi byte
#FFFF : ptr lo byte
#interpreter specs:
#cell storage type: unsigned 8-bit
#loop depth: unlimited
#max program length: 2^16
#cells: 2^16 - 6 (65530)