Skip to main content

A modern, statically typed scripting language with bytecode compilation and virtual machine execution

Project description

Tress

Release License: MIT

Tress is a modern, statically typed scripting language featuring robust type inference, Object-Oriented Programming (OOP) capabilities, exception handling, modular imports, and advanced language design safety features. It combines the safety of static typing with the ease of use of a scripting language.

Table of Contents


Key Features

  • Static Type System: Declares variable types explicitly or infers them automatically.
  • First-Class Functions & Lambdas: Full support for closures, anonymous functions, and lambdas with explicit return types.
  • Object-Oriented Programming: Clean class declarations, constructors, method definitions, and inheritance using extend, this, and parent.
  • Built-in Testing & Benchmarking: Native test and bench blocks to assert and profile execution speed.
  • Design by Contract (DbC): Pre- and post-condition assertions using @pre and @post.
  • Formal Verification Loops: The converge loop enforces proven loop termination at runtime.
  • Asynchronous execution: Direct support for async and await promises.
  • Standard Library Modules: Bundled utilities for math and array operations.
  • Robust Error Handling: Java-style try-expect-final blocks for safe runtime execution.
  • Modular Imports: Import external .trs source files using source "path.trs" as alias.
  • Multi-Platform Native Binaries: Built-in support for compiling into standalone binaries for macOS, Linux, and Windows using PyInstaller.

Quick Look

Tress Variables & Types Tress Functions & Lambdas

Tress Classes & Inheritance


Syntax & Features Guide

[!IMPORTANT] Semicolon ; is optional at the end of all statements.

0. Data Types

  • Integer: Represents both signed and unsigned numbers without decimal places.
  • Floating Point: Represents numbers with decimal places.
  • Boolean: Represents condition true or false.
  • String: Represents characters and words.
  • Array: Collection of items of the same type that can shrink and grow.
  • Set: Collection of items of the same type with fixed ordering and uniqueness.
  • Map: Collection of key-value pairs.
  • Box: Collection of mixed-type items that can shrink and grow (unordered).

1. Variables and Constants

Variables can be declared statically using init (requires explicit type annotations) or dynamically inferred using let.

// Mutable Variable with type specified
init int: age = 25
init str: name = "Alice"
init bool: isActive = true

// Immutable Variable with type inferred
let score = 98.5          // Infers float
let greeting = "Hello!"   // Infers str

[!NOTE] Constant variables can be declared using the const prefix.


2. Control Flow

Tress supports standard if-else conditionals, while loops, and for loops (including foreach iteration).

// Conditionals
if age >= 18 {
    disp("Access granted")
} else {
    disp("Access denied")
}

// Foreach Loop
let list = [10, 20, 30]
for item in list {
    disp(item);
}

// While Loop
let count = 5
while count > 0 {
    disp(count);
    count = count - 1;
}

[!IMPORTANT] Use cont instead of continue in loops. The break keyword behaves normally.


3. Functions & Lambdas

Define reusable functions with the fnc keyword. You can declare argument types, return types, and default values.

// Standard function
fnc add:int(a:int, b:int) {
    return a + b
}

// Function with default parameter values
fnc greet:str(name:str = "Guest") {
    return "Hello, " + name
}

// Lambdas (Anonymous inline functions)
let multiply = fnc? x:int, y:int -> x * y
let result = multiply(6, 7) // 42

4. Classes & Inheritance

Tress features a clean prototype-based class system. You can define fields, constructors, and extend parent classes.

class Animal {
    init str: name
    
    // Constructor (uses class name as function name)
    fnc Animal(name: str) {
        this.name = name
    }
    
    fnc speak() {
        disp(this.name + " makes a sound")
    }
}

class Dog extend Animal {
    fnc Dog(name: str) {
        parent.Animal(name) // Call parent constructor
    }
    
    fnc speak() {
        disp(this.name + " barks!")
    }
}

let pet = Dog("Buddy")
pet.speak() // Prints: "Buddy barks!"

5. Exception Handling

Safely capture runtime failures using try-expect-final blocks:

try {
    let result = 10 / 0
} expect error {
    disp("Error caught: " + error)
} final {
    disp("Execution complete")
}

6. Pattern Matching

Use the match statement for elegant, conditional branches:

fnc test_match(x: int) {
    match (x) {
        case 1 -> disp("One")
        case 2 -> disp("Two")
        default -> disp("Other")
    }
}

7. Generics

Declare parameter types generically using the *T notation to support multiple types with static compile-time verification:

fnc identity(*T, x: *T) {
    return x;
}

