If there weren't enough BASIC language interpreters out there (with some already written in Rust)... I give you one more!
Quoting EndBASIC's README:
EndBASIC is an interpreter for a BASIC-like language and is inspired by Amstrad's Locomotive BASIC 1.1 and Microsoft's QuickBASIC 4.5. Like the former, EndBASIC intends to provide an interactive environment that seamlessly merges coding with immediate visual feedback. Like the latter, EndBASIC offers higher-level programming constructs and strong typing. The main idea behind EndBASIC is to provide a playground for learning the foundations of programming in a simplified environment.
EndBASIC is written in Rust. The parser and interpreter's primary goal is to be readable and easy to modify. A secondary goal is to make the core minimal, extensible, and configurable. Performance is not a goal right now, though it likely won't disappoint.
EndBASIC is free software under the Apache 2.0 License.
I'm writing this as a tool to teach programming to my young kids. But, to be honest, I have had a lot of fun writing this in Rust (my second project in this language). To reach that educational goal, though, there are a lot of missing features that I'll be adding soon like "fun" commands to play with, a REPL, and probably some form of graphics support.
Where will this go? I don't know yet.
But for now, please enjoy! You can find the project and some more details in these links:
Nice work, and thanks for doing a little write-up as well! Each library has its own story, and I these sorts of "announcement" articles are always an interesting read.
I had a skim through the source code and it looks like you're handling errors by using failure::Fallible to bail out at the first problem. More elaborate diagnostics (e.g. report all errors or point at where the error occurred) may be useful if this is intended as a learning tool for others.
To implement error reporting and nice diagnostics I'd recommend codespan crate and its accompanying codespan_reporting. I've used it in several tools to provide users with nice user-friendly error messages that point at the offending line and provide explanation/suggestions. Most well-used of these is mdbook-linkcheck, and I know it powers at least twoprogramming languages.
It depends on how familiar you are with parsers, but during the parsing step this is usually implemented by having some dummy Error node. When a production fails you can substitute the Error node, emit a diagnostic, and try to resume parsing from some reliable checkpoint (e.g. say a Rust parser can't parse an impl block, skip until the closing } and try to parse the other items in the file).
Thanks for looking and for the suggestions, Michael.
Yeah, this was also brought up in a question I asked a few days ago (Ergonomics of a lexer and iterators). At that point, I spent some time removing the use of fallible from the reader and the lexer, but then stopped there given that, before changing semantics, I wanted to get the whole thing fully tested (even if with suboptimal behavior).
So yes, I want to make error reporting better (which will be necessary for recoverability in the REPL). It currently sucks right now I think I'd also want to avoid using fallible completely, but we'll see how far I take that.
Have a look at some of the stuff coming out of rust-analyzer, they're solving pretty much the same problem but at a much larger scale. matklad (one of the main contributors towards rust-analyzer) wrote a really interesting article on implementing fallible parsers. Their use case is quite niche (a super low latency IDE plugin which can re-evaluate while you're midway through typing a word), but it's still quite applicable.