Open j4james opened 6 years ago
Ugh, OK. Here is a historical perspective; you might enjoy it.
I don't know how much of this survives, but the original idea for "debugging" a Befunge program (i.e. viewing the playfield, the stack, and the input/output all at the same time) relied a feature of the Amiga shell: redirection to a newly-opened console window. You could give a string like newcon:Title,x,y,w,h
in place of a filename when opening a file; opening that "file" would cause a new console window to be opened, writing to it would cause text to appear in it, reading from it would accept input (buffered keystrokes) from it.
Looking at the code now, I see "stackfile", whose purpose was definitely being able to view the stack in another console window, while the program executed. "inputfile" and "outputfile" would have been similar (though I'm not sure why they couldn't have just been done with file redirection.) I don't see a "playfieldfile", -- so I think the idea was that -d
would display the playfield in the main console ("ANSI debugging") while you would be expected to pass newcon:whatever
s on the command-line to open additional console windows for stack, input, and output.
And note that, under the assumption that you have given an infile
and outfile
, the behaviour in debug mode isn't actually wrong, because the commands test for those first, and if they're present, the input/output goes there.
I am fairly certain the CONSOLE
define was only introduced later, when it was ported to MS-DOS.
I agree something should be done to at least stop it from exhibiting different behaviour in debug mode, I'm just not sure what, yet.
I'll start a branch for this but, at the rate I'm going, it might not make it in for v2.24.
That is really interesting. I'd often wondered why you had all those options for redirecting stuff to a file. It makes a lot more sense now. And if I've understood you correctly, simple file redirection wouldn't have been an option (at least for output), since you'd still need the standard output stream to produce the debugging view.
You can actually get a similar setup working in Linux by outputting to a file which you view with tail -f
in a separate console. Not as elegant as the Amiga implementation, but it does essentially work. I'm not sure if there is an equivalent solution for the input though.
As for the patches, I can understand you wanting to leave this for another time. The more I think about it the more I dislike the approach I was taking. There are just too many edge cases where it doesn't quite work.
OK, so clearly I don't know much about Linux. :) After a bit more investigating, I discovered you can actually redirect both input and output to another terminal simply by specifying the device name as the target filename.
In case this is news to you too, you can get the device name with the tty
command (on the terminal where you want the output to show), which should give you back something like /dev/pts/1
or /dev/tty1
. Then in the terminal where you want to debug, you'd launch the interpreter with something like:
./bef -r /dev/pts/1 -w /dev/pts/1 -d whatever.bf
You'll also probably want to do something in the output terminal to prevent the input being consumed by the shell itself. I just used sleep 60m
, but I suspect there are probably better approaches if you know what you're doing.
Interestingly this also works in the Windows Subsystem for Linux, but I don't think there's an equivalent in the native Windows shell.
I did expect something like that was possible; way back in the circa-1993 era, the university I was attending had an actual multi-user Unix system, and at some point when several of us were logged in at the same time, I looked up what my tty device was, set it world-writeable with chmod 777 /dev/ttyfoo
, and asked other users to write to it. That was fun.
A more sensible approach in the modern world would probably be to redirect output to a named pipe, and then cat that from another terminal. Or open a server socket and have the user telnet or netcat on it.
Either way, if one wanted to try to simulate Amiga's newcon:
, one would need to pop up a terminal window first... which might be possible, but would probably be terminal-program-dependent. gnome-terminal
for example supports an -x
argument which executes a command in the newly-opened terminal.
Anyway, I think this issue will stay in the "Doctor, it hurts when I do this / Well don't do that then" state for 2.24.
If bef is compiled without the CONSOLE define, and you try to debug a program which uses any of the input/output commands, the code won't be interpreted correctly. It's not just that the I/O commands aren't supported - the problem is that they leave the stack in the wrong state. The output commands don't pop anything, and the input commands don't push anything.
As a minimal "fix", you could just include a pop for the output commands, and maybe push -1 for the input commands. In case it's not obvious what I mean, here's a possible patch:
nocon-patch-1.txt
If you want to make a bit more effort though, it is possible to get quite close to the conio implementation using just ANSI escape sequences. I've put together a basic patch showing how that could work:
nocon-patch-2.txt
But that's just a proof-of-concept - you can see that there's a lot of code duplication going on which is in desperate need of refactoring. That level of change I think is best left to you, though, assuming you even what to do anything with this issue.