The computers of today are too complex to understand. To the uninitiated, they feel overwhelming. They take a long time to boot. They offer cluttered interfaces with lots of icons, buttons, and options. They are built on dozens of layers of abstraction. And because of these reasons, they feel fragile and not something that can be experimented with.

If you want to learn to code today, you face a steep learning curve. You need to understand how to open and operate an editor. You need to understand the file system so that you can navigate to the files you create. And you need to understand the basics of the command line to maybe-compile and run whatever you wrote in the editor. This is tedious and incurs a ton of mental overhead just to get started.

But it doesn’t have to be this way. In fact, it didn’t use to be this way.

If we look back to the 1980s, computing was much more approachable and discoverable—even if it did not look like so. I have pretty fond memories of my Amstrad CPC 6128 and its Locomotive BASIC 1.1 interface. The experience offered by that computer was common back in the day but unique for today’s standards: the computer booted and was ready to accept commands in a couple of seconds; the computer was resilient to mistakes thanks to the system being stored in ROM; and you could control the full computer from the built-in language. Changing colors, drawing figures, playing sounds… were all at your fingertips. And once you learned a few commands on the command line, stitching them together to form full-fledged programs was a breeze.

With the move to a PC and MS-DOS a few years later, the essence of this experience was already lost: booting was slower; the computer could be “damaged” by modifying the wrong files; and the command line’s interface didn’t match the language of the programs you wrote. Sure, you could write batch programs, but that language was very limiting. That said, MS-DOS was still reasonably simple and shipped with the QBASIC integrated environment, which gave you all you needed to develop programs quickly.

Fast-forward to 2021. For most, computers have become content consumption devices. But the possibility of excitement is still there. I set up a Raspberry Pi that booted directly into DOSBox with QuickBASIC 4.5 and I could witness how my kids showed a different kind of interest in the machine than they had had before just with games. I only had to type a bunch of PRINT and COLOR commands to make them want to try stuff on their own. So I thought… this is cool, but it’s awkward to be confined to such an old environment. How hard would it be to bring such an experience to the modern era? Hence “E. and D.‘s BASIC” was born. Or, simply put, EndBASIC.

EndBASIC is a modern take at implementing an integrated environment that offers instant gratification to the user/learner/programmer. The environment and the language are intentionally modeled after the experience that computers offered back in the 1980s—but don’t assume that those interfaces were too limiting: simplicity is powerful. EndBASIC is modern because the environment targets the web for ease of access, allows interacting with the Raspberry Pi as a learning device, and integrates with a cloud service for fun file sharing. Furthermore, EndBASIC is fully written in Rust, so whenever you are ready to make the leap into a “real language”, you can poke into its internals and tweak it to your own needs.

With that, I hope you enjoy EndBASIC as much as I have enjoyed creating it. I do not expect you to write shiny new programs in a language that is considered a dead end by most. No. My hope is that you use EndBASIC to learn or teach the foundations of programming and computing in an environment that is fun to interact with and that is tolerant of mistakes. Because, if you truly master the foundations, the specifics of the language or the operating system won’t matter as much.

Thank you for reading!

EndBASIC 0.4.0 showing its interactive editor, the built-in tour, and the built-in "guess the number" game. Video recorded on 2020-12-25.

BASIC interpreter

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.

INPUT "Did you ever experience BASIC (true/false)"; answer?
IF answer? THEN
    PRINT "Great; you are in for a treat!"
    PRINT "Oh noes; try today?"

EndBASIC’s primary goal is to offer a simplified and restricted environment to learn the foundations of programming and focuses on features that can quickly reward the learner. These features include things like a built-in text editor, commands to manipulate the screen, commands to interact with shared files, and even commands to interact with the hardware of a Raspberry Pi. Implementing this kind of features has priority over others such as performance or a much richer language.

DOS-like environment

EndBASIC’s command line features a set of commands to interact with files from various sources, and these commands resemble the interface exposed by MS-DOS. This is similar to old-style BASIC machines, as the Locomotive BASIC previously mentioned offered access to the built-in AMSDOS system for file manipulation.

Here is a sample session:


    Working directory: LOCAL:/
    System location: /Users/jmmv/Documents/endbasic/


    Name      Target
    DEMOS     demos://
    LOCAL     file:///Users/jmmv/Documents/endbasic
    MEMORY    memory://

    3 drive(s)


    Directory of DEMOS:/

    Modified              Size    Name
    2021-02-14 15:29      2152    GPIO.BAS
    2020-12-23 03:12      2097    GUESS.BAS
    2020-12-22 14:20       651    HELLO.BAS
    2020-12-24 01:52      8791    TOUR.BAS

    4 file(s), 13691 bytes
    0 of 13691 bytes free

What's your name? The Demo
Hello, The Demo!

Web and cloud interfaces

EndBASIC is a web-native application that runs locally on your browser thanks to WASM. This allows you to enjoy the environment without having to install anything on your computer, and also lets you run the interpreter on mobile devices.

Furthermore, EndBASIC can optionally connect to a cloud service that allows sharing files across users. The goal of the cloud service is to let you share your creations with friends and family, and even with the whole world if you choose to make those creations public.

Support for groups and domains could be added later if there was any interest. This type of ACLs would allow sharing files, say between a group of students and a teacher for grading purposes, or from a teacher to their students to hand out class assignments.

Here is a sample session:

LOGIN "learner"
Password: *********

Thank you for signing up, learner! I can't wait to see what you build around here.

The following users have shared some content with you:


Go forth and explore! You can mount their drives with the MOUNT command.
-----  END SERVER MOTD  -----

MOUNT "X", "cloud://jmmv"
DIR "X:"

    Directory of X:/

    Modified              Size    Name
    2021-07-02 04:10        89    thanks.bas

    1 file(s), 89 bytes

LOAD "X:/thanks.bas"
1 | PRINT "You found a shared file. Congratulations!"
2 | PRINT "Thanks for playing with this."
3 |

Hardware interaction

EndBASIC can also run as a local application on your machine and it is currently tested on Linux, macOS, and Windows (but also is known to work on FreeBSD, for example). You’ll find prebuilt binaries for these platforms in the downloads page. For the most part, the web and local interfaces expose the exact same features—with exceptions around hardware management.

For example, if EndBASIC is installed on a Raspberry Pi, it is able to control GPIO-attached devices, allowing the user to control simple pieces of hardware.

EndBASIC 0.6.0 running on a Raspberry Pi and showing a built-in demo program that waits for a button press and blinks an LED. Photo taken on 2021-02-15.

Open and embeddable

EndBASIC is built entirely with Rust and the core language has been designed to be minimal and free of any heavy dependencies. The goal is to let you embed the interpreter into your own programs and precisely control which commands to expose to the interpreted code. As a very simplified example:

async fn parse_sample_input_and_extract_values() {
    const INPUT: &str = r#"

        foo_value = 123
        enable_bar = (foo_value > 122)
        'enable_baz = "this is commented out"

    let mut machine = Machine::default();
    machine.exec(&mut INPUT.as_bytes())).await.unwrap();

    println!("foo_value is {}", machine.get_var_as_int("foo_value").unwrap());
    println!("enable_bar is {}", machine.get_var_as_bool("enable_bar").unwrap());

You can also define your own native commands and functions in Rust and expose them to the interpreter, thus using EndBASIC to script powerful Rust native code.

Oh, and by the way: EndBASIC is also free software. Check it out in GitHub!