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)