Install
cmake -B build && cmake --build build./build/precious your_file.precious./out
Outputs a Linux ELF binary named after the input file via g++. The compiler generates C++ source code and lets g++ handle register allocation, optimization, and code generation.
Entry Point
Every program defines fn the_precious() — Precious' equivalent of C's main. The compiler emits a real int main() that calls it; a gives(n) inside it becomes the process exit code. Only fn definitions may live at top level.
// fib.precious
fn fib(n) {
if (n < 2) {
gives(n);
}
gives(fib(n - 1) + fib(n - 2));
}
fn the_precious() {
my i = 0;
while (i < 10) {
say(fib(i));
i = i + 1;
}
gives(0);
}
The compiler turns that into this C++, then g++ makes the binary:
#include <bits/stdc++.h>
long fib(long n);
long the_precious();
int main() {
return the_precious();
}
long fib(long n)
{
if (n < 2) {
return n;
}
return fib(n - 1) + fib(n - 2);
}
long the_precious()
{
long i = 0;
while (i < 10) {
std::cout << (fib(i)) << "\n";
i = i + 1;
}
return 0;
}
Missing, duplicate, or misplaced entry points get gollum errors: "Where is the precious?!", "There can be only one precious!", "The precious takes no arguments!". Statement examples below are snippets — they live inside a function body.
Variables
Declare with my. Assign with =.
my x = 42;
x = 10;
Type Annotations
Optional : type after the variable name. Inferred if omitted.
| Precious | C++ type | Description |
|---|---|---|
number | long | 64-bit integers |
word | std::string | Strings |
question | long | Booleans |
decimal | double | Floating-point |
letter | char | Single characters |
my x: number = 5;
my name: word = "gollum";
my y = 10; // inferred as number
my msg = "hello"; // inferred as word
Operators
Arithmetic
my result = 2 + 3 * 4 - 1; // 13
my negative = -5; // unary minus
gives(result);
Comparison
== != < > <= >= — return 1 or 0.
Boolean
and, or, ! — precedence: ! > and > or.
if (x > 0 and x < 10) { gives(1); }
if (!0) { gives(2); }
if (x == 1 or x == 5) { gives(3); }
If / Elif / Else
my x = 5;
if (x == 5) {
gives(10);
} elif (x > 3) {
gives(20);
} else {
gives(30);
}
While Loop
my i = 0;
while (i < 5) {
i = i + 1;
}
gives(i);
Scopes
my x = 5;
{
my y = 10;
gives(x + y);
}
say(expr) prints to stdout. Works with integers, string literals, and string variables.
say(42); // prints 42
say("hello"); // prints hello
my msg: word = "gollum";
say(msg); // prints gollum
Functions
Define with fn. Return with gives. Parameters support type annotations. Call order doesn't matter — the compiler emits forward declarations.
fn add(a, b) {
gives(a + b);
}
fn multiply(a, b) {
gives(a * b);
}
fn greet(name: word) {
say(name);
}
fn the_precious() {
say(add(2, 3)); // prints 5
greet("precious"); // prints precious
my result = multiply(6, 7);
say(result); // prints 42
}
Return type is auto-detected from gives, or annotate it: fn greet() -> word { ... }.
Arrays
Indexed collections. Require explicit type annotations: type[size].
my numbers: number[3] = [10, 20, 30];
say(numbers[0]); // prints 10
say(numbers[2]); // prints 30
numbers[1] = 99;
say(numbers[1]); // prints 99
my words: word[2] = ["hello", "world"];
say(words[0]); // prints hello
my i: number = 1;
say(numbers[i]); // prints value at index 1
Array Push / Pop
Add and remove elements dynamically with push and pop.
my arr: number[] = [1, 2, 3];
push arr, 4;
say(arr[3]); // prints 4
pop arr;
say(arr[2]); // prints 3
my words: word[] = ["hello", "world"];
push words, "foo";
say(words[2]); // prints foo
String Concatenation
Join strings with +.
my first = "hello";
my second = " world";
my combined = first + second;
say(combined); // prints hello world
my a = "foo";
a = a + "bar" + "baz";
say(a); // prints foobarbaz
String Indexing
Access individual characters with [].
my msg = "hello";
say(msg[0]); // prints h
say(msg[4]); // prints o
Keywords
| Keyword | What it does |
|---|---|
my | Declare a variable |
gives | Return a value / set exit code |
fn | Define a function |
say | Print to stdout |
if / elif / else | Conditionals |
while | Loop |
for | C-style for loop / for-each |
in | For-each iteration |
break / continue | Loop control |
switch / case / default | Pattern matching |
push / pop | Array push/pop |
and / or / ! | Boolean logic |
number / word / question / decimal / letter | Types |
[ ] | Array literals and index access |
Tests
bash run_tests.sh