let int: res_int = identity(42);
let str: res_str = identity("Hello Generic World!");

8. String Interpolation

Embed variables directly inside string literals by prefixing the string with $ and wrapping variables in curly braces {}:

let str: name = "World"
let int: age = 25
let str: greeting = $"Hello {name}, you are {age} years old!"
disp(greeting)

9. Async / Await

Tress supports asynchronous execution using promises and native delayed delays:

async fnc calculate:int(x: int) {
    let delay_val = await mock_delay(10, x * 2);
    return delay_val;
}

let p = calculate(5);
disp(await p); // Prints 10 after a 10ms non-blocking delay

10. Advanced Decorators & Design by Contract

Tress supports method wrapping decorators and pre/post-condition validation:

Design by Contract (DbC)

Define function contracts using @pre (pre-condition) and @post (post-condition). Tress asserts these during runtime:

@pre[b != 0]
@post[result == a / b]
fnc div:int(a:int, b:int) {
    return a / b;
}

Code Decorators

  • @memoize: Automatically caches function results for unique arguments to speed up recursive computations (e.g. Fibonacci).
  • @debounce[ms]: Limits how frequently a function can run, delaying execution until after the specified milliseconds of inactivity.
@memoize
fnc fib:int(n: int) {
    if n <= 1 { return n; }
    return fib(n - 1) + fib(n - 2);
}

@debounce[50]
fnc log_event(val: int) {
    disp("Logged:", val);
}

11. Advanced Verification (Ghost, Converge, Lazy, Pipe)

Ghost Variables

ghost variables exist only within the static type checker's compile-time phase for verification. They generate zero runtime overhead and do not exist in the executable environment:

ghost let int: maxRetries = 5;

Converge Loops

A loop that requires a proven decrease in a specified "variant" value every iteration to guarantee loop termination. If the variant does not decrease, the runtime throws a termination error:

init int: n = 64
converge (n) while (n > 1) {
    n = n / 2; // n strictly decreases, proving termination
}

Lazy Evaluation

Defer the computation of an expression until its value is first accessed, after which the calculated value is cached:

lazy let int: result = expensive_computation();
// ... computation not run yet ...
let int: x = result; // Evaluated and cached here!

Pipeline Operator (|>)

Chain function calls from left to right, passing the left-side expression as the first argument to the right-side function:

let int: result = 2 |> addOne() |> triple() |> square();
// Equivalent to: square(triple(addOne(2)))

12. Call Stack & Variable Introspection (tress)

Tress provides a special built-in tress object that allows developers to dynamically inspect and modify variables and arguments on the call stack at runtime.

Features

  • Writable local slot access: Read and modify variables by their 0-based local stack slot index using tress[index].
  • Dynamic name lookup: Read and modify variables by their string identifier name using tress["varName"].
  • Stack frame traversal: Inspect any calling parent stack frame using tress.caller[index] (where tress.caller traverses up 1 frame, and chaining tress.caller.caller... goes deeper).
  • Metadata queries: Check a variable's type name using tress.type(index) or get its original variable identifier string using tress.name(index).
fnc my_func:int(a:int) {
    let name_a = tress.name(0);
    disp("First parameter name:", name_a); // Prints: "a"

    fnc child:int(b:int) {
        // Read caller frame parameter 'a'
        let parent_a = tress.caller[0];
        disp("Parent parameter value:", parent_a); // Prints: 42

        // Read variable by string name
        let b_val = tress["b"];

        // Modify local variable 'b' via index
        tress[0] = 99;
        disp("New value of b:", b); // Prints: 99

        // Modify parent variable 'a' via caller name
        tress.caller["a"] = 123;
        return 0;
    }

    child(10);
    disp("New value of a:", a); // Prints: 123
    return 0;
}

my_func(42);

Standard Library Modules

Tress includes a growing collection of core modules. They are imported via the source keyword.

std_math.trs

Includes algebraic operations, range conversions, trigonometry, and statistical utilities.

