adding proper eof handling#112
Conversation
|
Hi @dallinjdahl, thanks for the contribution! But this is not the right place for the change, because that error is port-specific, and the code in this repository must be portable. Which port were you working with that requires this change? The right place for the fix is there, by overriding |
| (/. E (toplevel-display-exception E))) | ||
| (loop))) | ||
| (trap-error (do (read-evaluate-print) (loop)) | ||
| (/. E (toplevel-exception (error-to-string E) loop))))) |
There was a problem hiding this comment.
Passing the loop symbol and then invoking it as (C) is not portable, will work with some platforms (Common Lisp for example), but not most. You could pass (freeze loop) and then (thaw C), but many platforms will not be able to handle the tail-recursion correctly in that case.
But you could do something like:
(define is-eof-error?
E -> (= (error-to-string E) "error: empty stream"))
(define loop
-> (let Init (initialise_environment)
Prompt (prompt)
Continue (trap-error
(do (read-evaluate-print) true)
(/. E (if (is-eof-error? E)
false
(do (toplevel-display-exception E)
true))))
(if Continue
(loop)
skip)))There was a problem hiding this comment.
What about passing (fn loop) instead? It seems like a natural use of recursion with higher order functions, but maybe I'm misunderstanding the issue.
There was a problem hiding this comment.
(fn loop) could work in some ports, but sadly it is not something you can depend on for portable code.
|
The same error occurs with both the SBCL and shen-scheme ports, so I thought it would be the language-defined error for an end of file, but if it truly is port-specific, then feel-free to close this PR. The issue is that every other interpreter I've used on unix-like systems handles eof by terminating gracefully, while currently the shen top-level just spins until you call the port-specific exit command. This avoids that in general by exiting the loop portably, rather than shelling out to the underlying port. |
|
I guess TBoS (at least v4) doesn't mention any way to determine the end of a stream, so if there's really no portable way to guard against reading the end besides reading it into a string, then this is definitely misplaced. |
|
@dallinjdahl not sure about the SBCL port because it doesn't use this version of the kernel, so it doesn't have the hooks. But for Shen/Scheme you can handle this in the override for If the exception is the EOF exception, you can call the native Other than converting the exception to a string, I think you should be able to also use the native check |
Yes, there is no portable way. Anything related to I/O or system operations in the Shen kernel is limited to the very bare minimum. |
This slightly refactors the toplevel to end on eof, resolving complaints about exiting shen and fitting it into a more unix-friendly environment. Care is taken to ensure that the tail-recursive nature of the loop is maintained.