-
Notifications
You must be signed in to change notification settings - Fork 1k
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
[Discussion] Accepting multi-line input in a REPL #799
Comments
We could try and look at other implementations of multi line REPLs (see Python) and maybe implement something similar or come up with an even better solution, once I'm done with the bytecode VM I'll try implementing your second proposal, great issue! |
I haven't thought a lot about this yet, but I'd also like to hack in some basic multi-like support. I think one possible way would be to make some changes to the That way, if you could call it while suppressing errors, and then the result is NULL with a final scope that is not 0, then just ignore those suppressed errors and perhaps print a different kind of prompt to indicate that you're in a "continue" mode to the user and let them keep going. Every time they hit enter, just compile their whole input string again (including what failed to compile last time). Whenever the |
I came up with a rough implementation that seems to be working okay. I'm working on a variant of It's hard to post my code here because I've deviated from the book's version a fair bit by now. So I guess I'll just describe my basic approach in case it's useful? First, I needed a way to stop the compiler and runtime errors from printing if the user had typed in a half-completed bit of code and hit enter. Next, I needed a way to detect when the code that the user entered was at least somewhat likely to have been simply incomplete rather than a complete syntactic failure. I ended up solving the second problem in what I think ended up being a pretty simple way. The
In the compiler's
Everywhere that used to check for The end result of all of this is that when the compiler finishes, if the very first error it hit was an So with that problem at least somewhat solved, I had to get back to the first problem of hiding the compiler's errors in this case while not losing them entirely in case the input was completed and I needed to show it. To solve that, I replaced all of the hardcoded In my After the user inputs a string and In all other cases I print whatever So anyway, I know a bunch of code would probably be more clear - but that's the approach I'm using at the moment and it seems to work well enough for now! |
Your solution is very similar to what I've done before too, @BigZaphod. Basically just try to parse the line and if the parser runs out, then assume it's a multi-line input, read another line, and try again. It feels a little hacky, but... REPLs tend to get a little hacky like this in my experience. :) |
@munificent could you add a discussion label to this one as well? Thanks for all the hard work! I just finished Part I, and I've not had this much fun in a long time. |
What I did was simply scrap the repl from the |
@mcfriend99 I would love to see the code where you did that. That sounds like such a cool way to implement the REPL |
if you're interested, my collaborator made a line editing library for the language we're working on (based on clox) here. It's handy because it doesn't require any modification to the parser whatsoever |
Do you mind sharing your implementation? |
I ran into that as soon as I added blocks at the end of chapter 8. This is how I resolved it. In Lox.java:
It simply waits for an empty line before it runs the program. Usually you would not need empty lines in a REPL, but it's a simple solution that works well. |
The Lox REPL as described in the book (and as implemented in clox and jlox) doesn't support multi-line input. The code listings at the end of Chapter 8 and 9 all span multiple lines though, and attempting run them on clox/jlox/my implementation predictably results in parser errors.
I wondered what it would take to implement support for multi-line input in a REPL,
and found that this is one of those classic trade-off style design questions.
I think this would make for an interesting design aside in the book!
This problem fascinated me, so I spent the evening thinking up some solutions.
Here are some simple designs I came up with:
(I'm sure there are other more elegant solutions I haven't thought of...)
The text was updated successfully, but these errors were encountered: