BrainFox implementation -- * Memory Matrix of 65536 elements [X] of 256 pages [Y] default (each base program assumed to start with 16mb allocated) * [X]=0 axis backward compatible with Brainfuck * Independant accumulator * 64k value stack * 64k value string or work area * Multi-value operations are big endian * Default datatype is value (0..255) * Pages can change datatype. * Axises wrap at boundary * Cannot enter negative pages without special instruction ~~[ Legend ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [PC] Program Counter [PC] [A] Accumulator [Z10] [X] X axis pointer [Z00] [Y] Y axis pointer [Z01] [C] RAM Cursor [X][Y] [M] value at RAM cursor ([X][Y]) [D] Data Select, Data at mode cursor [P] Long Parameter [Z14] [I] Next value from STDIN [O] Value bucket to STDOUT [Z] System page (Page -1) [Zx] Offset x in System Page, base 16 [S] Stack (Page -2) [Sx] Offset x in Stack, base 16 [K] Stack pointer [ZFE] [U] String Area (Page -3) [Ux] Offset xx in String Area, base 16 [L] Length of string in area [ZFD] [LS] Location stack [Z0100] [LSP] Location stack pointer [ZFC] [LSxx] Location stack offset ~~[ System page - 256 values, page -1 : System page is multitype ]~~~ 0000 Current X position [X] - int 0001 Current Y position [Y] - int 0002 Current X position #2 [X2] - int 0003 Current Y position #2 [Y2] - int 0004 Current X size (High value) [XS] - int 0005 Current Y size (High value) [YS] - int 0006 Current instruction counter (PC) [PC] - long 0010 Accumulator [A] - variant 0011 Register 1 [R1] - variant 0012 Register 2 [R2] - variant 0013 Register 3 [R3] - variant 0013 Register 4 [R4] - variant 0013 Register 5 [R5] - variant 0013 Register 6 [R6] - variant 0013 Register 7 [R7] - variant 0018 Long parameter [P] - variant 00FC Current location stack pointer - int 00FD Length of String in String Page [L] - long 00FE Items on stack [K] - int 00FF Never used, default temp work area - variant 0100-01FF Location stack - ints ~~[ Stack - 65536 values, page -2 ]~~~~~~~~~~~~~~~~~~~~~~~~~ 0000-FFFF 64k value stack area [T0000..TFFFF] (variants) ~~[ String page - 65536 values, page -3 - String page is always Unicode]~~ 00-FF 256 value string area [S0000..SFFFF] ~~[ Data Types ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 0 Data bit bucket. All operations return 0, and will not change memory or the accumulator. 1 Byte (8 bit) 2 Short Int (16 bit) 3 Char (8 bit) 4 Int (32 bit) 5 Float (32 bit) 6 Double (64 bit) 7 Long (64 bit) 8 Pointer (32-256 bit) 9 Signed Byte (8 bit) A Signed Short(16 bit) B Unicode (64 bit) C Extreme Int (256 bit) D Signed Int (32 bit) E Large float (80 bit) F Signed Long (64 bit) ~~[ Data stores ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 0 Accumulator 1 Register 1 2 Register 2 3 Register 3 4 Register 4 5 Register 5 6 Register 6 7 Register 7 8 RAM Cursor 9 X axis pointer A Y axis pointer F Bit bucket. Returns 0, does not store ~~[ Brainf*ck I compatibility ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Increment value at RAM pointer by one: [M]+1 -> [M] - Decrement [M] by one: [M]-1 -> [M] < Move RAM cursor left: [X]-1 -> [X] > Move RAM cursor right: [X]+1 -> [X] , Read a character from stdin: [I] -> [M] ' Write a character to stdout: [M] -> [O] [ Jump to matching ] if zero: if [M]=00 goto ] ] Jump to matching [ if nonzero: if [M]<>00 goto [ ~~[ Navigation primitives ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { Move memory cursor down one page: [Y]-1 -> [Y] } Move memory cursor up one page: [Y]+1 -> [Y] Z Jump to element 0 on X axis (extreme left): 00 -> [X] V Jump to element 0 on Y axis (extreme bottom): 00 -> [Y] J Jump RAM cursor left/right by the amount at DataSelector (signed): ([X]+[DS]) -> [X] K Jump RAM cursor up/down by the amount at RAM cursor (signed): ([Y]+[DS]) -> [Y] # Push current location onto location stack: [LSP]+4 -> [LSP] : [X] -> [Z(C0+[LSP])] : [Y] -> [Z(C2+[LSP])] $ Pull current location from location stack: [Z(C0+[LSP])] -> [X] : [Z(C2+[LSP])] -> [Y] : [LSP]-4 -> [LSP] ~~[ Accumulator primitives ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ I Push value at cursor into Accumulator: [M]->[A] O Pull value out of Accumulator into current location: [A]->[M] % Swap Accumulator and value at cursor: [A]<->[M] & Increment location by amount in Accumulator: [M]+[A] -> [M] X Jump RAM cursor left/right by the amount in accumulator (signed): ([X]+[A]) -> [X] Y Jump RAM cursor up/down by the amount in accumulator (signed): ([Y]+[A]) -> [Y] ( Jump to matching ( if value at RAM cursor = Accumulator: if [M]=[A] goto ) ) Jump to matching ) if value at RAM cursor <> Accumulator: if [M]<>[A] goto ( ~~[ Data entry primitives ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ \ Store zero at DataSelector: 00 -> [DS] : Move RAM cursor right one and store zero, equal to '>\': [X]+1 -> [X] : 00 -> [M] 0 No operation 1 Add 1 to value at DataSelector, Synonomous with '+': [DS]+1 -> [DS] 2 Add 2: [DS]+2 -> [DS] 3 Add 3: [DS]+3 -> [DS] 4 Add 4: [DS]+4 -> [DS] 5 Add 5: [DS]+5 -> [DS] 6 Add 6: [DS]+6 -> [DS] 7 Add 7: [DS]+7 -> [DS] 8 Add 8: [DS]+8 -> [DS] 9 Add 9: [DS]+9 -> [DS] A Add 10: [DS]+10 -> [DS] B Add 11: [DS]+11 -> [DS] C Add 12: [DS]+12 -> [DS] D Add 13: [DS]+13 -> [DS] E Add 14: [DS]+14 -> [DS] F Add 15: [DS]+15 -> [DS] . Shift left 4 bits (Multiply by 16): [DS]*16 -> [DS] " Shift right 4 bits (Divide by 16): [DS]/16 -> [DS] ~~[ Misc primitives ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ G Load 'Long parameter' (DWORD) with left 4 values and execute 'Special function' at RAM cursor: [M-4]->[Z0C] : [M-3]->[Z0D] : [M-2]->[Z0E] : [M-1]->[Z0F] : [M]->[EXEC] ~~[ I/O primitives ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ H Output value at cursor as hex code: [M]->[TOHEX]->[O] N Output value at cursor as type: [M]->[TOINT]->[O] R Read [A] values from STDIN and put them at the RAM cursor: [I00]..[I([A]-1)] -> [M00]..[M([A]-1)] W Write [A] values at the RAM cursor to STDOUT: [M00]..[M([A]-1)] -> [O00]..[O([A]-1)] ~~[ Memory movement ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ M Move (copy) [A] values at RAM cursor to RAM Cursor #2: [M00]..[M([A]-1)] -> [M2(00)]..[M2([A]-1)] P SwaP [A] values at RAM cursor to [C]: [M00]..[M([A]-1)] <-> [M2(00)]..[M2([A]-1])] ~~[ String primitives ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ S Place RAM cursor into String Area: [S]->[Y] : 00 -> [X] T Push [A] values from here into String area: [M00]..[M([A]-1)] -> [S00]..[S([A]-1)] : [A]->[L] Q Pull [L] values from string area to this location: [S00]..[S([L]-1)] -> [M00]..[M([L]-1)] : [L]->[A] ~~[ System Page ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ U Place RAM cursor into System Page: [Z]->[Y] : -1 -> [X] = Set offset [A] in System Page to value at RAM cursor: [M]->[Z(A)] ; Get offset [A] in System Page to value at RAM cursor: [Z(A)]->[M] ~~[ Stack primitives ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @ Pop one value off the stack into the value at the RAM cursor: [T(K)] -> [M] : [K]-1 -> [K] ! Push value at RAM Cursor onto the stack: [K]+1 -> [K] : [M] -> [T(K)] * Duplicate value at top of stack into the value at RAM cursor: [T(K)] -> [M] ^ Replace value at top of stack with value at RAM cursor: [M] -> [T(K)] L Place RAM cursor inside the stack page: [S]->[Y] : 00 -> [X] | Pop one value off the stack into the accumulator: [T(K)] -> [A] : [K]-1 -> [K] _ Push value in accumulator onto the stack: [K]+1 -> [K] : [A] -> [T(K)] ~~[ Documentation ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ / Ignore everything after this until newline or next '/' ~~[ Special functions ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 00 Halt with returncode stored in accumulator 01 Change current page to BYTE datatype 02 Change current page to WORD datatype (16 bit int) 03 Change current page to CHAR datatype (8 bit, but outputs as ASCII) 04 Change current page to DWORD datatype (32 bit int) 05 Change current page to FLOAT datatype (32 bit float) 06 Change current page to UNICODE datatype (Each cell can store a single unicode character) 07 Toggle signnedness of current page 80 Load matrix from file (if [7F]>00 then use filename in buffer, else use matrix.bfox) 81 Dump matrix to file (if [7F]>00 then use filename in buffer, else use matrix.bfox) FE Resize the matrix, preserving as much existing data as possible. FF Kill and resize matrix, filling it with value in accumulator ~~[ Example proggy ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ / Resize matrix to 1x1, this program only requires one value of RAM 0'8i0'0= 0'9i0'1= 0'Ai0'0= 0'Bi0'1= F'FG / Now write HELLO WORLD! / H E L L O SP W O R L D ! CR LF 4.8'4.5'4.C'4.C'4.F'2.0'5.7'4.F'5.2'4.C'4.4'2.1'0.D'0.A' / Halt 0'0ig