; brainfuck interpreter ; holds the brainfuck tape @tape %%(1<<20) ; brainfuck macros (64-bit words, with anding) ; 1 word macro bf< set [gp0] [gp0#-1] end ; 1 word macro bf> set [gp0] [gp0#1] end ; 4 words macro bf+ push *[gp0] wadd 1 bitand 255 pop *[gp0] end ; 4 words macro bf- push *[gp0] wsub 1 bitand 255 pop *[gp0] end ; 1+? words macro bf. push *[gp0] ; output end macro writeEOF .if OnEOF == 0 ; 1 word set *[gp0] [zero] .elseif OnEOF == -1 ; 1 word set *[gp0] 255 .else OnEOF == 1 ; unchanged - no writeback ; 0 words .endif end ; 6+[0,1]+? words macro bf, ; input dup cmpne EOF cond jmp $$EOF pop *[gp0] jmp $$end $$EOF: drop ; 1 or 0 words writeEOF $$end: end ; 3 words before macro bfLB (here) (dest) push *[gp0] popbool cond 0Eh jmp (dest) label (here) end ; arguments inverted so that they are in the same order as the ; matching bfLB ; 3 words before macro bfRB (dest) (here) push *[gp0] popbool cond jmp (dest) label (here) end macro incr_ua_ptr (ptr) (c_o) bitand 7 (c_o) push (ptr) shll 3 bitor add 1 select ((2^32-1)<<3) [SV] swap bitand 7 end proc regcall bf_interp ; [arg] = ptr to string to interpret ; [gp0] = size of string to interpret ; [jump] = address of this function set [gp1] @tape ; offset of start of tape end