Documentation/Chapters

Your first program

On this page

BASIL is a compiled language for writing small utilities and substantial native applications. You write readable text, the compiler checks it, and the result is an executable program. You do not need to understand memory management to print a greeting. As your programs grow, the same language provides static types, structured errors, automatic resource cleanup and lightweight concurrent tasks.

This book describes the maintained self-hosted implementation, initially for Linux x86-64. It is not a compatibility manual for every historical BASIL. Read chapters 1 through 8 in order if programming is new to you. Chapters 9 through 15 explain the ownership and concurrency model. Later chapters build practical applications. The reference part supplies detailed library behavior and signatures.

Obtain a working compiler

From a source checkout, follow the bootstrap instructions . The canonical build is:

python3 tools/selfhost.py --report docs/selfhost-report.json
build/selfhost/stage3 --help
build/selfhost/stage3 toolchain

The bootstrap performs substantial validation. A successful build publishes build/selfhost/stage3. Throughout this book, shell commands use that path from the repository root. If your installation provides basic on PATH, substitute basic. Keep the compiler and its matching native SDK together; optional library features use that SDK. toolchain identifies the executable, target and native inputs.

Say hello

Save this complete program as hello.bas:

PRINT "Hello, world!"

Compile and run it:

build/selfhost/stage3 build hello.bas -o build/hello
./build/hello

The output is:

Hello, world!

PRINT writes text followed by a newline. Quotes delimit a string, which is a text value; the quotes themselves are not printed. The compiler’s build command writes the executable and reports its path. The simpler one-step command is build/selfhost/stage3 run hello.bas.

The historical compiler interface is also supported: stage3 hello.bas writes executable bytes to stdout. Redirect those bytes to a file and check the command’s exit status before executing it. For everyday use, prefer build and run.

Make the program your own

' An apostrophe starts a comment.
name = "Ada"
PRINT "Hello, " + name + "!"
PRINT "She said ""Hello""."

A variable gives a name to a value. The first assignment introduces name and infers its type as STRING. The plus signs concatenate strings. Double a quote inside a string to include a literal quote. Backslashes have no escape meaning: "\n" contains a backslash and an n.

Identifiers are ASCII case-insensitive, so Name and name identify the same variable. Strings and source files use UTF-8. Indentation helps readers; block keywords such as END IF determine structure. Put statements on separate lines.

Entry points and exit status

Top-level executable statements, as above, are convenient for small programs. Alternatively, supply a SUB Main() or a zero-argument INTEGER FUNCTION Main(). Choose one entry style per program.

FUNCTION Main() AS INTEGER
    PRINT "Ready"
    RETURN 0
END FUNCTION

An integer Main returns a process exit status: zero conventionally means success. Functions introduced later can declare checked failures. An unhandled root error is reported after recoverable cleanup and exits with status 1.

Read a compiler message

count = 3
count = "three"

This example is intentionally rejected. A variable’s static type does not change when you assign again. Find the reported file and location, then read what operation and types conflict. Fix the first useful error and rebuild. Do not assume that a later message describes an independent problem.

Try changing the greeting, adding another PRINT, and deliberately removing a closing quote. Seeing a small error in a familiar program is a good way to learn the compiler’s diagnostic style.

How examples are checked

Most teaching examples are complete programs with output checked by the book build. Deliberately rejected examples are tested for a diagnostic. Excerpts, interactive programs and examples requiring a server, GUI or native dependency are explicitly described as such. Detailed build and example records accompany the editable source. Examples establish the behavior they demonstrate, rather than proving every property of the language.

From the BASIL documentation. View source ↗

Find your way around BASIL

Type to search the manual.