Giter Site home page Giter Site logo

endbasic / endbasic Goto Github PK

View Code? Open in Web Editor NEW
298.0 10.0 16.0 5.23 MB

BASIC environment with a REPL, a web interface, a graphical console, and RPi support written in Rust

Home Page: https://www.endbasic.dev/

License: Apache License 2.0

Rust 96.73% Shell 0.14% HTML 0.09% JavaScript 0.46% CSS 0.16% BASIC 2.07% FreeBasic 0.04% Makefile 0.12% Visual Basic 6.0 0.17%
programming-language basic interpreter parser scripting-language learn-to-code raspberry-pi gpio language rust

endbasic's Introduction

The EndBASIC programming language

Test Build release Release checks Deploy to staging Deploy to release

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.

EndBASIC offers a simplified and restricted environment to learn the foundations of programming and focuses on features that can quickly reward the programmer. These features include things like a built-in text editor, commands to render graphics, and 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.

EndBASIC is written in Rust and runs both on the web and locally on a variety of operating systems and platforms, including macOS, Windows, and Linux.

EndBASIC is free software under the Apache 2.0 License.

The latest version of EndBASIC is 0.10.0 and was released on 2022-12-27.

Quick start on the web

Open EndBASIC in your browser by visiting:

https://repl.endbasic.dev/

Or go the project's website at:

https://www.endbasic.dev/

The web interpreter should work on all major desktop browsers as well as mobile devices (with some small known issues on Android).

The web interpreter runs fully locally: any programs you write are persisted in your browser's local storage by default. That said, you can choose to sign up for the cloud service and upload your programs to share them with the world.

Quick start on your machine

Visit the release page to download prebuilt binaries. Once downloaded, unpack the archive and run the endbasic binary to get started.

Be aware that the binaries are not signed right now so it can be difficult to get these to run on Windows and macOS.

The binary releases are built with the recommended settings: they all include graphics support, and the builds for the Raspberry Pi include support for its hardware. To use the graphics console, you will need to launch the binary using one of these forms:

endbasic --console=graphics            # Default console size, windowed.
endbasic --console=graphics:800x600    # Custom resolution.
endbasic --console=graphics:800x600fs  # Custom resolution, full screen.
endbasic --console=graphics:fs         # Desktop resolution, full screen.

Building from source

Of course, you can also build and install EndBASIC from source by running the following command (assuming you have a Rust toolchain installed):

cargo install endbasic

The above will fetch EndBASIC from https://crates.io/, build it with default settings, and then install the resulting binary under ~/.cargo/bin/.

If you want to enable graphics support (recommended), you will first have to install the SDL2 and SDL2_ttf libraries. Follow these steps depending on the platform you are on:

# On Debian-based systems:
sudo apt install libsdl2-dev libsdl2-ttf-dev
cargo install --features=sdl endbasic

# On FreeBSD systems:
sudo pkg install sdl2 sdl2_ttf
cargo install --features=sdl endbasic

# On macOS systems with Homebrew:
brew install sdl2 sdl2_ttf
cargo install --features=sdl endbasic

# On Windows systems, this is tricky.  The easiest way is to clone this
# repository and then do the following from PowerShell:
.\.github\workflows\setup-sdl.ps1
cargo build --release --features=sdl endbasic

If you want to enable support for the Raspberry Pi hardware (along with the recommended graphics features), do this on the Raspberry Pi itself:

sudo apt install libsdl2-dev libsdl2-ttf-dev
cargo install --features=rpi,sdl endbasic

More information

Refer to the User's Manual for information on how to get started with EndBASIC.

Type HELP within the interpreter to access the Reference Manual.

The following documents provide more information about the structure of this repository:

Why EndBASIC?

EndBASIC started as part of my desire to teach programming to my own kids. I remember learning programming on an old Amstrad CPC 6128: the experience was unique in the sense that every command had immediate effect. Changing colors, drawing on the screen, or playing sounds were just a few keystrokes away after booting the computer, without the need to deal with separate editors and terminals. I've noticed a similar excitement in my kids when showing this to them via an emulator, so I thought I would replicate this in a more modern fashion. And here we are.

