Befunge 98: eof from stdin

231 views Asked by At

what is the expected behaviour for the ~ instruction in befunge-98, when EOF is encountered?

Intuitively, it should place -1 on the stack, but I discovered some variation in this respect:

  • the "intuitive" way is followed by the Befunge-93 JS interpreter. (The below script outputs: "-1 -1 97")
  • Michael Riley's interpreter treats EOF as LF character (ASCII 10) and keeps placing it on top when an extra (non-existent) character is read. (Outputs: "10 10 97")
  • Matti Niemenmaa's interpreter also treats EOF as LF, but keeps waiting for user input when an extra character is read. (Outputs nothing)

Here is the test:

echo "a" | funge test.fg

with test.fg as follows (reads three chars and outputs their codes):

~~~...@

Are there actually interpreters that do treat EOF correctly (i.e. differently from LF) and still support the full befunge-98 specs?

1

There are 1 answers

2
Deewiant On BEST ANSWER

CCBI is following the specification:

In the case of an end-of-file or other file error condition, the & and ~ both act like r.

As can be verified using its built-in tracer/debugger:

$ echo "~~~...@" > test.fg
$ echo "a" > input
$ ccbi --trace test.fg

Instruction: 126 0x7e '~'
Position: (0,0) -- Delta: (1,0) -- Offset: (0,0)
Stack: 0 cell(s): [  -   -   -   -   -   -   -   -] ""
Tick: 0 -- IPs: 1 -- Index/ID: 0/0 -- Stacks: 1 -- Mode:

(Tracer) stdin < input
Successfully set stdin to file 'input'.
(Tracer) s

Instruction: 126 0x7e '~'
Position: (1,0) -- Delta: (1,0) -- Offset: (0,0)
Stack: 1 cell(s): [  -   -   -   -   -   -   -  97] "a"
Tick: 1 -- IPs: 1 -- Index/ID: 0/0 -- Stacks: 1 -- Mode:

(Tracer) s

Instruction: 126 0x7e '~'
Position: (2,0) -- Delta: (1,0) -- Offset: (0,0)
Stack: 2 cell(s): [  -   -   -   -   -   -  97  10] "a^J"
Tick: 2 -- IPs: 1 -- Index/ID: 0/0 -- Stacks: 1 -- Mode:

(Tracer) s

Instruction: 126 0x7e '~'
Position: (1,0) -- Delta: (-1,0) -- Offset: (0,0)
Stack: 2 cell(s): [  -   -   -   -   -   -  97  10] "a^J"
Tick: 3 -- IPs: 1 -- Index/ID: 0/0 -- Stacks: 1 -- Mode:

(Tracer) s

Instruction: 126 0x7e '~'
Position: (2,0) -- Delta: (1,0) -- Offset: (0,0)
Stack: 2 cell(s): [  -   -   -   -   -   -  97  10] "a^J"
Tick: 4 -- IPs: 1 -- Index/ID: 0/0 -- Stacks: 1 -- Mode:

(Tracer) s

Instruction: 126 0x7e '~'
Position: (1,0) -- Delta: (-1,0) -- Offset: (0,0)
Stack: 2 cell(s): [  -   -   -   -   -   -  97  10] "a^J"
Tick: 5 -- IPs: 1 -- Index/ID: 0/0 -- Stacks: 1 -- Mode:

(Tracer) s

Instruction: 126 0x7e '~'
Position: (2,0) -- Delta: (1,0) -- Offset: (0,0)
Stack: 2 cell(s): [  -   -   -   -   -   -  97  10] "a^J"
Tick: 6 -- IPs: 1 -- Index/ID: 0/0 -- Stacks: 1 -- Mode:

On tick 3, the delta has changed from (1,0) to (-1,0), i.e. the ~ instruction on column 3 (position (2,0)) reflected on EOF as expected. After that, the code infloops between the two ~ instructions.

Your code could be amended to check for conformant ~-on-EOF behaviour e.g. like so:

~~#v~...a"tcelfer ton did">:#,_@
   >..a"detcelfer">:#,_@