# Re: [stack] befreaked

## Brent Kerby — 2003-06-28 06:36:51

    > as a first program, i thought i'd attempt an implementation of

    > conway's game of life.

     That would be excellent :-)

    One issue to deal with, though, is that Conway's game of life is

    irreversible. You could implement it in Befreak, but not easily, without

    rapidly running out of memory (since you cannot simply discard past game

    states). You would need to use some method to compress the game history

    (this has certainly been done before with Life, but never in Befreak :-)).

    Of course, there are reversible cellular automata (albeit they probably

    don't look as cool as Life); perhaps it would be easier to implement one of

    those.

     > the way i want to think of this is that

    > there's a rectangular area, infinite in the east and south

    > directions, and instructions for reading and writing cells

    > in the area.

     Befreak has no such instructions, although they could be added without much

    trouble (it would have to XOR, of course, rather than overwrite). I think

    I'd probably use "g" and "p" (get and put) as in Befunge, since "r" and "w"

    are already used for I/O.

    You mentioned the area should be infinite; I think that is a good idea. It

    would fit the system (since the stack is infinite, the data area ought to be

    also). The big question is now, should we just use the code area for the

    data area (as in Befunge), or should it be separate? An advantage of having

    a separate data area would be that the language could then still be

    efficiently compiled, whereas self-modifying code pretty much thwarts any

    such attempts. Of course, there's arguably not much interest in watching a

    compiled Befreak program anyway, but who knows. Supposing the code area is

    used for data, should the code area be extended to be infinite (instead of

    wrapping around)?

    This ties in with another issue that's been on my mind for a while ... I was

    thinking of making a modified version of Befreak in which errors were

    eliminated; i.e., there would be no way to write an invalid Befreak program.

    This requires several changes to the language:

    The biggest issue is that almost all instructions have the potential to

    cause an "empty stack" error; to eliminate this, I was thinking of making

    the stack a fixed size (modifyable of course, by the user, just as the size

    of the code area can be modified). And then, instead of the stack growing

    and shrinking, a stack pointer would simply move up and down through it,

    wrapping around when it reaches one end. Then, empty stack errors are

    impossible, provided the stack has at least size 3 (the maximum number of

    items needed by any instruction).

    Then, the "(" and ")" instructions would move the stack pointer up and down.

    The stack would be initialized as all 0's, and so "(" would still act like

    it was pushing a 0. It would be a typical policy still to ensure that the

    top item is 0 before using ")" even though this would no longer be an error

    if it wasn't (it would just mean the next time we do "(", we'd get something

    other than a 0 as the top item). Programming in this version of Befreak

    would probably be more bug-prone :-)

    The goal is that the new "lenient Befreak" would be backwards-compatible

    with normal Befreak. That is, normal Befreak programs should execute the

    same using lenient Befreak, provided the stack size is set large enough.

    Anyway, several other changes would need to be made: The return stack would

    need to become fixed size and cyclic also. Undefined instructions would

    simply pass as no-ops. The multiply and divide instructions present some

    difficulty: when an error is generated, we could just sweep it under the rug

    and treat the instruction as a no-op, but there's probably a more elegant

    way ...

    So, if that can all be worked out, then the fun thing to do would be to

    generate random programs and watch what they do. In an irreversible

    programming language, a random program would probably just hit a dead-end

    pretty quickly. But with Befreak, I suspect the behavior could be much more

    interesting (for one thing, given the complete finiteness of the system, and

    reversibility, we know that any program will eventually end up exactly where

    it started, although this may takes eons)

     > > The interpreter needs documentation ... Use CTRL-L to load from a file,

    > > CTRL-W to write, CTRL-R to rename... see the source for the rest :-)

     I'm reminded again that I need to write documentation ... But until then, a

    few other important things:

    ALT-RIGHT (or CTRL-F):  Step program forwards one step

    ALT-LEFT  (or CTRL-B):  Step program backwards one step

    ENTER                :  Pause/unpause

    ALT-UP    (or CTRL-P):  Increase speed

    ALT-DOWN  (or CTRL-N):  Decrease speed

    CTRL-X: Cut/Paste

    CTRL-V: Paste (while keeping on the clipboard)

    CTRL-A/CTRL-D: Reflect contents of clipboard

    CTRL-Q/CTRL-E: Rotate contents of clipboard

    I hope your terminal has arrow keys, because you need them to move the

    cursor around. Ahh, and this reminds me, it's set up to compile for DOS (a

    few little quirks of PDCurses, etc.); for UNIX (Ncurses), remove the USEDOS

    define at the top of bfi.h.

    - Brent