Because of this inspiration, EndBASIC's name stands for "E. and D.'s BASIC" following my kids first name initials.

endbasic's People

Contributors

dependabot[bot] avatar jmmv avatar zenria avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

endbasic's Issues

UTF-8 support - repl/editor panicking

Hi, there are a couple of issue with current utf-8 support eg. When in repl or in editor, I type:

print "é"

When I type the last double quote, endbasic panics:

philou@siderant ~ $ RUST_BACKTRACE=1 endbasic --console=graphics                                                                                                     101 [11:19:57]
thread 'main' panicked at 'byte index 8 is not a char boundary; it is inside 'é' (bytes 7..9) of `print "é`', /Users/philou/.cargo/registry/src/github.com-1ecc6299db9ec823/endbasic-std-0.8.1/src/console/readline.rs:179:39
stack backtrace:
   0: rust_begin_unwind
             at /rustc/9d1b2106e23b1abd32fce1f17267604a5102f57a/library/std/src/panicking.rs:498:5
   1: core::panicking::panic_fmt
             at /rustc/9d1b2106e23b1abd32fce1f17267604a5102f57a/library/core/src/panicking.rs:116:14
   2: core::str::slice_error_fail
   3: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
   4: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
   5: tokio::park::thread::CachedParkThread::block_on
   6: tokio::runtime::thread_pool::ThreadPool::block_on
   7: tokio::runtime::Runtime::block_on
   8: endbasic::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

This also happens if I type é and then backspace. With a similar error:

thread 'main' panicked at 'byte index 1 is not a char boundary; it is inside 'é' (bytes 0..2) of `é`', /Users/philou/.cargo/registry/src/github.com-1ecc6299db9ec823/endbasic-std-0.8.1/src/console/readline.rs:144:39

Can't type " in the interpreter

I have a keyboard with the US international layout and cannot type " in the interpreter. " requires shift + the ' key to be typed.

Build ID: 0.9.0 built from d7a7c72 on 2022-06-05

Why term.onKey?

Congrats, this is a really nice example how to get cmdline tools into web realms with wasm and xterm.js. The blocking I/O is really a showstopper for easy ports of most apps, also the wasm env still lacks several POSIX layers, but I guess this will change over time (emscripten already shims FS parts for C apps).

On thing that bugs me in xterm.js snippets seen all over the internet - is there a specific reason to use onKey handler with xterm.js instead of onData? The latter would give you a character stream as on stdin of a console app (on a raw terminal, thus still lacking echoing, erase - things done by the missing pty). onData would also handle c&p and meta keys correctly, while onKey is on a very raw edge.

Add command to query all variables

We should have some introspection commands to query the state of the machine. An obvious one that comes to mind is a way to dump all currently-defined variables. Maybe something as simple as adding a VARS command that prints a table.

No Line Numbers in Editor

Build ID: 0.9.0 built from d7a7c72 on 2022-06-05

I use several tools like (GotoMeeting or Zoom) to discuss code with remote friends.

Some of these tools don't show where my mouse pointer is on the screen.

It is very useful to have line numbers on the screen when discussing code.
I honestly don't care if they are numbers or just letters, AA AB AC etc.

Also, since the LIST command doesn't allow line numbers, I have to use the editor to see any code that spans over a single page, as the console doesn't have any ability to "scroll back"

Thank you for consideration of this issue.

Dave Whitten (7-June-2022)
713-870-3834

Configure cargo-deny to tame dependencies

I recently came across the cargo-deny tool, which can be used to keep dependencies under control. I think they have grown quite a bit and, by looking at Cargo.lock there seem to be some duplicates, so it seems like using this tool in CI would be very useful.

Support user-defined functions

A major deficiency of the language right now is the inability to define custom functions. This makes it hard to write almost any kind of program (except for the most trivial ones). Unsure how these should look like, but I wouldn't go too "retro" on them. Maybe look at Visual Basic.

Installation Instructions

Hi jmmv,

I followed your instructions in the README, but I get the following error when using cargo install endbasic:

   Compiling endbasic-core v0.5.0
   Compiling endbasic-std v0.5.0
   Compiling endbasic v0.5.0
    Finished release [optimized] target(s) in 15.05s
error: no binaries are available for install using the selected features

