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

KEY or async handling doesn't play nice when compiled #60

Open
rlamorea opened this issue Dec 12, 2023 · 4 comments
Open

KEY or async handling doesn't play nice when compiled #60

rlamorea opened this issue Dec 12, 2023 · 4 comments

Comments

@rlamorea
Copy link

Maybe I'm trying to do too much, but I'm having a very difficult time getting either KEY or bind or bindAsync to work when inside a compiled word.

Example:

: testit
    ." ENTER A KEY "
     KEY
     ." KEY WAS " .
     ;

testit

What ends up happening is that the window.prompt dialog comes up before anything is emitted, so that prompt text is invisible until I enter a key into the prompt dialog, then it all gets dumped out.

The same thing happens with synchronous or asynchronous bindings -- once inside a compiled word, there is no way (seemingly) to get any sort of interactive session that takes users input inside a word definition.

I don't know if it would work to have a type of bind to an async function that would await its return -- and thereby stop the Forth execution until that is done? (Ideally after dumping any emitted content, though that is something that could be done inside the async function itself if necessary).

@remko
Copy link
Owner

remko commented Dec 12, 2023

Hi,

For starters, the web version only flushes output on newline, so the text won't have been sent to the console yet by the time you do a 'KEY'. This could be fixed by flushing any pending output when a KEY is done, which would be an easy fix.

However, even adding a CR to force the flush of the output buffer doesn't seem to solve the problem yet. I think that what's happening is that, although the output has been sent to the DOM, the DOM hasn't re-rendered yet by the time 'KEY' is executed, and the prompt modal is blocking re-rendering. If you try it in the standalone version (which uses real blocking calls for i/o), it works.

I don't think there is a synchronous way to force-redraw the document before opening the prompt.

So, I think the conclusion is that using a synchronous word such as 'KEY' doesn't work well in a browser. I think programs have to be written in a way that they receive input asynchronously.

Making KEY async, and awaiting the output would be nice, but WebAssembly doesn't support suspending execution, although there have been proposals in the past AFAICT (such as this one). An alternative would be to make WAForth itself suspendable and resumable, but this would make things very complicated.

@remko
Copy link
Owner

remko commented Feb 24, 2024

FYI, once JavaScript Promise-integration lands, this can be fixed.

@rlamorea
Copy link
Author

Good to know. I hacked workaround for a simple online Forth sandbox in the meantime.
https://github.com/rlamorea/runforth?tab=readme-ov-file

@farvardin
Copy link

farvardin commented Mar 11, 2024

I was going to open a similar issue until I've found this one.

It seems to be more complicated than I thought. I suppose disabling the JS alert and making the prompt inside the text area (console) wouldn't be sufficient?

I wanted to test a simple menu like that:

DEFER start 

: chapter01
KEY
DUP
114 = IF 
." You've gone to the right. THE END " EXIT
THEN
108 = IF ." You've gone to the left. THE END " EXIT
ELSE
 ." Try again "
 CR
 \ start
 THEN
;

:NONAME \ start
." This is a test " CR
." Do you want to go to the right (r) or to the left (l)? "
chapter01
; IS start

start

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

No branches or pull requests

3 participants