Language Reference
A complete reference for the Techlang programming language.
Types
| Type | Description | Example |
|---|---|---|
int | 32-bit signed integer | 42 |
float | 32-bit floating point | 3.14 |
double | 64-bit floating point | 3.14159265 |
char | Single character | 'a' |
string | String of characters | "hello" |
bool | Boolean value | true or false |
ArrayOf(T) | Array of type T | {1, 2, 3} |
PointerOf(T) | Pointer to type T | std.addressOf(x) |
any | Pointer-sized integer; castable to any type | 42 |
Default Values
Every type has a base value used when declaring struct instances:
| Type | Default |
|---|---|
int | 0 |
float / double | 0.0 |
char | '\0' |
string | "" |
bool | false |
| struct | all fields set to their base values |
Variables
Declaration
int x = 5;
float f = 3.14;
double d = 3.14159265;
char c = 'a';
string s = "hello world";
bool b = true;
bool b2 = 0; // same as falseModifiers
float pi = 3.14 [const]; // cannot be reassignedAssignment
x = 10;
x += 5;
x -= 3;
x *= 2;
x /= 4;Operators
Arithmetic
int a = 10 + 3; // 13
int b = 10 - 3; // 7
int c = 10 * 3; // 30
int d = 10 / 3; // 3
int e = 10 % 3; // 1Comparison
bool a = 5 == 5; // true
bool b = 5 != 3; // true
bool c = 5 > 3; // true
bool d = 5 < 3; // false
bool e = 5 >= 5; // true
bool f = 5 <= 3; // falseLogical
bool a = true && false; // false
bool b = true || false; // true
bool c = !true; // falseCasting
Use the as keyword to cast between types. Variables of type any can be cast to all types.
float x = 3.14;
int y = x as int; // 3Control Flow
If / Else
if (x > 0) {
std.print_string("positive");
} else {
std.print_string("not positive");
}While
while (x > 0) {
x -= 1;
}For
The for loop has three comma-separated parts: declaration, condition, increment.
for (int i = 0, i < 10, i += 1) {
std.print_int(i);
}Functions
Declaration
function add(int a, int b) returns int {
return a + b;
}Calling
int result = add(3, 4);Void Functions
Use none as the return type for functions that don't return a value.
function greet(string name) returns none {
std.print_string(name);
}Recursion
function fibonacci(int n) returns int {
if (n <= 1) {
return n;
}
return fibonacci(n - 1) + fibonacci(n - 2);
}External Functions
Link to C implementations with the extern keyword:
function my_func(int x) returns int extern "c_function_name" {}Arrays
Declaration
ArrayOf(int) nums = {1, 2, 3, 4, 5};
ArrayOf(float) floats = {1.1, 2.2, 3.3};
ArrayOf(string) words = {"hello", "world"};Access
int first = nums[0];
nums[0] = 10;Length
ArrayOf(int) x = {1, 2, 3, 4};
std.print(x.length); // 4Passing to Functions
function sum(ArrayOf(int) arr, int size) returns int {
int total = 0;
for (int i = 0, i < size, i += 1) {
total += arr[i];
}
return total;
}
int result = sum(nums, 5);Strings
Declaration
string s = "Hello world";
string empty = "";Concatenation
Strings can be concatenated with the + operator or via std.concat():
string first = "Hello";
string second = " World";
string result = first + second; // "Hello World"
string r2 = std.concat("foo", "bar"); // "foobar"Length
string s = "hello";
std.print(s.length); // 5Standard Library String Functions
| Function | Description |
|---|---|
std.concat(a, b) | Concatenate two strings |
std.string_length(s) | Get string length |
std.string_equals(a, b) | Compare two strings (returns bool) |
std.string_substring(s, start, end) | Get substring |
Pointers
Getting a Pointer
int x = 5;
PointerOf(int) p = std.addressOf(x);Dereferencing
int value = std.deref(p);Writing Through a Pointer
std.storeAt(p, 10); // x is now 10Pass by Reference
function increment(PointerOf(int) p) returns none {
int current = std.deref(p);
std.storeAt(p, current + 1);
}
int x = 5;
increment(std.addressOf(x));
// x is now 6Structs
Declaration
struct person = {
int age;
float height;
string name;
}Instantiation
person p; // all fields set to base valuesField Access
p.age = 30;
p.height = 1.75;
p.name = "Alice";Passing to Functions
function greet(person p) returns none {
std.print_string(p.name);
}Enums
Declaration
enum direction = {
NORTH, // 0
SOUTH, // 1
EAST, // 2
WEST // 3
}Manual Values
enum levels = {
EASY, // 0
MEDIUM, // 1
HARD = 9, // 9
EXTREME // 10
}Usage
Enum values are integers and can be used anywhere an int is expected:
int d = NORTH;
if (d == NORTH) {
std.print_string("Going north!");
}Imports
Split code across multiple files using !import. The alias prefixes all functions from that file.
!import(math.tec) as math;
int result = math.add(3, 4);Imports are resolved relative to the current file's directory. Circular imports are detected and prevented.
Standard Library
!import(std.tec) as std;Error Handling
The recommended pattern for error handling is returning error codes and using std.exit():
function divide(int a, int b) returns int {
if (b == 0) {
std.exit(1); // exit with error code
}
return a / b;
}I/O
File handles are always of type any. Pass the file mode as a string ("r", "w", "a").
// Writing
any f = std.file_open("hello.txt", "w");
std.file_write(f, "Hello from Techlang!\n");
std.file_close(f);
// Reading
any f2 = std.file_open("hello.txt", "r");
string line = std.file_read_line(f2);
int eof = std.file_eof(f2); // 1 if EOF
std.file_close(f2);
// Deleting
std.file_delete("hello.txt");Standard Library
Import with !import(std.tec) as std;
Printing
std.print_int(42);
std.print_float(3.14);
std.print_string("hello");
std.print_char('a');
std.print_bool(true);
std.print_newline();Input
int x = std.read_int();
float f = std.read_float();Math
float s = std.sqrt(16.0); // 4.0Strings
| Function | Description |
|---|---|
std.concat(a, b) | Concatenate two strings |
std.string_length(s) | Length of a string |
std.string_equals(a, b) | Compare two strings |
std.string_substring(s, start, end) | Extract a substring |
Pointers
PointerOf(int) p = std.addressOf(x);
int val = std.deref(p);
std.storeAt(p, 10);File I/O
| Function | Description |
|---|---|
std.file_open(path, mode) | Open a file ("r", "w", "a") |
std.file_write(f, s) | Write string to file |
std.file_read_line(f) | Read next line from file |
std.file_eof(f) | Returns 1 if at end-of-file |
std.file_close(f) | Close a file handle |
std.file_delete(path) | Delete a file |
Program Control
std.exit(0); // exit with code 0 (success)
std.exit(1); // exit with code 1 (error)VecTec — GPU Compute
VecTec is a companion language to Techlang that runs code on the GPU. VecTec kernels are written in .vtec files and called from Techlang with zero boilerplate — the compiler handles all CUDA memory management automatically.
Requirements
VecTec requires an NVIDIA GPU and the CUDA toolkit installed.
# Arch Linux
sudo pacman -S cuda
# Ubuntu
sudo apt install nvidia-cuda-toolkitWriting a Kernel
Kernels are functions that run on the GPU. Every thread runs the kernel simultaneously — use threadId() to know which element to process.
// arrays.vtec
kernel addArrays(
ArrayOf(float) a,
ArrayOf(float) b
) returns ArrayOf(float) {
int id = threadId();
return a[id] + b[id];
}Calling from Techlang
Import a .vtec file just like any other Techlang module. The compiler automatically compiles the kernel to PTX, generates the CUDA runtime wrapper, and links everything together.
!import(std.tec) as std;
!import(arrays.vtec) as gpu;
function main() returns none {
ArrayOf(float) a = {1.0, 2.0, 3.0, 4.0};
ArrayOf(float) b = {5.0, 6.0, 7.0, 8.0};
// runs on the GPU — zero boilerplate!
ArrayOf(float) result = gpu.addArrays(a, b);
std.print(result[0]); // 6.0
std.print(result[1]); // 8.0
}Built-in Functions
| Function | Description |
|---|---|
threadId() | Returns the current thread's ID (0 to N-1) |
threadCount() | Returns the total number of threads in the block |
Supported Types in Kernels
| Type | Notes |
|---|---|
int | 32-bit integer |
float | 32-bit float |
double | 64-bit float |
bool | 1-bit integer |
ArrayOf(T) | Passed as pointer — one element per thread |
How it Works
When you import a .vtec file, the Techlang compiler:
arrays.vtec
↓
VecTec compiler (LLVM NVPTX backend)
↓
arrays.ptx (GPU assembly)
↓
Auto-generated C wrapper with embedded PTX
↓
nvcc compiles wrapper → arrays_runtime.o
↓
Linked with your Techlang binary automaticallyKernel Rules
A few things to keep in mind when writing VecTec kernels:
- One thread processes one element — use
threadId()as the array index - The number of threads launched equals the size of the first array parameter
- Kernels cannot call Techlang functions
- No string or file I/O inside kernels
- Shared memory support coming in a future release
Comments
Techlang supports single-line comments with
//.