The binary endbasic was not dropped into $HOME/.cargo/bin. I know I am missing something simple, what can it be?

Re-add line-oriented programming

Earlier versions of EndBASIC had line numbers for the program contents and they came with RENUM and AUTO. When I added the full-screen editor, I removed those because the editor obsoleted them and the program lines didn't have any meaning. But... I find the lack of line numbers to be a deficiency for the kind of experience I want EndBASIC to offer.

So. We need to put line numbers back. But they must play well with the editor too, which must stay.

Shouldn't be too hard... unless we add line-based GOTOs, which we should have too, because then RENUM must understand them...

Add single-line IF statements

It seems like writing one-line IF statements is a pretty common need and QuickBASIC, for example, has special syntax for them that looks like this:

IF condition THEN statement

Note the lack of END IF and the lack of colon separators in the line.

Research this a bit more before implementing to see how these really behave in at least QuickBASIC and maybe GW-BASIC.

Support automatic integer promotion

Then language is strictly typed right now and does not allow automatic type promotion between integers and floats. There are some commands and functions that accept both with special code, but those are exceptions.

More importantly, functions cannot return various numeric types depending on their input, so it's impossible to implement things like ABS, MIN or MAX without hacks; we currently have MINI, MINF, MAXI, MAXF, for example, to cope with this and... let's face it: it's ugly.

While I do not like automatic integer promotion, BASIC has this feature and it'd make usability much better, especially when rendering graphics... so we should probably add this.

Homogenize SDL and web console implementations

The SDL and web consoles are pretty much copy/pastes of each other. This is annoying on its own, but is extra problematic because, while we do have test coverage for the SDL console, we have none for the web console.

I'm imagining that we should have a generic framebuffer console implementation that is backed by a "raster ops" object (much like NetBSD's console system) which implements the actual drawing primitives. With that, common logic such as "open line" would be in one place. And once we have that, we can consider reimplementing the terminal console to use our own rendering.

Restore video syncing when in the REPL prompt

If a user or a script calls GFX_SYNC FALSE and forgets to turn it back on, the REPL will misbehave. There is a warning about this in the help message for GFX_SYNC... but people are bound to make mistakes in this area and be confused.

We should probably have some machine-level hooks that soft-reset certain subsystems. There currently is such a feature for CLEAR, but it's too broad because it resets colors and many other details. So we should have a narrowed definition of what "clearing" means and call it from the REPL every time we show the prompt.

Add structured error handling

It is currently impossible for scripts to detect and react to errors. An obvious problem is calling GFX_* in the terminal console where graphics are not supported. Calling those commands will result in an error being shown, but the script will be terminated. It'd be good if the script could somehow capture those errors and do something about them. Look at how Visual Basic does error handling.

Caret browsing causes strange behavior in the web REPL

If "Caret browsing" (F7) is enabled in Chrome-based web browsers, the behavior of the REPL is erratic: pressing the Arrow Up key to recall a previous command and hitting Enter causes the browser to navigate away from the REPL (because the browser selects the EndBASIC link at the bottom of the page).

I suspect we can work around this issue with better keyboard handling in the web UI. Would be good to know if this is a regression in 0.8 with the replacement of xterm.js with custom code.

Add labeled GOTOs

Having support for labels and the ability to jump to them seems pretty important to offer a retro feeling, and is a prerequisite both for ON ERROR GOTO ... and for labeled statements.

Implementing this feature needs a significant shift in how we process programs. The current recursive interpreter doesn't lend itself well to having GOTOs, but there are ways to workaround the issue without a full rewrite. Still unsure what to do though.

Add basic speaker-like sound playing

The missing piece to be able to write some retro-style games or demos is the ability to play some sounds. I'd probably start mimicking the PLAY statement from Locomotive BASIC to generate speaker tones, but may need to research this further. Obviously we could go all fancy and support sound files too, but that should come later.

Decouple HELP from std

The HELP command is purely a feature of the REPL so it should be in the repl crate, not std.

Moving the command should be easy to do, except maybe for its tests that rely on the std MachineTester.

