Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing issues with swap command and character input #1

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

anthonykozar
Copy link

@anthonykozar anthonykozar commented Nov 27, 2021

I found multiple problems with this implementation of Gaot++ while using it from TryItOnline. The first is that the swap command doesn't swap the top two entries on the stack. It pops them off and then pushes them back on in the same order they were in before. The following program demonstrates this bug.

baa baaa
bleeeeeeeeeeeeeet
bleeeeeeeeet bleeeeeeeeet

The program pushes 1 and then 2 onto the stack, swaps them, and then outputs the top two entries of the stack as numbers. It should produce the output "12" but instead gives "21".

The second issue is that character input throws an exception whenever standard input is not connected to a terminal. This affects Gaot++ programs running on TryItOnline or running from a commandline with input redirection. This simple program should read a single character from stdin and output it as a character:

bleeeeeeeeeeeet bleeeeeeeeeet

On TryItOnline, it produces this exception:

Traceback (most recent call last):
  File "/opt/gaotpp/gaot_plus_plus.py", line 136, in <module>
    main()
  File "/opt/gaotpp/gaot_plus_plus.py", line 133, in main
    gaot.run(gaot.get_code())
  File "/opt/gaotpp/gaot_plus_plus.py", line 50, in run
    self.commands[n-2]()
  File "/opt/gaotpp/gaot_plus_plus.py", line 113, in _getchar
    _ = ord(getch())
  File "/opt/gaotpp/getch.py", line 24, in __call__
    return self.impl()
  File "/opt/gaotpp/getch.py", line 34, in __call__
    old_settings = termios.tcgetattr(fd)
termios.error: (25, 'Inappropriate ioctl for device')

This pull request resolves both of these issues. With these patches, the "cat" program example from esolangs.org can be used to copy the input to the output as expected. (Unless the input contains an embedded NULL character. See the notes on the last commit).

Dec. 8: I've added 3 more commits to this pull request that fix additional bugs. The first commit halts a Gaot++ program when the instruction pointer becomes negative which could happen if the direction of the instruction pointer was reversed and then went past the beginning of the program. Since the interpreter halts a program that reaches the end of its code, it seemed to make sense to halt when in reverse too.

The next two commits fix problems with the rotate command. (Try "baa baaa bleeeeeeeeeeeeeeeet" on TryItOnline). The code previously referenced an undefined variable which produced the exception below and it tried to concatenate a list and an integer which is not allowed. I also made sure that rotate does nothing when the stack is empty.

Traceback (most recent call last):
  File "/opt/gaotpp/gaot_plus_plus.py", line 136, in <module>
    main()
  File "/opt/gaotpp/gaot_plus_plus.py", line 133, in main
    gaot.run(gaot.get_code())
  File "/opt/gaotpp/gaot_plus_plus.py", line 50, in run
    self.commands[n-2]()
  File "/opt/gaotpp/gaot_plus_plus.py", line 130, in _rotate_stack
    self.stack = Stack(x[1:]+x[0])
NameError: global name 'x' is not defined

If you have any questions, please let me know. Thanks!

Anthony Kozar

…rs when piping or redirecting input to the interpreter.
Reverted changes to getch.py. Only use getch() if stdin is a tty. This fixes an exception that occurs when piping or redirecting input to the interpreter. gaot_plus_plus.py seems like a better place to put this logic since the purpose of the getch module is to provide unbuffered input from a terminal.

There is a small difference in the behavior of these two solutions when running a simple "cat" program with stdin redirected from a file. The former stops reading from the input file if an EOF byte (0x04) is encountered. The new solution stops reading if a null byte (0x00) is encountered. I don't think there is a solution for copying arbitrary binary files since Gaot++ doesn't provide a way to detect the true end of a file. (If stdin is a tty, then control-D still causes the cat program to exit).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant