- There is currently no repo or mirror, because I'm don't have the money for that
- Contact me or make a PR if you want to do that
- Also most of the docs were run through DeepL as English is not my first language and I'm not exactly good at it!
- Also Tree is a just for fun project by me, made so that I will understand C
- Needs CMake and Make
With pkgtree runtime (default):
make
./tree ../pkgtree/pkgtree.treeWithout pkgtree runtime (stubs only):
mkdir -p build
cd build
cmake -DWITH_PKGTREE=OFF ..
cmake --build . --config Release
./tree ../pkgtree/pkgtree.treeWith pkgtree:
gcc -o tree main.c pkgtree_runtime.c -lmWithout pkgtree:
gcc -o tree main.c -lm./tree_parser script.treeCreate hello.tree:
print("Hello from Tree!");
x = To,Int(42);
y = to_float(3.14);
name = to.String(x);
print("Answer: ", name);
Run it:
./tree_parser hello.treepkg(){
"math";
};
x = 16.0;
result = math::sqrt(x);
print("sqrt(16) = ", to.String(result));
base = 2.0;
exp = 10.0;
power = math::pow(base, exp);
print("2^10 = ", to.String(power));
angle = 0.0;
sine = math::sin(angle);
cosine = math::cos(angle);
print("sin(0) = ", to.String(sine));
print("cos(0) = ", to.String(cosine));
Output:
pkg(){
"random";
};
random::rand-seed(12345);
r1 = random::rand();
r2 = random::rand();
print("Random 1: ", to.String(r1));
print("Random 2: ", to.String(r2));
dice = random::rand-int(6);
print("Dice roll (0-5): ", to.String(dice));
coin = random::rand-int(2);
result = coin;
print("Coin (0=heads, 1=tails): ", to.String(result));
Answer: 42
✅ Lexer: Tokenizes Tree source with proper indentation tracking
✅ Parser: Recursive descent parser building an AST
✅ Interpreter: Direct AST evaluation with runtime values
✅ Static Typing: Type inference via naming conventions
✅ Built-in Functions: print(), To,Int(), to_float(), to.String()
✅ Collections: Lists and dictionaries with config syntax
✅ Variables: Symbol table with proper scoping
✅ Packages: Built-in math and random packages with namespaced functions
Source Code (.tree)
↓
Lexer (tokenization + indentation handling)
↓
Parser (AST construction)
↓
Interpreter (evaluation + execution)
↓
Output
main.c: Complete implementation (~800 lines)- Lexer:
lex_all(), token types - Parser:
parse_program(),parse_expr(),parse_stmt() - Interpreter:
eval_program(),eval_expr(), builtin functions - Value system: runtime type representation
- Symbol table: variable storage
- Lexer:
# Variables and assignment
x = 42;
name = "Alice";
# Function calls require parentheses
print("Hello", " ", "World");
# Type conversion by naming convention
int_val = To,Int("100"); # PascalCase,WithComma → int
float_val = to_float(42); # snake_case → float
str_val = to.String(int_val); # dot.case → string
# Math operations
sqrt_16 = to_sqrt(16.0); # 4.0
power = to_pow(2.0, 3.0); # 8.0
sum = To,Add(5, 3); # 8
product = To,Mul(4, 5); # 20
# String operations
upper = to.Upper("hello"); # "HELLO"
len = to.Length("hello"); # 5
# Lists (with optional config entries)
numbers = [1, 2, 3];
configured = [1, 2, 3, separator="\n", mode="fast"];
# Dictionaries
person = {name="Bob", age=To,Int(30), active=1};
| Category | Function | Returns | Notes |
|---|---|---|---|
| Output | print(...) |
nil | Prints all args + newline |
| Conversion | To,Int(x) |
int | String/float to int |
to_float(x) |
float | String/int to float | |
to.String(x) |
string | Any to string | |
| Math (Float) | to_sqrt(x) |
float | Square root |
to_pow(b,e) |
float | Power function | |
to_abs(x) |
float/int | Absolute value | |
to_sin(x) |
float | Sine (radians) | |
to_cos(x) |
float | Cosine (radians) | |
to_floor(x) |
float | Round down | |
to_ceil(x) |
float | Round up | |
| Integer Math | To,Add(a,b) |
int | Addition |
To,Sub(a,b) |
int | Subtraction | |
To,Mul(a,b) |
int | Multiplication | |
To,Div(a,b) |
int | Integer division | |
| Strings | to.Length(s) |
int | String/list/dict length |
to.Upper(s) |
string | Uppercase | |
to.Lower(s) |
string | Lowercase | |
| Containers | get-length(c) |
int | Number of items |
get-first(l) |
any | First item | |
get-last(l) |
any | Last item | |
get-type(x) |
string | Type name (int/float/string/list/dict/nil) |
Domco/
├── main.c # Parser + interpreter implementation
├── TREE_LANGUAGE.md # Full language documentation
└── README.md # This file
x = To,Int(10);
y = to_float(x);
z = to.String(y);
print("Result: ", z);
x = to_float(16.0);
sqrt_x = to_sqrt(x);
print("sqrt(16) = ", to.String(sqrt_x));
a = 10;
b = 3;
sum = To,Add(a, b);
product = To,Mul(a, b);
print(to.String(a), " + ", to.String(b), " = ", to.String(sum));
print(to.String(a), " * ", to.String(b), " = ", to.String(product));
text = "tree language";
upper_text = to.Upper(text);
lower_text = to.Lower(text);
length = to.String(to.Length(text));
print("Original: ", text);
print("Uppercase: ", upper_text);
print("Lowercase: ", lower_text);
print("Length: ", length);
numbers = [5, 10, 15, 20, 25];
first = get-first(numbers);
last = get-last(numbers);
len = to.String(get-length(numbers));
item_type = get-type(first);
print("First: ", to.String(first));
print("Last: ", to.String(last));
print("Count: ", len);
print("Item type: ", item_type);
-
Create a
builtin_function_name()function:static Value builtin_my_func(AstNode **args, int argc, SymTable *table) { if (argc != expected_argc) { fprintf(stderr, "my_func expects %d argument(s)\n", expected_argc); return val_nil(); } // Evaluate arguments and perform operation Value result = ...; return result; }
-
Register it in
eval_call():if (strcmp(name, "my.Func") == 0) return builtin_my_func(args, argc, table);
Add new naming patterns:
- Pattern:
lowercase_with_underscore()for float ops (existing) - Pattern:
identifier_identifier()for new custom family - Update
eval_call()to recognize and dispatch
Create .tree files and run:
./tree_parser test_file.treeCheck for:
- Correct output
- No memory leaks (use
valgrindif available) - Proper error messages on invalid syntax
✅ Package system with pkg() syntax
✅ Built-in math package (sqrt, pow, abs, sin, cos, floor, ceil)
✅ Built-in random package (rand, rand-int, rand-seed)
✅ Namespace resolution with :: syntax
✅ Package aliases with as keyword
- Operators:
+,-,*,/,%,==,!=,<,>,and,or - Tree Package Loading: Load
.treefiles as packages - C Extension Loading: Load compiled
.so/.dllC extensions - Package Versioning: Support version checking (
pkg,versionsyntax) - Operators:
+,-,*,/,%,==,!=,<,>,and,or - Indexing:
list[n],dict[key] - Control Flow:
if/elsif/else,for,while,break,continue - Custom Functions:
defkeyword for user-defined functions - Comments:
#for line comments - Error Handling:
try/catch, graceful error recovery - Pattern Matching: Destructuring for lists/dicts
gcc -o tree_parser main.c -lm- Lexing: O(n) where n = source code length
- Parsing: O(m) where m = number of tokens
- Evaluation: O(p × q) where p = program statements, q = avg expression depth
For typical scripts (<1000 LOC), execution is sub-millisecond.
To extend Tree:
- Understand the lexer, parser, and interpreter flow
- Add new tokens to
TokenKindenum if needed - Extend the parser (
parse_expr,parse_stmt) - Add evaluation logic (
eval_expr,eval_call) - Test thoroughly with
.treeexamples
- LGPL-v3
- ! AI was slightly used - only for help with errors that didn't even exist on stackoverflow = It was lobotomized so it couldn't write the actual full code !
- Also some basic writing help AIs were used to make the docs as I suck at documentation and didn't want to do it...
- Language Design: https://en.wikipedia.org/wiki/Programming_language
- Interpretation: https://craftinginterpreters.com/
- C Memory: Standard C library (
malloc,free)
Version: 1.0
Created: March 2026
Language: C (C99 compatible)