I want to wrap a simple REPL around my app. It should:
Read lines from the terminal
Parse the lines using a DCG
Process the resulting requests and display the results
Have command-line editing and persistent history
All the bits appear to be in the standard libraries but I’m struggling to find a worked example of how to glue them together. Does anyone have a pointer? Thanks!
Except for the command line editing, this is all pretty specific to your application. Best SWI-Prolog option for commandline editing is library(editline), providing el_wrap/4 and friends. Normally, the terminal is already wrapped though. Then use read_line_to_codes/3 to read lines, add your DCG and process the output thereof.
I have tried to make my own REPL more than once and it turned out every time that I should be using the top level instead. There must be a very good reason not to; for example if the language is syntactically incompatible with (SWI-)Prolog.
Thanks, I found read_line_to_codes, have tinkered with it and I noticed that it seemed to do editing and history, but I wasn’t sure if that was something I could rely on. What’s the relationship between editline and readline? I see mentions of them both in the docs.
I would like to do “backslash continuation”, i.e. if the last char of a line before the CR is \ then read another line. I couldn’t find a way of doing that with the difflist version of read_line_to_codes and strings seem easier to munge than codes, so I was thinking of using read_line to build up a list of strings, collapsing it down to a single string, converting it to codes and then passing it to my DCG.
There is a good reason, it’s that the users are syntactically incompatible with Prolog The language is trivial, just a list of field specifiers and search terms.
Actually I can’t rely on it, all that’s in the command history is whatever was typed into the prolog top level. A call to el_add_history addresses that, thanks for the pointer to editline, I don’t think I would have found it otherwise.
Thanks. I was wondering how to do that.
Bash glues continuation lines into one long line in its history, the SWI top-level also accepts \ continuation lines but preserves the \ + linebreak, That’s ideal but looks like it might be a bit of a faff to do so I’ve just done “glue all the lines together in the history” as it’s trivial to do. Here’s what I ended up with:
They are two line editing libraries. Originally, SWI-Prolog used GNU libreadline, but the license change to BSD makes this a bit cumbersome (you effectively get GPL), so editline was added as alternative. As is, the editline has several advantages, such as a single process can have multiple iistances of editline, but not of readline. This is handy for e.g., the SSH server that is in an extension package.
I don’t expect there to be more than 2-3 lines of input and it’s for interactive use, so I won’t be worrying about any quadratic behaviour in this case.
The last time I touched Prolog was when I was working on the Alvey Project.