Function Signature Detail
area area(radius: float) -> float Returns the area of a circle.
deg_to_rad deg_to_rad(deg: float) -> float Converts degrees to radians.
rad_to_deg rad_to_deg(rad: float) -> float Converts radians to degrees.
hypot hypot(a: float, b: float) -> float Calculates the hypotenuse $\sqrt{a^2 + b^2}$.
factorial factorial(n: int) -> int Computes the factorial of a positive integer.
gcd gcd(a: int, b: int) -> int Computes the Greatest Common Divisor.
sin sin(x: float) -> float Standard sine trigonometric approximation.
cos cos(x: float) -> float Standard cosine trigonometric approximation.
tan tan(x: float) -> float Standard tangent trigonometric approximation.
fibonacci fibonacci(n: int) -> int Computes the Fibonacci sequence.
exp exp(x: float) -> float Exponential function $e^x$.
ln ln(x: float) -> float Natural logarithm $\ln(x)$.
log log(x: float, base: float) -> float Logarithm with arbitrary base.
sinh / cosh / tanh sinh(x: float) -> float Hyperbolic trig functions.
lcm lcm(a: int, b: int) -> int Least Common Multiple.
is_prime is_prime(n: int) -> bool Primality check.
mean mean(array) -> float Arithmetic mean of an array.
source "std_math.trs" as math

let x = math.fibonacci(3) // 2
let y = math.factorial(3) // 6
let z = math.area(4.0) // 50.26544

std_array.trs

Generic utility module for manipulating list-like collections.

Function Signature Detail
contains contains(array, target) -> bool Searches for target in the array.
find_index find_index(array, target) -> int Returns the zero-based index of target or -1 if not found.
sum sum(array) -> float Returns the mathematical sum of all numeric array elements.
reverse reverse(array) -> arr Returns a reversed copy of the array.
map_arr map_arr(array, fn) -> arr Maps a function over each element of the array.
filter filter(array, fn) -> arr Filters elements matching the predicate function.
reduce reduce(array, fn, initial) -> int Reducer function.
minimum minimum(array) -> int Returns the minimum value in the array.
maximum maximum(array) -> int Returns the maximum value in the array.
source "std_array.trs" as array_util

let numbers = [1, 2, 3, 4, 5]
let found = array_util.contains(numbers, 3) // true
let index = array_util.find_index(numbers, 4) // 3

std_string.trs

String processing and manipulation utilities.

Function Signature Detail
split split(s: str, delimiter: str) -> arr Splits string into array by delimiter.
join join(separator: str, parts: arr) -> str Joins array elements into string with separator.
repl repl(s: str, old: str, new: str) -> str Replaces all occurrences of old with new.
contain contain(s: str, sub: str) -> bool Checks if string contains substring.
startswith startswith(s: str, prefix: str) -> bool Checks if string starts with prefix.
endswith endswith(s: str, suffix: str) -> bool Checks if string ends with suffix.
lookup lookup(s: str, sub: str) -> int Returns count of substring occurrences.
str_index str_index(s: str, sub: str) -> int Returns index of first occurrence, or -1.
substr substr(s: str, start: int, end: int) -> str Extracts substring from start to end.
to_arr to_arr(s: str) -> arr Converts string to array of characters.
concat concat(s1: str, s2: str) -> str Concatenates two strings.
len len(s: str) -> int Returns length of string.
trim trim(s: str) -> str Removes leading/trailing whitespace.
upper upper(s: str) -> str Converts to uppercase.
lower lower(s: str) -> str Converts to lowercase.
revert revert(s: str) -> str Reverses the string.
source "std_string.trs" as str

let parts = str.split("a,b,c", ",")   // ["a", "b", "c"]
let upper = str.upper("hello")         // "HELLO"
let has = str.contain("foobar", "bar") // true

std_filesys.trs

File system operations for reading, writing, and navigating files and directories.

Function Signature Detail
read_file read_file(path: str) -> str Reads entire file content as string.
write_file write_file(path: str, content: str) -> void Writes content to file (overwrites).
append_file append_file(path: str, content: str) -> void Appends content to file.
exists exists(path: str) -> bool Checks if path exists.
delete_file delete_file(path: str) -> void Deletes a file.
move_file move_file(old: str, new: str) -> void Moves/renames a file.
file_size file_size(path: str) -> int Returns file size in bytes.
mkdir mkdir(path: str) -> void Creates a directory.
rmdir rmdir(path: str) -> void Removes a directory.
listdir listdir(path: str) -> arr Lists directory contents.
isdir isdir(path: str) -> bool Checks if path is a directory.
isfile isfile(path: str) -> bool Checks if path is a file.
pwd pwd() -> str Returns current working directory.
chdir chdir(path: str) -> void Changes working directory.
ext ext(path: str) -> str Returns file extension.
filename filename(path: str) -> str Returns file name from path.
dirname dirname(path: str) -> str Returns directory name from path.
join join(path1: str, path2: str) -> str Joins two path segments.
source "std_filesys.trs" as fs