The more interesting question is: what do we do about the descriptions attached to all commands and functions? Somehow it does not make sense for those to be in the std crate because they are a user-facing, but keeping those descriptions attached to the callable objects makes it easier to update them. If we moved everything to the repl crate, then we'd need a way to ensure all registered commands and functions are documented, which kinda violates layering principles...

Separate keyboard shortcuts from console implementations

At the moment, the various console implementations are responsible for translating things like Ctrl+A to Home. This is a hack: the console should provide "raw" key events to the caller, and the caller should be responsible for interpreting them as desired.

This would mean moving the shortcuts into the readline and editor implementations.

Once this is done, we can expose the "raw" events via INKEY, such as C-a for Ctrl-A. We cannot do this at the moment because the behavior between arbitrary combined keys and known shortcuts would be different.

Move interactive commands to the repl crate

This is a follow up to #118. The std crate currently has various commands that are meant to be used from an interactive context only, like LOAD and SAVE, and it even has a concept of a InteractiveMachineBuilder. I sense that all of these belong in the repl crate.

One might argue that a program should be able to use LOAD, for example, to run a different program -- but that wouldn't work because, as soon as it did that, it'd lose control of what it is doing. So the answer here is that those programs should use RUN as described in #129. Need to review if there are other corner cases like that.

Display current program name in the browser's status bar

As of recently, the program-related commands keep track of the currently-loaded program so that the editor can display its name and so that SAVE can reuse it. But, while we are on the REPL, it's impossible to know what program is loaded.

An original thought was to display a status bar within the terminal, similar to the one the editor shows, and mimicking what QBASIC did for DOS. But I'm not sure we should go that way.

For now, though, it should be relatively easy to display this name in the browser's status bar along with the screen size and the like. And let's face it: most people are just going to use the web UI so this might be good enough.

Readline leaves text behind when moving from a long line to a shorter line

When moving from a long line to a shorter line in the REPL using the up/down arrow keys, the previous contents of the line aren't properly cleared. This is a recent regression in 0.8.0, as I modified the readline logic to be "smarter" and not clear the whole line every time (to not mangle existing graphical output, if any).

command to retrieve console dimensions

It'd be useful to be able to programmatically determine the size of the console both in terms of characters and pixels. Perhaps a set of commands like:

gfx_size_x()
gfx_size_y()
console_size_x()
console_size_y()

each of which returns an Integer with the maximal value of that dimension.

Sign binary releases

The pre-built Windows and macOS binary releases that we ship are very hard to use because they are unsigned, so these systems will block their execution by default. Things are now even worse as we ship various libraries due to SDL2... and these cause macOS to raise warnings for every single library. I'm not sure how we could sign the binaries, but it should be done.

For those reading, note that the binaries are built via GitHub Actions so you can audit how they are put together by looking at the scripts under .github/workflows/ and the logs for the corresponding run.

Allow customizing the prompt

Given that we have a concept of a current directory, the prompt should reflect that. But before overloading the current simple Ready prompt, I'd like to have a mechanism to customize it.

This is trivial by adding "special" environment variables, which we should have to customize various aspects from AUTOEXEC.BAS, but I'm not sure yet if it's wise to pollute the user's namespace with them.

Create backup files on SAVE

When saving a program to a file that already exists, the old program should be renamed to a .BAK extension to minimize the chances of losing data. This is especially important now that SAVE tracks the name of the loaded program and uses it to write things back to disk.

Handling string constants

I'm unable to type:
print "aaa"

in web interface

It simply ignored the " characters i type.
The same is true for ' character

Allow passing arguments to programs

EndBASIC programs should be able to receive arguments from the caller. This would make it possible to write useful command-line scripts, or parameterize the execution of those programs.

Need to decide how to model how these are passed. Would they be stored in a global ARGV array, for example?

Allow configuring the editor colors

While people can configure the colors of the console and make those changes relatively "persistent" via AUTOEXEC.BAS (not really, because the colors will be reset as soon as a CLEAR or RUN happens), the editor cannot be configured.

White on black is problematic for some people, and I've never liked a bunch of unmodifiable constants that exist in the code. Thus the colors should be configurable.

