The performant yet elegant and feature-packed programming language. Implemented with Rust.
Terbium is still a work in progress. You can contribute by simply cloning this repository, however.
This means some promises made here are merely goals we want to accomplish for Terbium.
require std;
func main() {
std.println("Hello, world!");
}
We want Terbium to meet the following:
- A language that doesn't take long to learn
- A language emphasizing strong and static types
Types are static, but type inference will exist - A language which is fast and performant
- A language which is elegant to write and emphasizes readability
- A language that utilizes a comprehensive analyzer that catches bugs before runtime
- A language which utilizes explicit mutability
We want to enforce a static type system in Terbium that isn't too restrictive:
- All variables, unless redeclared, will have a constant type
- Default all types to the
auto
type (Type inference)- When a type cannot be inferred, use the
any
type unless explicitly disabled (@trb:strict
)
- When a type cannot be inferred, use the
- Allow for a robust type system (think Generics)
Terbium designs static types like this so that while beginners don't have to learn Terbium with the complexity of a type system, and gradually implement these types as they learn more about them.
The static-type checker, along with other types of analysis (such as optimization), is run at compile-time*. This ensures that your code will run as expected with minimal errors before even running.
* If you run Terbium using its interpreter, analysis will be run immediately before runtime.
A very common pattern in more modernized languages are those which lack a "null" type.
We chose to keep null
but make it required to explicitly handle and propagate null
,
specifically with the static type-checker which is run at compile-time.
Luckily, doing such is easy.
There is also the ExplicitNullHandler
class which you can use to utilize
an "unwrap-like" interface over null
. This type is used in many of the
interfaces in Terbium's standard library.
We also want to make Terbium code as concise as possible, without sacrificing performance or readability.
Directly assign the result of an if
statement to a variable:
let x = if 1 + 1 == 2 {
std.println("1 + 1 is indeed 2!");
2
}
std.println(x); // 2
Call a function with the result of a match
statement:
std.println(match 1 + 1 {
1 -> "one",
2 -> "two",
else "other",
});
or... use non-expressions with match
:
std.println(match 1 + 1 {
2 -> {
let message = "two";
message
},
else {
let message = "other";
message
},
});
(above three inspired by Rust)
Null propagations and assertions:
std.println(x.y?.z!);
// equivalent to:
// if x.y { if x.y.z { std.println(x.y.z) } else { throw error } } else { std.println("null") }
(above inspired by TypeScript)
- terbium_analyzer: Analyzes Terbium code and houses the static type-checker. This is run at compile-time and apart from ensuring type-safety, will try picking as many places that could be optimized, and as many places that could lead to errors at runtime.
- terbium_bytecode: Transforms Terbium source code into Terbium bytecode, and intermediate representation of Terbium runtime code that can be either interpreted or compiled.
- terbium_grammar: Tokenizes Terbium code and transforms it into an Abstract Syntax Tree (AST).
- terbium_interpreter:
The interpreter which interprets and evaluates code generated from
terbium_grammar
. - terbium: The top-level Rust crate providing access to all other Rust crates listed here. This also houses the source for Terbium's CLI implementation.
- lib: The Terbium standard library and stub declarations for builtin objects/types.
See CONTRIBUTING.md for details.
Terbium is a project by jay3332.
Thanks to the following core contributors:
- Cryptex-github: Creating workflows + General contributions