Introduction
This page provides an overview of the EndBASIC programming language and environment. Most of this text is written in a tutorial-like style, guiding you to accomplish certain tasks. The text is not meant to teach you programming from the ground up, although that would be desirable considering what EndBASIC’s goals are.
Launching the interpreter
EndBASIC is multi-platform and runs on the web and on almost all desktop operating systems, including macOS, Windows, and any Unix derivative such as FreeBSD or Linux. Most features exist in all builds, although there are a few exceptions.
The easiest way to get started is via the web-based interpreter, which you can start by clicking on this button:
Launch interpreter
If you prefer the desktop version, visit the Download page to fetch the right build for your system and follow the instructions provided there.
As a teaser, note that if you end up trying out different versions of the interpreter, the easiest way to move files between them is to use the file-sharing cloud service.
Writing your first program
To create your first program, open up the interpreter, type EDIT
and press Enter
. This will open up a full-screen text editor where you can start typing your first program. Within it, type the text below and press Esc
to return to the command line:
INPUT "What's your name"; name$
PRINT "Hello,"; name$
Once you are back in the command line, try using the LIST
command to visualize that the program you typed is stored in the interpreter’s memory, and then use the RUN
command to launch your program:
Ready
LIST
INPUT "What's your name"; name$
PRINT "Hello,"; name$
Ready
RUN
What's your name? Julio
Hello, Julio
That’s it! You have written and executed your first program!
When the interpreter stops, all state changes made by the program are left untouched. This is useful to illustrate that the program and the interpreter are tightly coupled and helps troubleshoot problems in the program. In other words: any variables defined up to the point where the program stopped are still in memory, so if you type PRINT name$
from the command line, you’ll get back the name that you previously entered.
Because of the side-effects that an executed program leaves behind, the CLEAR
exists and lets you reset the interpreter to a clean slate while maintaining your program in memory. (Essentially, RUN
does a CLEAR
first to ensure that your program isn’t impacted by previous state.) There is also a command called NEW
which does the same as CLEAR
and also clears the program stored in memory.
To iterate on the program, you can go back to the editor by typing EDIT
again, modifying your previous code.
Loading and saving
In the previous section, you wrote your first program—and I suppose you don’t want to lose such a precious creation! To avoid that, you can save your program to disk with the SAVE
command, verify that it was saved via the DIR
command, and load it back into memory via the LOAD
command:
SAVE "hello.bas"
Saved as LOCAL:hello.bas
Ready
DIR
Directory of LOCAL:/
Modified Size Name
2022-06-03 13:08 55 hello.bas
1 file(s), 55 bytes
Ready
LOAD "hello.bas"
Once you have given the program a name, the interpreter will keep track of it until you exit or discard the currently-loaded program via the NEW
command. This means that any subsequent SAVE
operation can be done without re-entering the program name: simply typing SAVE
will update the previously-created file with the new contents.
EndBASIC will try to prevent you from losing your program. For example, if you try to drop the current program with NEW
or exit the interpreter before saving your program, EndBASIC will prompt you to confirm your actions.
That said, get in the habit of saving your program frequently. If your program gets stuck, you may need to reboot the interpreter and there is no protection against that.
Getting help
EndBASIC is designed to be self-documenting, and this document does not intend to provide a full reference manual to EndBASIC because this information is already built into the interpreter.
To access the built-in reference documentation, type HELP
within the interpreter, which will greet you with a message like this:
Ready
HELP
This is EndBASIC 0.9.99.
Project page at <https://www.endbasic.dev/>
License Apache Version 2.0 <http://www.apache.org/licenses/LICENSE-2.0>
Top-level help topics
>> Array functions
>> Cloud access
>> Console
>> Data management
>> File system
>> Graphics
>> Hardware interface
>> Interpreter
>> Language reference
>> Numerical functions
>> Stored program
>> String and character functions
Type HELP followed by the name of a topic for details.
Type HELP "HELP" for details on how to specify topic names.
Type LOAD "DEMOS:/TOUR.BAS": RUN for a guided tour.
Type END or press CTRL+D to exit.
This main help page shows you the available help topics. To get extra help, you need to provide one of those topics to the HELP
command. Topic matching is done on a prefix basis, so you can type only part of the topic name. For example, to access the Array functions topic:
Ready
HELP "ARR"
Array functions
>> LBOUND% Returns the lower bound for the given dimension of the array.
>> UBOUND% Returns the upper bound for the given dimension of the array.
Type HELP followed by the name of a symbol for details.
And from there, you can also obtain extra information on the subtopics. For example, to get details on the LBOUND%
function:
Ready
HELP "LB"
LBOUND%(array[, dimension%])
Returns the lower bound for the given dimension of the array.
The lower bound is the smallest available subscript that can be
provided to array indexing operations.
For one-dimensional arrays, the dimension% is optional. For
multi-dimensional arrays, the dimension% is a 1-indexed integer.
Pay special attention to the LANG
topic, which gives you access to documentation on the language itself. This document replicates some of that information.
Language basics
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. The language itself includes many of the features that you may expect from BASIC, but it can also feel lacking in some scenarios. Please let me know if you find yourself needing a new language construct or new standard library features.
Case sensitivity
EndBASIC is case-insensitive. It is common to write BASIC code all in uppercase, but this is not a requirement. The convention in the EndBASIC interpreter, the documentation, and example code is to write all keywords in uppercase and all identifiers (variable names) in lowercase.
As a tip, note that uppercase keywords make the code look dated because all modern programming languages use lower_snake_case
(Rust, C++), camelCase
(Java, Python, Go) or PascalCase
(C#, Go). Writing your EndBASIC code in lowercase will make it look more modern.
For extra trivia, note that the convention in Visual Basic is to use CamelCase
.
Primitive types
EndBASIC is a strongly typed language. Variables are assigned a type at definition time and their type remains immutable throughout their existence. This type is represented as a single-character type annotation appended to the variable names. The type annotation is optional, in which case EndBASIC will infer types, but it must match the type of the variable if present.
Similarly to the note on case sensitivity, the convention in EndBASIC is to almost-always show type annotations next to variable names, but this makes the code look dated. For a more modern look, avoid type annotations unless explicitly required.
The following types are supported:
Type | Annotation | Default | Values |
---|---|---|---|
Boolean | ? | FALSE | TRUE and FALSE |
Double floating point | # | 0.0 | Numbers with a period |
32-bit signed integers | % | 0 | Numbers from -2,147,483,648 to 2,147,483,647 |
Strings | $ | "" | Any text enclosed in double-quotes |
Integer literals can also be specified in base form:
Base | Integer literals |
---|---|
Binary | &b0101 or &b_0101 |
Octal | &o750 or &o_750 |
Decimal | 789 , &d789 or &d_789 |
Hexadecimal | &xa10f or &x_a10f |
New variables can be defined and declared at assignment time, like in these examples:
bool_var? = TRUE
double_var# = 5.0
integer_var% = 5
string_var$ = "Hello, world!"
Or they can be declared and set to their default values with the DIM
command:
DIM b AS BOOLEAN ' b? is set to FALSE.
DIM d AS DOUBLE ' d# is set to 0.0.
DIM i AS INTEGER ' i% is set to 0.
DIM s AS STRING ' s$ is set to "".
Arrays
EndBASIC supports multidimensional arrays. Arrays are represented as contiguous blocks of memory in row-wise order and all values in the array must be of the same type.
Arrays must be defined with the DIM
command and are later accessed using parenthesis (which is unlike most common languages today, which use square brackets for indexing):
' Define a 2-dimensional array (aka matrix) with 5 rows and 3 columns.
DIM arr(5, 3) AS INTEGER
` Assign and access two different positions.
arr(3, 2) = 12345
PRINT arr(1, 1)
Arrays are 0-indexed, which matches QuickBASIC and modern programming practices. There is no support for OPTION BASE
nor to specify the lower bound of an array to change this behavior. This might change though, so you are encouraged to use LBOUND%
and UBOUND%
when iterating over arrays to make your code future-proof:
DIM arr(10)
FOR i = LBOUND%(arr) TO UBOUND%(arr)
PRINT i, arr(i)
NEXT
Operators
Arithmetic operators
EndBASIC supports the following arithmetic operators:
Expression | Meaning |
---|---|
a + b | Addition |
a - b | Subtraction |
a * b | Multiplication |
a / b | Division (integer or floating point depending on variable types) |
a MOD b | Modulo operation (integer division remainder) |
a ^ b | Exponent operation |
-a | Sign flip |
Integers are automatically promoted to doubles when they appear in a floating point expression, and floats are rounded to the closest integer (3.4 becomes 3, but 3.5 becomes 4) when they appear in a context that requires integers.
Comparison operators
EndBASIC supports the following comparison operators:
Expression | Meaning |
---|---|
a = b | Equality comparison |
a <> b | Inequality comparison |
a < b | Less-than comparison |
a <= b | Less-than or equal to comparison |
a > b | Greater-than comparison |
a >= b | Greater-than or equal to comparison |
Integers are automatically promoted to doubles when they appear in a floating point expression, and floats are rounded to the closest integer (3.4 becomes 3, but 3.5 becomes 4) when they appear in a context that requires integers.
Logical and bitwise operators
EndBASIC supports the following logical and bitwise operators:
Expression | Meaning |
---|---|
a AND b | Logical or bitwise and |
a OR b | Logical or bitwise or |
a XOR b | Logical or bitwise exclusive or |
NOT a | Logical or bitwise negation |
a << b | Bitwise integer left shift |
a >> b | Bitwise integer right shift (signed) |
When the operands to these operators are booleans, they perform logical comparisons. There is no automatic coercing of other types into booleans, and there will not be. In particular, this means that something like NOT a
in a boolean context is invalid unless a
is a boolean.
When the operands to these operators are integers, they perform bitwise operations. The result of these operations are integers, so they cannot be directly used in boolean context. For example, if you are trying to test if a bit is set, you will have to compare the outcome of a bitwise operation against an integer:
IF (a AND &b_0001) <> 0 THEN PRINT "a has the right-most bit set"
Expressions
All of the previously-described operators can be combined in complex expressions. The following ordering applies when evaluating expressions:
- Function calls and array references.
- Parenthetical sub-expressions.
- Arithmetical sign flip and logical negation.
- Arithmetical multiplication, division and modulo.
- Arithmetical addition and subtration.
- Comparisons.
- Logical/bitwise and, or and exclusive or.
Operators of the same priority are applied left-to-right. For example, in 3 - 4 + 5
, where both addition and subtraction have the same priority ordering, the subtraction will be done before the addition (as you would expect).
As an example, here is an expression to compute a random number between 500 and 600 and check whether the resulting number is within 500 to 550:
Ready
PRINT INT(RND(1) * 100.0) + 500 < 550
FALSE
GOTO and GOSUB
EndBASIC supports unconditional jumps to labels and explicitly-assigned line numbers, just like QuickBASIC supports. Labels are words prefixed by the @
sign that appear on a line of their own and line numbers prefix statements just like they do in traditional BASIC implementations.
Here are some examples:
GOTO @first
@first
PRINT "first"
GOTO @second
@second: PRINT "second": GOTO 300
300 PRINT "third"
The @
prefix for label names is an EndBASIC-specific artifact required to resolve parsing ambiguities. This requirement might be relaxed in the future.
EndBASIC does not yet support defining custom functions nor procedures, but it supports GOSUB
, which provides an unconditional jump to a target location (using the same syntax as GOTO
) and the ability to return to the call site via RETURN
.
You can use this feature to implementing rudimentary procedures and functions. For example:
x = 3: y = 4: GOSUB @add
PRINT result
END
@add
result = x + y
RETURN
Conditionals
If statements
EndBASIC supports conditional statements (IF
) with zero or more alternate branches (ELSE IF
and ELSE
).
Here is how the most simple construct looks like:
IF 3 < 5 THEN
PRINT "Three is less than five"
END IF
Here is a more advanced construct with multiple alternate branches:
discount# = RND(1)
IF discount# < 0.2 THEN
PRINT "Meh, a small discount."
ELSEIF discount# < 0.7 THEN
PRINT "Nice, a good discount!"
ELSE
PRINT "Wow, an amazing discount!"
END IF
One-line if statements are also supported and have these forms:
IF 3 < 5 THEN PRINT "Less"
IF 3 < 5 THEN PRINT "Less" ELSE PRINT "More"
Multiple choice
Other than for IF
/ELSE IF
conditionals, EndBASIC also supports to more advanced SELECT CASE
multiple choice statement. Here is how it looks like:
INPUT "Enter a number"; a
SELECT CASE a
CASE 1, 3, 5, 7, 9
PRINT "Odd"
CASE 0, 2, 5, 6, 8
PRINT "Even"
CASE IS < 0, 10 TO 100
PRINT "Other cases"
CASE ELSE
PRINT "Fallback"
END SELECT
Loops
EndBASIC supports a wide variety of loop types.
While loops
While loops are supported via the WHILE
and WEND
keyword. Here is how they look like:
n% = 0
WHILE n% < 1 OR n% > 10
INPUT "Enter a number between 1 and 10: ", n%
WEND
For loops
For loops are supported via the FOR
keyword. For loops iterate over an inclusive range of integers with a default step of 1. For example, the following loop will print numbers 1, 2, 3, 4 and 5:
FOR i% = 1 TO 5
PRINT i%
NEXT
The stepping through the range is configurable via the STEP
keyword, and this can be both positive and negative. For example, the following loop will print the numbers 10, 8, 6, 4 and 2:
FOR i% = 10 TO 1 STEP -2
PRINT i%
NEXT
Both the beginning and end of the range can be arbitrary integer expressions. However, the STEP
argument must be an integer literal.
Do loops
Do loops are the most generic type of loop, as they can specify until/while conditions at the start or at the end, or they may omit all conditions to specify an infinite loop.
Here are some examples:
DO
PRINT "Infinite loop"
LOOP
DO
a = a + 1
LOOP UNTIL a = 10
DO
a = a + 1
LOOP WHILE a < 10
a = 0
DO UNTIL a = 10
a = a + 1
LOOP
a = 0
DO WHILE a < 10
a = a + 1
LOOP
The EXIT DO
statement can be used to terminate a DO
loop.
Error handling
Certain errors can be caught and handled programmatically, such as when trying to perform graphical operations on a non-graphical console. This can be achieved with the ON ERROR
statement, which configures what to do whenever an error arises. The following options are available:
ON ERROR GOTO 0
: Restores the default error handler, which terminates the program upon the next error that arises.ON ERROR GOTO @label
: Continues execution at@label
when an error happens.ON ERROR RESUME NEXT
: Continues execution at the next statement when an error happens.
The ERRMSG
function returns the textual representation of the last error that was caught.
Data blocks
A program can specify data values with the DATA
statement. These data values can be defined anywhere in the program and can be extracted later on via the READ
statement. Here is an example:
DATA 1, 3, 5, 7, 9
DO
READ i%
IF i% < 0 THEN EXIT DO
PRINT i%
LOOP
DATA 0, 2, 4, 8, -1
User-defined functions and subroutines
EndBASIC supports user-defined functions and subroutines. Here are some examples:
FUNCTION add(n1%, n2%)
add = n1 + n2
END FUNCTION
FUNCTION multiply(n1 AS INTEGER, n2 AS INTEGER)
n = 0
FOR i = 1 to n2
n = n + n1
NEXT
multiply = n
END FUNCTION
SUB print_all(n1 AS INTEGER, n2 AS INTEGER, t AS STRING)
PRINT "Your message is "; t
PRINT add(n1, n2)
PRINT multiply(n1, n2)
END SUB
print_all 3, 4, "Hello"
All function and subroutine arguments are currently passed by value. There is no way to pass arrays by reference.
The EndBASIC syntax to set the return value of a function is to assign the value to a variable named like the function. This does not cause the function to return immediately, however,
All variables within functions and subroutines are local by default. To access a global variable, the variable must be defined outside the function with the DIM SHARED
keyword:
DIM SHARED the_global AS DOUBLE
SUB increment_global
the_global = the_global + 1
END SUB
PRINT the_global
increment_global
PRINT the_global
Console
The EndBASIC console is a hybrid console that offers overlapping textl and graphics. As such, the console exposes two coordinate systems: commands that deal with text use character-based coordinates, and commands that deal with graphics use pixel-based coordinates. Both coordinate systems are 0-indexed and start at the top-left corner of the console.
The graphical console is available by default in the web version of EndBASIC.
Desktop builds have support for the graphical console as well, but they must be built with SDL support. All prebuilt binaries in the Download section have SDL support. Note, however, that to launch the desktop version of EndBASIC with graphics support, you will have to use a command like these:
endbasic --console=graphics # Default settings.
endbasic --console=graphics:1024x768 # Specific resolution.
endbasic --console=graphics:1920x1080fs # Specific resolution, full screen.
Text manipulation
The EndBASIC text console provides sufficient features to build simple text-based interactive interfaces. These include changing colors, moving the cursor around, and waiting for key presses.
To get started, you can play with the CLS
command to clear the screen, the COLOR
command to set the foreground and/or background colors of the text, and the LOCATE
command to move the cursor to a new position. Note that LOCATE
on its own is useless unless it is immediately followed by a PRINT
invocation.
To experience these features, type the following string of commands in the console and press Enter:
COLOR 15, 12: CLS: LOCATE 10, 10: PRINT "Hello": LOCATE 0, 15
Interactive interfaces
To build any kind of interactive interface, be it textual or graphical, you will need to wait for key presses. The INPUT
command is insufficient for this because it waits for a full line of input. But we can use the INKEY
function to poll the keyboard for an input.
For example, see this code to build a loop that waits for a key press and then reacts to it:
PRINT "Press keys to get feedback, or ESC to exit"
k$ = ""
WHILE k$ <> "ESC"
k$ = INKEY
IF k$ <> "" THEN
PRINT "You pressed"; k$
END IF
SLEEP 0.01
WEND
Rendering graphics
A distinctive feature of EndBASIC is its support for graphics and text in the same console. You can start rendering graphics right from the command line, without having to understand how two separate windows interact with each other or without changing modes.
To get started, play with the GFX_LINE
or GFX_RECT
commands:
GFX_LINE 0, 0, 100, 100
GFX_RECT 100, 100, 300, 300
Remember that you can access detailed reference information for all available commands within the graphics category by typing HELP "GRAPHICS"
.
Efficient graphics rendering
Drawing occasional graphics from the console by typing individual commands is a great way of exploring what’s available and understanding how the computer reacts to code, but rendering graphics in this manner is not very efficient: every drawing operation will be flushed to the video card as soon as it is executed, and this is a slow process.
To draw animations in an efficient manner, you must explicitly control when the console’s contents are sent to the screen: in other words, you need to control when every video sync operation happens.
The general idea is that your program needs to render everything first “in memory” and then tell the video driver to paint the results. This can be accomplished via the GFX_SYNC
command, which allows us to enable or disable automatic video flushing, and to explicitly flush the video.
Here is a sample program that renders an animation. Pay attention to the way the calls to the GFX_SYNC
are done:
' Disable automatic video syncing.
GFX_SYNC FALSE
' Loop until any key is pressed.
x% = 0
c% = 0
WHILE INKEY$ = ""
' Clear the screen and render the current frame.
CLS
COLOR c%
GFX_RECTF x%, 100, x% + 10, 110
' Update positions and colors for the next frame.
c% = (c% + 1) MOD 15
x% = (x% + 5) MOD 500
' Flush the rendered frame to the screen.
GFX_SYNC
' Pause until the next frame.
SLEEP 0.01
WEND
CLS
COLOR
' Enable automatic video syncing.
GFX_SYNC TRUE
File system
EndBASIC offers a DOS-like interface to access and manipulate files.
Due to the fact that the EndBASIC command line is BASIC, there are a few oddities you will have to get used to when typing commands. The first one is that paths and file names are strings, and as such must be double-quoted. The second one is that arguments to commands must be separated by commas, not just spaces.
Drives and paths
The EndBASIC virtual file system is composed of a bunch of drives, each containing its own collection of files. Drives are mapped to targets, and these targets expose a variety of backend storage services.
Paths in EndBASIC have the general form [DRIVE:][/]FILENAME
. Both the drive name and the slash are optional. When all components are present, such as in LOCAL:/FILE.BAS
, we have an absolute path that unique identifies a file; when the drive component is missing, such as in FILE.BAS
, we have a relative path to the current working directory.
The current working directory can be queried with the CWD
command and can be changed via the CD
command. For example:
Ready
PWD
Working directory: LOCAL:/
System location: /home/jmmv/Documents/endbasic/
Ready
CD "memory:"
Ready
PWD
Working directory: MEMORY:/
No system location available
Directories are not currently supported. This is why the slash in the paths above is optional, but it’s good to get in the habit of specifying it because support for directories will come later.
Drive providers
Drives are mapped to targets, and these targets are backed by virtual file system providers that expose a variety of backend storage services.
The following providers are currently supported:
Target scheme | Availability | Description |
---|---|---|
cloud://user | All | Exposes the cloud drive of the user . More on this in the Cloud service section. |
demos:// | All | Read-only collection of built-in demo programs. |
file:///path | Desktop | Exposes the /path directory of the local file system. Any subdirectories are ignored. |
local:// | Web | Provides a file system backed by the browser’s local storage. Files saved in this provider never leave your machine. |
memory:// | All | Memory-backed file system. Different instances of this provider offer disjoint file systems. |
The list of currently-mounted file systems can be queried and modified via the MOUNT
command. For example:
Ready
MOUNT "cloud://jmmv" AS "jmmv"
Ready
MOUNT
Name Target
DEMOS demos://
JMMV cloud://jmmv
LOCAL file:///home/jmmv/Documents/endbasic
MEMORY memory://
4 drive(s)
Side-loading files
While EndBASIC provides a built-in editor, the editor is currently quite simplistic. If you find that the editor limits your development speed, you can side-load files into the interpreter. This feature is only available in the desktop version of EndBASIC.
To do this, you can either save files under the default projects location, which typically is ~/Documents/endbasic/
, or you can save them under a directory of your choice and then mount that directory inside EndBASIC using the file://
mount target.
For example, say that you create a program outside of EndBASIC:
$ mkdir ~/bas
$ vim ~/bas/example.bas
... edit edit edit ...
Once the file is saved, you can access it like this:
Ready
MOUNT "file:///home/jmmv/bas" AS "X"
Ready
CD "X:"
Ready
DIR
Directory of X:/
Modified Size Name
2022-06-03 23:37 23 example.bas
1 file(s), 23 bytes
Cloud service
The EndBASIC service is a simple cloud-based file system that lets you maintain and share your creations with the world, right from the EndBASIC command line.
You can always consume public content without creating an account but, to share your own content, you will need an account first.
Accessing public content
To access a file that was shared publicly by you or someone else, you have two options.
The first option is to tell the web UI to automatically run the program based on a URL of the form:
https://repl.endbasic.dev/?run=user/file.bas
Replace user
with the name of the user that has shared the file and file.bas
with the name of the file that was shared. With that, the interpreter will launch, mount the user’s public drive, and run the given file. Try it now: run the endbasic/welcome.bas
demo!
The second option is to mount the user’s drive interactively and then investigate its contents. You can do so providing a target of the form cloud://user
to the MOUNT
command, where user
is the name of the user that shared the file. Then, inspect the drive contents with the DIR
command and load a file with the LOAD
command. Here is a sample session:
Ready
MOUNT "cloud://endbasic" AS "e"
Ready
CD "e:"
Ready
DIR
Directory of E:/
Modified Size Name
2022-05-27 16:25 40 welcome.bas
1 file(s), 40 bytes
Ready
LOAD "welcome.bas"
Ready
LIST
PRINT "Welcome to the EndBASIC service!"
When mounting a cloud drive, the contents you see will depend on your credentials. If you are not logged in, all you will see are the user’s public files (if any). If you are logged in, whoever, you will also see any files that the user may have shared directly with you.
Signing up
To create an account, use the SIGNUP
command from within the interpreter. You will have to provide basic information for the account, such as a username and a password, and you will also have to provide an email address for account activation (see privacy notes). Here is what you can expect during account creation:
Ready
SIGNUP
Let's gather some information to create your cloud account.
You can abort this process at any time by hitting Ctrl+C and you will
be given a chance to review your inputs before creating the account.
Username: demo
Password: *********
Retype password: *********
We also need your email address to activate your account.
Your email address will be kept on file in case we have to notify you
of important service issues and will never be made public. You will
be asked if you want to receive promotional email messages (like new
release announcements) or not, and your selection here will have no
adverse impact in the service you receive.
Email address: your-email@example.com
Receive promotional email (y/N)? n
We are ready to go. Please review your answers before proceeding.
Username: demo10
Email address: your-email@example.com
Promotional email: no
Continue (y/N)? y
Your account has been created and is pending activation.
Check your email now and look for a message from the EndBASIC Service.
Follow the instructions in it to activate your account. Make sure to
check your spam folder.
Once your account is activated, come back here and use LOGIN to get
started!
If you encounter any problems, please contact support@endbasic.dev.
After you complete this process, check your email and look out for a message from the EndBASIC service. You’ll have to click on the link provided within to activate your account, and you must do that before proceeding.
Note the question above to receive promotional emails. If you consent to that, you will receive notifications of new EndBASIC releases and new blog posts via email. I’d appreciate it if you said yes as a mechanism to keep a certain level of engagement in EndBASIC over time. Expect about one email a month at most.
Logging in
Once you have created and activated your account, all you have to do is type LOGIN "username"
to log into your account:
Ready
LOGIN "demo"
Password: ********
----- BEGIN SERVER MOTD -----
Welcome back, demo! It's good to see you again.
----- END SERVER MOTD -----
After a successful log in, the EndBASIC client will mount the CLOUD:
drive, which is your personal space to hold files in the cloud. Any files stored in this drive are private to you by default, but they can be shared with others with ease using the SHARE
command.
Ready
CD "CLOUD:"
Ready
DIR
Directory of CLOUD:/
Modified Size Name
2021-06-25 13:51 116 thanks.bas
2021-06-25 13:50 103 welcome.bas
2 file(s), 219 bytes
65317 of 65536 bytes free
Uploading a program
Sometimes, it is simpler to develop a program outside of the EndBASIC environment and then side-load it into the interpreter. This is easy to do in the desktop build of EndBASIC because it has direct access to the local file system, but it is hard to do for any file in the cloud.
The way around this is to develop your program locally and then upload it to the cloud. To do this, you will have to do a manual file copy. For example, suppose we want to upload LOCAL:/upload.bas
to CLOUD:/upload.bas
. We can do so by loading the file into memory and then saving it again, like this:
Ready
LOAD "LOCAL:/upload.bas"
Ready
SAVE "CLOUD:/upload.bas"
Saved as CLOUD:/upload.bas
Publishing a program
The primary purpose of the EndBASIC cloud service is to let you share your magical creations with the public.
Files saved in cloud drives have reader ACLs that control who can read them. You can give read permissions to individual users, or you can give read permissions to everyone by means of the public
pseudo-user.
Suppose we have saved a awesome.bas
file in our cloud drive. We can share it with the public like this:
Ready
SHARE "CLOUD:/awesome.bas", "public+r"
You have made the file publicly readable. As a result, other people
can now auto-run your public file by visiting:
https://repl.endbasic.dev/?run=jmmv/awesome.bas
Note how the SHARE
command detects that you have made the file public and will print the URL that users can open to automatically launch your program.
Privacy and security notes
EndBASIC is, right now, a toy project. While I have tried my best to keep the service secure and private, I ask that you do not store any sensitive information in this service.
More specifically:
Your user account and files are stored in a PostgreSQL database managed by Azure. Read the Azure Encryption documentation for more details on what this entails.
I collect high-level metadata on all requests to the cloud service for troubleshooting purposes and basic usage analytics. Details include the contacted API endpoint, the client IP address, and the originating browser agent. The logs do not include the request payloads, but obviously the database does.
The email address collected during the sign-up process will only be used for critical service-related communications by default. These can include notifications of data loss due to the evolving nature of the service. There has only been the need to send one such notification so far, and I expect the volume of these emails to be near zero.
Your email address will never be sold nor given to third-parties. However, as part of giving you service, your email must flow through SendGrid and has is in theory visible to the operators of the PostgreSQL database managed by Azure.
You can opt in to receiving “promotional emails”, and I would appreciate it if you did so. These emails will include notifications of new EndBASIC releases as well as notifications of new blog posts. You can expect about one such message per month on average.
You can always update your account’s information or permanently delete your account and all information associated with it. Contact support and I’ll be happy to assist you; I haven’t had a chance to build those features within the interface yet.
Hardware access
EndBASIC supports limited direct hardware access as a way to play with real-world hardware. Toying with LEDs, buttons, and the like can be a great way of learning how computers work, and is the reason why this support was builtin EndBASIC.
Hardware support is currently limited to the desktop builds for the Raspberry Pi, which you can get from the Download page.
GPIO
EndBASIC has support to manipulate the GPIO pins of the Raspberry Pi via the family of commands described in HELP "HARDWARE"
.
As an example, here is how to wait for a physical button press attached to pin number 8:
GPIO_SETUP 8, "IN-PULL-DOWN"
pressed? = FALSE
WHILE NOT pressed?
pressed? = GPIO_READ(8)
SLEEP 0.01
WEND
And here is how to flash an LED attached to pin number 18:
GPIO_SETUP 18, "OUT"
state? = TRUE
FOR i = 1 to 10
GPIO_WRITE 18, state?
SLEEP 1
state? = NOT state?
NEXT
GPIO_CLEAR
LCDs
EndBASIC has support for the ST7735s LCD and can display its own console on this 128x128 display. If you have such a device, you can launch EndBASIC like this:
endbasic --console=st7735s
For more information, see Porting the EndBASIC console to an LCD.
Configuration
AUTOEXEC.BAS
The EndBASIC interpreter looks for a file named AUTOEXEC.BAS
(all uppercase) in the LOCAL:/
drive at startup time and, if found, will run it before dropping you into the command prompt.
You can create this file from within the interpreter and make it run any commands you like. A common use may be to run LOGIN
to automatically log into your cloud account. Or you could use it to customize the appearance of the console by changing its colors.