We need a mechanism to define configuration variables and then use those throughout the interpreter to replace hardcoded constants. An obvious way to do this is to define special variables like CONFIG_EDITOR_BG, set those via AUTOEXEC.BAS, and change the machine logic to treat them as special so that CLEAR does not wipe them out. We'd also need a CONFIG command that dumps them all (or a more generic VARS that prints all variables for introspection). But I'm not yet sure if that's the best design choice...

Recognize CTRL+C to stop running programs

Right now, if we have a program in a tight loop without doing any keyboard input, or if we have a program doing a long SLEEP, it's impossible to stop it. We should modify the interpreter to recognize interrupts at arbitrary points.

I'm not yet sure if this would involve fixing the native implementation of various features to be truly async. Those implementations currently block and don't let us do other stuff while we wait -- which might prevent fixing this.

Add support for the shebang in scripts

EndBASIC scripts should be allowed to start with a Unix-style shebang (#!/usr/bin/env endbasic).

At first, it seems like this should be implemented in the CLI when loading files... but given that # is not a valid character in BASIC, that'd prevent sharing those files with the web for example. So maybe we need to implement this at a lower level.

Various Unicode handling issues

In #161, @zenria fixed various Unicode-related crashes, but a few issues remain when dealing with "wide-looking" characters (don't know what the right name for those is). The easiest way to reproduce is to type some Korean characters (load and play with the test utf8.bas file).

  • Rendering these in the web version looks very weird because the console expects all characters to have the same width as "A" -- but those characters are wider. This does not have an easy fix (and I'm not even sure I want to fix it, because then we break the "grid" abstraction of the console), unless we make all rendered characters wider, which would look terrible.

  • Navigating such characters in the terminal editor doesn't work well either. The characters are rendered but navigation moves within them and stops prematurely before the end of the line. I suppose this is due to the TODO about handling graphemes properly. I did a quick try to use the unicode-segmentation crate and replace uses of chars() with graphemes(true) in LineBuffer, but that didn't fix the issue.

  • Rendering of Unicode characters works well in SDL, but not all. I tried with things like á and ç and those show up properly, but Korean characters show up as the typical empty boxes. Don't know what's going on there because the font we use supports Korean and, by looking at the SDL crate, it's actually calling into SDL's UTF8 rendering features. I was going to add a test for this but didn't because it's broken. If/when fixing this, I suspect we'd encounter the same issues as with the web regarding different character widths... so I'm not even sure it's worth fixing.

Allow auto-executing files via URLs

For files uploaded to cloud drives, it'd be very useful if it was possible to run them via special URLs like https://repl.endbasic.dev/username/file.bas. The idea here would be to open the interpreter, tell it to load the file, and then execute it.

There are two open questions here.

The first is what to do with public files. Such files should be probably visible and executable by anyone, maybe even those without a service account. That poses problems on the service side though, because it currently requires authentication for all requests.

The second is how to perform authentication if we choose to need it for all files, or if it is needed to access a non-publicly shared file. Right now authentication happens within the client context and is not visible from the browser (i.e. there are no cookies involved), so we'd have to introduce a login prompt somehow.

Maybe the easiest answer is to always require authentication and make the auto-execution process be: open the interpreter, ask for a username/password, load the file, and execute it. Which seems reasonable for the first file you load, but might get old if you try multiple and have to log in every time. That said, maybe this is sufficient for now given the small user base...

Track line numbers in error messages

The language parser is currently unaware of line numbers so most error messages are deficient. It is very hard to track down where problems come from without these.

Unsure if we should also track column numbers, especially for lines with multiple statements in them.

Parameterize RUN to execute other scripts

The RUN command should be extended to load scripts when given them as arguments, and maybe even support loading external binaries (so that you could write a "menu launcher").

The only problem here is how to model passing arguments to those programs vs. passing arguments to the currently-loaded script. The latter is currently not implemented, but see #128.

Allow concatenating numbers to string

It is impossible right now to construct a string from various parts because the addition operator only works on strings and we have no way to convert numbers to strings. We should add a mechanism to do this, probably by overloading the addition operator.

This is necessary to, for example, easily center computed strings on the screen.

React to screen size changes

We need a way to react to screen size changes.

The most obvious need for this is on mobile devices with on-screen keyboards, because the size of the console changes depending on whether the keyboard is shown or not. In particular, this is needed to fix the console on iPads where we always get a little input bar at the bottom of the screen -- but this bar shows up only once we have initialized the console to a larger size, which means the console currently overflows the bottom of the screen and results in invisible text.

Once we have #108, this will also let programs to adapt and resize themselves.

Support page up/down in editor

For "long" scripts (anything longer than a screenful), it's tedious to move along them line by line. We should support page up/down, and maybe the corresponding Emacs-like/macOS-like keybindings (because we already have others like that).

Add function to query screen dimensions

Given that the console can vary in size, we should have a way for programs to query this size. I'm not sure how that would look like though: do we return an array with the various dimensions, or do we try to come up with records first? Also, need to expose both the text and graphical dimensions, maybe within the same command or two separate ones.

[sdl] missing frames

I'm currently testing the SDL console on macos.

Sometimes, rendered surface seems not to be presented to the window. It happens more likely in REPL when 2 lines are printed without any user interaction. (Typically, "Ready" is not displayed)

I tracked the issue deeply in the code to check is there was a missing call to present_canvas(). Everything seems alright.

With the following code at the very end of force_present_canvas(), I managed to reproduce the issue:

self.canvas.surface().save_bmp("screen.bmp").map_err(string_error_to_io_error)

So here is the rendered BMP (everything is OK here):
surface_saved

And here is the screenshot of the actual window:
Capture d’écran 2022-04-24 à 18 18 04

The "Ready" prompt is missing! It has correctly been rendered in the underlying surface, but is not shown to the actual window! If I hit a key, let's say "B" the Ready prompt is correctly render and the "B" letter is shown at the right place...

I initially thought the issue was coming from the unusual way to render to the window (rendering to a surface and then blitting the surface to the window surface). SDL documentation and example wants you to render directly to a window canvas typically created by calling window.into_canvas().build(). This is also the way to enable hardware acceleration and Rust SDL documentation emphasizes that rendering to a surface is slow and not accelerated. So I heavily modified the code to do the rendering to a window canvas and to present the canvas.

This did not work! Same issue.

I then read a bunch of example of SDL code. In all example, the render is always done the same way:

  • consume all events
  • render the whole scene
  • wait some time to achieve 30 or 60 fps
  • present the canvas

The critical part missing from the endbasic SDL rendering code is the wait time. I confirmed this by adding a dumb std::thread::sleep in force_present_canvas() function. No more missing frames.

I'm not sure how to fix this. I think the best way would be to have a dedicated thread that does main loop the way sdl wants it to be (poll events/render/wait/present) and communicates with the rest of endbasic (the Console trait impl) with channels.

Fix SDL tests flakiness

The SDL integration tests require creating an SDL context, and there can only be a single context available at a time. To sequence those tests, we have a lock, but for some reason, it's not reliably working and sometimes two tests step on each other and fail on CI. This always happens on the Windows build because it's the only one in which we exercise this, and it's a relatively common failure on CI.

Add break/continue

It'd be very useful to stop loops half-way through. Need to research if variants of BASIC have break and continue keywords, or if we should add labels and rely on GOTO instead. The latter is probably more idiomatic, and fixes the issue of exiting nested loops anyway.

Keyboard input not working on Android

Hey, cool project! I tried to test it in Firefox on my Android phone, but when I enter a space character, it erases all input on the line. Pressing enter also clears the line and doesn't result in any output.

Maybe you're not planning to support mobile or Firefox, but I thought I'd let you know anyway.

Various keys escape the terminal

Pressing the Tab key when inside the web interface causes the terminal to lose focus, as the input focus moves to the next element in the DOM. This is annoying when within the editor because Tab can be used for indentation.

I tried a simple fix to call terminal.focus() on key up/down events but that did not fix the problem, so filing this bug instead to track this issue.

Add DATA and READ

In order to input large data sets, the DATA and READ statements are very useful, especially because cloud storage is very limited and declaring arrays with individual assignments takes a lot of space.

This sounds simple in practice until we realize that DATA statements can appear after READ, so we have to find a way to find that data. QuickBASIC, for example, seems to just look for DATA statements that appear anywhere in the program and treat them as if they were at the end... which means a pre-pass through the program.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.