EndBASIC 0.2.0 is here

A couple of weeks ago, I announced EndBASIC: a simple BASIC language interpreter written in Rust with a goal to provide an environment for teaching my kids how to code. That first release provided what-I-think-is a robust interpreter, but that was about it: the language features were still minimal and the interactive features were non-existent.

Well, EndBASIC 0.2.0 is here and things are changing! It’s still far from the vision I want to reach, but it’s slowly moving towards that direction. I’m a bit less satisfied about the robustness of these new features compared to those in the core language, but that’s OK: they will have to change significantly or maybe even be dropped entirely, so no harm done.

So, what’s new? Let’s take a little tour.

The REPL

The first thing is a REPL, which is where all action will take place. To start it up, simply run endbasic and be greeted by:

If we follow the instructions and type HELP, we can obtain interactive information about all available commands, which is a good way to see what’s available:

Ready
HELP
This is EndBASIC 0.2.0.
CLEAR Clears all variables to restore initial state.
DIR Displays the list of files on disk.
EDIT Edits the stored program.
HELP Prints interactive help.
INPUT Obtains user input from the console.
LIST Lists the contents of the stored program.
LOAD Loads the given program.
NEW Clears the stored program from memory.
PRINT Prints a message to the console.
RENUM Reassigns line numbers to make them all multiples of ten.
RUN Runs the stored program.
SAVE Saves the current program in memory to the given filename.
Type HELP followed by a command name for details on that command.
Press CTRL+D to exit.
Ready
⎕

Quite a bit of stuff! We can also type HELP followed by any command name, like HELP EDIT, to obtain detailed information about each command. I’m not going to bore you with that here, but one of the integration tests dumps them all for validation.

Oh, by the way: note that all input happens via rustyline so you can use a multitude of keystrokes to edit the entered command. You can even navigate history.

Anyway. Seeing a raw list of commands may still make it hard to imagine what is possible, so let’s take a look at them as groups.

Line-oriented code editor

Of these commands, the first group to highlight is a line-oriented code editor inspired by Locomotive BASIC’s interface. This is a rudimentary code editor by any standards, but it is sufficient for now (but definitely not enough for the future).

Now… I have to clarify that line numbers are meaningless here: they are just a clutch to support this rudimentary code editing experience. The language does not (and will not) implement GOTO (which, ironically, prevents me from implementing the typical “print hello and go to 10” code sample used for teaching).

Finally, the CLEAR and NEW commands are slightly related here. The first lets us clear the in-memory state of the interpreter without clearing the program (that is, it wipes all variables); and the second lets us clear that same stuff plus the stored program.

Program storage

Alright, so now we know how to enter programs in the memory of the REPL. But what do we do with them once we are done? Will they be lost? No! We can use the SAVE command to persist them to disk. Let’s create two programs:

These file operations all work on a single directory that, by default, is ~/Documents/endbasic/ but can be customized with the --programs-dir flag at startup time. You should not be able to escape that directory from within the interpreter, but of course you can use a separate code editor on the files in that directory if you so wish.

Other changes

Aside from the REPL and everything related to it, the language itself has also seen some improvements as shown in the release notes. These include support for : as a statement delimiter, _ characters in identifiers, a better INPUT command, and a MOD operator.

Separately… maybe you want a scripting language for your Rust program? I’ve put some effort in this directory by making the core interpreter minimal, which should allow embedding with full control of what the executed scripts can do. Even INPUT and PRINT are optional. The examples subdirectory shows how you might go about this, but be aware that I make zero promises about the API for now. I should be posting on this topic soon though.

For 0.3.0, the major thing I’m planning is a full-screen command-line application and a bunch of screen manipulation commands (think CLS, COLOR, and LOCATE). These will take quite a bit of fiddling to get right, especially considering that, for some reason, I want to support Windows. Crossterm looks promising in this regard though. I have no idea how I’ll go about integration testing though.

And with that, go cargo install endbasic while it’s fresh on any macOS, Linux, or Windows system!