Quadrate is a stack-based programming language with a LLVM backend, designed for simplicity, expressiveness, and system-level programming.
Development Status: Active Development
// hello.qd
fn main( -- ) {
"Hello, World!" . nl
}
$ quadc hello.qd -o hello
$ ./hello
Hello, World!
Install the quadc compiler by following the installation guide.
The simplest program consists of a main function:
fn main( -- ) {
// Program starts here
}
The signature ( -- ) declares the stack effect: this function takes no inputs and returns no outputs.
Let's add two numbers:
fn main( -- ) {
5 3 + // Push 5 and 3, then add them
. nl // Print result and newline
}
Output:
8
The . operator prints a value, and nl prints a newline.
Functions declare their inputs and outputs explicitly:
fn square(n:f -- result:f) {
dup * // Duplicate n, then multiply
}
fn main( -- ) {
5.0 square . nl // Prints: 25.0
}
The signature (n:f -- result:f) means:
n)result)Quadrate provides rich stack manipulation:
fn main( -- ) {
1 2 3 // Stack: (1, 2, 3)
dup // Stack: (1, 2, 3, 3)
swap // Stack: (1, 2, 3, 3)
over // Stack: (1, 2, 3, 3, 2)
rot // Stack: (1, 2, 3, 2, 3)
}
Clean, expressive control structures:
fn classify(age:i -- ) {
dup 18 < if {
drop "Minor" . nl
return
}
dup 65 < if {
drop "Adult" . nl
return
}
drop "Senior" . nl
}
fn main( -- ) {
25 classify // Prints: Adult
}
Iterate with for loops:
fn main( -- ) {
// Print 0 through 9
0 10 1 for {
$ . nl // $ is the loop counter
}
}
Or use infinite loops with loop:
fn main( -- ) {
0 loop {
dup . nl
inc
dup 5 >= if {
drop break
}
}
}
Import modules for extended functionality:
use math
use str
fn main( -- ) {
// Trigonometry
45.0 math::sin . nl
// String manipulation
"hello world" str::upper . nl // Prints: HELLO WORLD
// More functions available
16.0 math::sqrt . nl // Prints: 4.0
}
Available standard library modules:
Built-in support for concurrent programming:
use time
fn worker( -- ) {
"Worker thread running" . nl
1000 time::Millisecond mul time::sleep
"Worker thread done" . nl
}
fn main( -- ) {
"Main thread starting workers" . nl
&worker spawn
&worker spawn
wait // Wait for first thread
wait // Wait for second thread
"All threads complete" . nl
}
Graceful error handling with stack unwinding:
fn validate(n:i -- ) {
dup 0 < if {
drop "Error: Negative value not allowed!" error
}
drop
}
fn main( -- ) {
5 validate // OK
-3 validate // Triggers error
}
Quadrate supports four types with automatic and explicit casting:
fn main( -- ) {
42 // Integer
3.14 // Float
"text" // String
&main // Pointer (function pointer)
// Type casting
42 castf // Convert int to float: 42.0
3.7 casti // Convert float to int: 3
42 casts // Convert int to string: "42"
}
fn bmi(weight:f height:f -- bmi:f) {
sq / // weight / (height * height)
}
fn main( -- ) {
70.0 1.75 bmi
dup . nl
25.0 > if {
"Overweight" . nl
} else {
"Normal weight" . nl
}
}
fn fib(n:i -- result:i) {
dup 2 gte if {
dup 1 - fib
swap 2 - fib
+
}
}
fn main( -- ) {
0 20 1 for {
$ dup fib . nl
}
}
use net
use str
fn handle_client(client:i -- ) {
client net::recv dup str::len 0 > if {
client swap net::send
}
client net::close
}
fn main( -- ) {
8080 net::listen
loop {
net::accept
&handle_client spawn detach
}
}
Organize code into reusable modules:
File: math_utils/module.qd
fn double(n:i -- result:i) {
2 *
}
fn triple(n:i -- result:i) {
3 *
}
File: main.qd
use math_utils
fn main( -- ) {
5 math_utils::double . nl // Prints: 10
5 math_utils::triple . nl // Prints: 15
}
Ensure cleanup code runs even on early return or error:
fn process_file( -- ) {
"Opening file" . nl
defer {
"Closing file" . nl
}
"Processing..." . nl
// Deferred code runs when function exits
}
fn main( -- ) {
process_file
}
Output:
Opening file
Processing...
Closing file
Quadrate comes with a complete development toolkit:
# Format a single file
quadfmt -w my_program.qd
# Format all .qd files in current directory
quadfmt -w *.qd
Quadrate's LSP server provides IDE features like:
Quadrate: Simple, powerful stack-based programming