Skip to main content

Getting Started

BT source files use the .bt extension. A program defines a zero-argument main function. ctbt builds it into an executable or runs it directly.

Hello, World​

Create hello.bt:

include "io";

infallible fn main() -> int {
println("Hello, World!");
return 0;
}

println belongs to the standard library's io package, so the file includes it.

Build it:

ctbt hello.bt

The executable is named after the first source file: hello on Linux, hello.exe on Windows. Choose the name with -o:

ctbt build -o greeting hello.bt

ctbt hello.bt and ctbt build hello.bt are the same command.

A folder is one package, so every .bt file beside hello.bt is compiled into the same program. Give each program its own folder.

Run a source file directly​

ctbt run compiles in memory and runs the program without writing an executable:

ctbt run hello.bt
ctbt run hello.bt first "second argument"

The program keeps the caller's working directory, standard streams, and environment. An integer returned by main becomes the exit status. Compilation errors and unhandled runtime errors print diagnostics on stderr and exit with a nonzero status.

Compiler options go before the source file. Everything after it is passed to the program verbatim, including -- and arguments that start with -:

ctbt run --jobs 4 hello.bt --verbose
ctbt run -- -filename.bt

--jobs N sets the number of parallel compile workers (1 to 32, default 4). --bttls enables the optional TLS provider when ctbt was built with it. -o, --target, and --debug are build options and are rejected by run.

Linux executable scripts​

Put this shebang on the first line, with LF line endings:

#!/usr/bin/env -S ctbt run
include "io";

infallible fn main() -> int {
println("Hello!");
return 0;
}

Mark the file executable and run it:

chmod +x hello.bt
./hello.bt

BT ignores a shebang on the first line, so the same file still works with ctbt run on Windows and ctbt build anywhere.

Windows file association​

Register the current compiler for .bt files for your Windows user:

ctbt associate

This adds BT Script to Open with, running "<compiler path>" run -- "%1" %*. It becomes the default only when .bt has no per-user default yet. If an editor already opens .bt files, choose Open with → BT Script and make it the default to run scripts by double-clicking. The registration stores the compiler's absolute path, so run the command again after moving the compiler.

No administrator rights are needed.

Remove the registration with:

ctbt associate --remove

The entry point​

main takes no parameters and returns void or int. An int result becomes the process exit status. A program with no main, or with a main of any other shape, fails to compile.

include "io";

infallible fn main() -> void {
println("No explicit exit status");
}

Like every fn without infallible, main may fail. A fallible main can propagate errors with ?:

include "io";
include "time";

fn main() -> int {
timer_after(0.05)?;
println("Done");
return 0;
}

An unhandled error from main ends the program with a failure status.

When main returns, the program ends. Tasks started with branch that are still running are dropped without finishing, so join any work that must complete first (see Concurrency).

Command-line arguments​

process_arg_count() returns the number of arguments. process_arg(index) returns one argument; it is fallible because the index may be out of range.

include "process";
include "io";

fn main() -> int {
for (int index = 0; index < process_arg_count(); index++) {
string argument = process_arg(index)?;
println(argument);
}
return 0;
}

Argument zero is the executable path for a built program and the source path under ctbt run.

Multiple source files​

Files in the same folder form one package. They see each other's declarations without an include:

// greeting/main.bt
infallible fn main() -> int {
print_message();
return 0;
}
// greeting/messages.bt
include "io";

infallible fn print_message() -> void {
println("Hello from another source file");
}

Pass any file of the package to ctbt. It loads that file's package and every package it includes:

ctbt build -o greeting greeting/main.bt

Each file includes the packages it uses itself: messages.bt includes io for println, and main.bt needs no include.

Code in another folder is another package. A file includes it by module path, which requires a module definition such as bt.module.json. See Functions and modules.

Building a program artifact​

A program that runs BT scripts, such as a cTurtle game, loads a compiled program artifact (.ctbt) instead of an executable:

ctbt artifact -o greeting.ctbt greeting/main.bt

An artifact is not a standalone program; you can't run it by itself.

Next steps​

Continue with Language basics, then Error handling and Concurrency. Those three chapters cover the rules that differ most from C-family languages.