fs.write_file("output.txt", "Hello Tress!")
let content = fs.read_file("output.txt")
let files = fs.listdir(".")
disp(fs.exists("output.txt"))  // true

std_json.trs

JSON serialization and deserialization.

Function Signature Detail
load load(data: str) -> map Parses JSON string into a map/array.
dump dump(data) -> str Serializes a map/array to JSON string.
source "std_json.trs" as json

let obj = json.load("{\"name\": \"Alice\", \"age\": 25}")
let text = json.dump(obj)
disp(text)

std_request.trs

HTTP client for making web requests.

Function Signature Detail
get get(url: str, params: map, headers: map) -> str Sends HTTP GET request.
post post(url: str, body: str, params: map, headers: map) -> str Sends HTTP POST request.
put put(url: str, body: str, params: map, headers: map) -> str Sends HTTP PUT request.
delete delete(url: str, params: map, headers: map) -> str Sends HTTP DELETE request.
source "std_request.trs" as http

let response = http.get("https://api.example.com/data", {}, {})
disp(response)

std_argparse.trs

Command-line argument parser using an OOP-style Parser class.

Method Signature Detail
Parser Parser(description: str) Creates a new parser instance.
add_option add_option(name: str, short: str, default: str, help: str) Adds a named option with default.
add_flag add_flag(name: str, short: str, help: str) Adds a boolean flag.
parse parse() -> map Parses CLI arguments and returns a map.
source "std_argparse.trs" as ap

let parser = ap.Parser("My CLI Tool")
parser.add_option("--name", "-n", "World", "Your name")
parser.add_flag("--verbose", "-v", "Enable verbose output")
let args = parser.parse()
disp(args)

CLI & Usage

Running Locally

To execute a .trs source file, invoke the tress runner script or run the interpreter via Python directly:

./tress script.trs
# Or
python3 src/interpret/exec.py script.trs

Compiler Options

Usage: tress <file.trs>
       tress -h/--help     Show help guide
       tress -v/--version  Show compiler version

Project Structure

graph TD
    A[Source Code: *.trs] --> B[Lexer: lexical.py]
    B --> C[Parser: typr_parser.py]
    C --> D[Type Checker: type_checker.py]
    D --> E[AST Evaluator: eval_ast.py]
    E --> F[Runtime Output]
  • lexical.py: Tokenizes the input stream using PLY.
  • typr_parser.py: Generates the Abstract Syntax Tree (AST) using LALR parser tables.
  • type_checker.py: Statically analyzes variable and expression types, inferring parameter types where omitted.
  • eval_ast.py: Performs execution by traversing the AST.
  • environment.py: Manages symbol scoping, closures, and class instance states.

CI/CD and Building Releases

We automate native, standalone builds for macOS, Linux, and Windows using GitHub Actions and PyInstaller.

1. Compile Locally

To build a standalone executable locally, run PyInstaller:

pip install -r requirements.txt
pyinstaller tress-ast.spec --clean

The compiled executable will be placed in dist/tress-ast (or dist/tress-vm).

2. GitHub Release Action

Our GitHub Actions pipeline is defined in .github/workflows/release.yml. On any new git version tag push (e.g. v0.1.0), the workflow:

  1. Spins up Ubuntu, macOS, and Windows runners.
  2. Compiles tress into a single binary for each platform.
  3. Automatically attaches tress-linux, tress-macos, and tress-windows.exe to a newly drafted GitHub Release.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tress_lang-0.1.2.tar.gz (71.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tress_lang-0.1.2-py3-none-any.whl (69.6 kB view details)

Uploaded Python 3

File details

Details for the file tress_lang-0.1.2.tar.gz.

File metadata

  • Download URL: tress_lang-0.1.2.tar.gz
  • Upload date:
  • Size: 71.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for tress_lang-0.1.2.tar.gz
Algorithm Hash digest
SHA256 17f5648b617bf6ac7335ba873c3a30d681c49020eddd8ead7d03f6671624d72d
MD5 e9dfaefaf9d044e4a68646b5dcc67d24
BLAKE2b-256 c2db879de7dc995f543da2794d4cf8486add5b6ce1435315b1173da241356c09

See more details on using hashes here.

File details

Details for the file tress_lang-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: tress_lang-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 69.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for tress_lang-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 88960ec2a866ae7574ddcaaead66298a9fc4c9ec19308d81b0056b4da83193de
MD5 e0fdbed91d55135615ace9ac345c3868
BLAKE2b-256 f9382dbd25b0f1c7277b0f4e3917544704c21d4ba486e244dccbf754eadfeaf0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page