Language Reference
This page documents every feature of the SUB language. For the standard library modules, see the Standard Library page.
Comments
SUB uses # for single-line comments. Everything after # on a line is ignored by the parser.
# This is a comment
let x = 42 # inline comment
Variables
Declare mutable variables with let and immutable bindings with const.
let name = "Alice" # mutable
const PI = 3.14159 # immutable — reassignment is an error
name = "Bob" # OK
# PI = 3 # Error: cannot reassign const
Data Types
SUB has seven value types. The type is inferred from the assigned value — there are no type annotations.
| Type | Example | Notes |
|---|---|---|
int | 42, -7 | Arbitrary-precision integers |
float | 3.14, -0.5 | 64-bit IEEE 754 double |
string | "hello" | UTF-8, double-quoted |
bool | true, false | Logical values |
null | null | Absence of a value |
array | [1, 2, 3] | Ordered, heterogeneous |
object | {"key": "value"} | Key-value map |
let count = 100
let price = 9.99
let greeting = "Hello"
let active = true
let nothing = null
let items = [1, "two", 3.0]
let config = {"debug": true, "level": 5}
Functions
Define functions with the fn keyword. Functions can take parameters and return values with return.
fn greet(name) {
return "Hello, " + name + "!"
}
fn add(a, b) {
return a + b
}
println(greet("World")) # Hello, World!
println(add(3, 4)) # 7
Note: Functions must be defined before they are called. There is no hoisting.
Control Flow
if / elif / else
let score = 85
if score >= 90 {
println("A")
} elif score >= 80 {
println("B")
} elif score >= 70 {
println("C")
} else {
println("F")
}
for-in loop
Iterate over arrays or ranges.
let fruits = ["apple", "banana", "cherry"]
for fruit in fruits {
println(fruit)
}
# Using range
for i in range(0, 5) {
println(i) # 0, 1, 2, 3, 4
}
while loop
let count = 0
while count < 5 {
println(count)
count = count + 1
}
do-while loop
Executes the body at least once before checking the condition.
let x = 10
do {
println(x)
x = x - 1
} while x > 0
switch / case / default
Pattern matching over integers, strings, and floats. No fall-through — each case runs its body and exits.
let day = "Monday"
switch day {
case "Monday":
println("Start of the week")
case "Friday":
println("Almost weekend")
case "Saturday", "Sunday":
println("Weekend!")
default:
println("Midweek")
}
Classes
SUB supports class-based object-oriented programming. Define classes with class, create instances with .new, and access fields with dot notation.
class Point {
let x = 0
let y = 0
}
let p = Point.new
p.x = 10
p.y = 20
println(p.x) # 10
println(p.y) # 20
Tip: Classes transpile to idiomatic constructs in every target language — structs in Rust, classes in Java/Python, interfaces in TypeScript.
Error Handling
Use try/catch/finally for error handling and throw to raise errors.
fn divide(a, b) {
if b == 0 {
throw "Division by zero"
}
return a / b
}
try {
let result = divide(10, 0)
println(result)
} catch err {
println("Error: " + err)
} finally {
println("Cleanup done")
}
Modules
Import standard library modules or user-defined modules with import.
import math
import arrays
import strings
let result = math.sqrt(144)
println(result) # 12
let nums = [3, 1, 4, 1, 5]
let total = arrays.sum_int(nums)
println(total) # 14
Operators
| Category | Operators |
|---|---|
| Arithmetic | + - * / % ** |
| Comparison | == != < > <= >= |
| Logical | && ! |
| Assignment | = |
| String concat | + |
let a = 10 + 5 # 15
let b = 10 % 3 # 1
let c = 2 ** 8 # 256
let d = "Hello" + " " + "World" # "Hello World"
let e = (5 > 3) && (2 != 4) # true
Built-in Functions
These functions are available globally without importing any module.
I/O
print(value)
Print a value to stdout without a trailing newline.
println(value)
Print a value to stdout followed by a newline.
input(prompt)
Read a line of text from stdin. Displays the optional prompt string.
Type Conversion
str(value)
Convert any value to its string representation.
int(value)
Convert a string or float to an integer.
float(value)
Convert a string or integer to a float.
type(value)
Return the type name of a value as a string: "int", "float", "string", "bool", "null", "array", "object".
Collections
len(value)
Return the length of a string, array, or object.
push(array, value)
Append a value to the end of an array.
pop(array)
Remove and return the last element of an array.
Math
abs(value)
Return the absolute value of a number.
min(a, b)
Return the smaller of two numbers.
max(a, b)
Return the larger of two numbers.
sqrt(value)
Return the square root of a number.
floor(value)
Round a float down to the nearest integer.
ceil(value)
Round a float up to the nearest integer.
round(value)
Round a float to the nearest integer.
String Operations
upper(string)
Return the string with all characters converted to uppercase.
lower(string)
Return the string with all characters converted to lowercase.
trim(string)
Remove leading and trailing whitespace.
split(string, delimiter)
Split a string by a delimiter and return an array of substrings.
join(array, delimiter)
Join an array of strings with a delimiter into a single string.
substring(string, start, end)
Return a portion of the string from index start to end (exclusive).
contains(string, needle)
Return true if the string contains the substring.
replace(string, old, new)
Return a new string with all occurrences of old replaced by new.
char_at(string, index)
Return the character at the given index.
Utility
range(start, end)
Return an array of integers from start (inclusive) to end (exclusive).
Networking
net_fetch(url)
Perform an HTTP GET request and return the response body as a string.
net_post(url, body)
Perform an HTTP POST request with the given body and return the response.
net_download(url, path)
Download the contents of a URL and save them to a local file at path.
UI DSL
SUB includes a first-class declarative UI syntax for building graphical interfaces. UI trees are composed of ui.window, ui.label, ui.button, and other UI primitives.
ui.window {
title: "My App"
width: 400
height: 300
ui.label {
text: "Hello, SUB!"
font_size: 24
}
ui.button {
text: "Click me"
on_click: fn() {
println("Button clicked!")
}
}
}
Note: The UI DSL is a declarative tree — it describes what the interface looks like, not how to draw it. Different renderers can interpret the same tree for different platforms.
Next Steps
- Standard Library — explore math, arrays, strings, io, and more
- Examples — real programs to learn from
- Transpilation — learn how SUB targets 13 languages