Talk:Brainmaker
The page reads:
! Jump to matching ] (so this command skips other jump points until it reaches the end of the current "loop") & Jump to previous [
Shouldn't the second line be "Jump to matching [", in a way similar to the first? If it really is a jump to the previous [
, then the encoding of brainfuck (below in the page) is wrong, because it doesn't handle nested loops correctly.
Something else that troubles me: different implementations or derivatives of brainfuck use different conventions:
- are the cells unbounded?
- do the increment and decrement instructions wrap around?
- how is end of file handled by the input instruction?
- what does < do when the pointer is on the first cell, is it a no-op or is the tape unbounded in both directions?
Those "details" are ignored in your description of Brainmaker. I think they shouldn't, because Brainmaker is precisely about describing brainfuck-derivatives...
- for example, if you say that by default
,
on eof is a no-op, then you can encode a brainfuck language where,
on eof sets the current cell to 0 (by defining,
to[-],
). - another example: if cells by default hold signed unbounded integers, and if the tape is unbounded in both directions, then a "regular" brainfuck can be encoded by having guards on + and - to check when the value goes outside the range 0-255, and guards on < to check if the data pointer doesn't go to the left (for instance placing a -1 in the cell to the left of the first cell).
Note that Brainmaker could also include some code to be executed at the beginning and end of a program in the described language; for instance if there need to be a particular set-up for the tape before execution starts (like the -1 in the previous example), or if the described language's only means of output is the final state of its tape. --Koen (talk) 22:27, 7 October 2012 (UTC)
nameless stack-based language
I think there are problems with the "simple stack-based language": the count of >
and <
seems to be wrong. For instance, the add instruction is just '[<+>-]
, which has the effect to add the top element to the second element, and to replace the top element with 0. I think the description "add top stack elements together" should mean "add top element to second element, then pop top element", so the code should be '[<+>-]<
. Similarly, the code for the swap instruction is '[>+<-]<'[>+<-]>>'[<<+>>-]
: the >
and <
are balanced in every loop, but outside the loops there is only one <
for two >
, which means this will push an extra zero in addition to swapping the top two elements. The multiply instruction '[>+<-]<'[%'[>>+<<-]>>>'+]
is even worse: if the stack is ... x y
, the first loop sets it to ... x 0 y
with the pointer on the 0; then one <
sets the pointer to the x; then the % instruction creates a mess, because the code for %
assumes there is a 0 in each of the the two cells just after the top element, which is not the case here since there is y in the second cell after the top.
Here is a proposed revision for that language:
> : > // push a new zero (CODE) [CODE] : [?!CODE&] // brainfuck-style loop < : '[-]< // pop and discard top element % : '[->+>+<<]>>'[-<<+>>]< // duplicate top element @ : '[->+<]<'[->+<]>>'[-<<+>>]< // swap top two elements + : '[-<+>]< // pop y, pop x, push x+y - : '[-<->]< // pop y, pop x, push x-y * : <'[->>+<<]>'[->'[->+<<<+>>]>'[-<+>]<<]>'[-]< // pop y, pop x, push x*y . : .[-]< // pop top char and output it , : >, // push a char from input 0 : >++++++++++* 1 : 0+ // any digit d: pop x, push 10*x+d 2 : 1+ // thus the code >n where n is decimal 3 : 2+ // pushes the number n to the stack 4 : 3+ 5 : 4+ 6 : 5+ 7 : 6+ 8 : 7+ 9 : 8+