Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ToberlerOhn/hades/llms.txt

Use this file to discover all available pages before exploring further.

Hades control flow looks familiar to anyone coming from C, Java, or JavaScript — curly-brace blocks, parenthesised conditions, and for loop headers. The return statement uses => instead of a return keyword, and the language specification describes additional loop-control keywords that are not yet fully executed by the interpreter (see notes below).

Conditional statements

if / else if / else

Conditions are placed in parentheses and the body in curly braces. Any number of else if branches may follow the opening if, with an optional final else.
foo: int = 5;

if (foo == 3) {
    print('foo is 3');
} else if (foo == 5) {
    print('foo is 5');
} else {
    print('foo isn\'t 3 or 5')
}
// outputs: foo is 5
Any value can be used as a condition — the interpreter uses truthiness rules to coerce it to bool. An empty string, 0, 0.0, nothing, or an empty list are all falsy; everything else is truthy.
No semicolon is required after a closing }. Semicolons are only needed to terminate simple expressions and declarations.

Loops

While loop

A while loop evaluates its condition before every iteration. If the condition is falsy on the very first check, the body never runs.
i: int = 0;
while (i < 3) {
    print(i);
    i++
};
// outputs:
// 0
// 1
// 2

Do-while loop

A do-while loop runs the body first, then checks the condition. The body always executes at least once.
i: int = 0;
do {
    print(i);
    i++
} while (i < 3);
// outputs:
// 0
// 1
// 2
i: int = 0;
while (i < 3) {
    print(i);
    i++
};
Condition is checked before each iteration. May run zero times.

For loop

The classic C-style for loop has three parts in its header separated by semicolons: an initialiser, a test expression, and an update statement.
for (i: int = 0; i < 3; i++) {
    print(i)
};
// outputs:
// 0
// 1
// 2
The initialiser declares a typed variable scoped to the loop. The update runs after every iteration’s body.

For-in loop

The for-in variant iterates over each element of a list or each character of a str. The loop variable is typed; the interpreter checks each element against that type at runtime.
for (item: int; item in [10, 20, 30]) {
    print(item)
}
// outputs:
// 10
// 20
// 30
word: str = 'hi';
for (ch: str; ch in word) {
    print(ch)
}
// outputs:
// h
// i
You cannot iterate over an int, float, or bool. Attempting to do so raises a runtime error. Only list and str are iterable.

Loop control keywords

The next and break keywords are described in the Hades language specification and README, but they are not yet implemented in the current interpreter. There is no BreakSignal or NextSignal handler — using these keywords will not produce the expected behaviour at runtime. They are documented here as planned features.
next is intended to jump to the start of the next iteration, skipping any remaining statements in the current loop body. In a for loop, the update expression (e.g. i++) would still run.
// Planned syntax — next is not yet executed by the interpreter
for (i: int = 0; i < 5; i++) {
    if (i == 2) {
        next
    };
    print(i)
};
break is intended to immediately exit the enclosing loop, skipping both the remaining body statements and all future iterations.
// Planned syntax — break is not yet executed by the interpreter
for (i: int = 0; i < 10; i++) {
    if (i == 3) {
        break
    };
    print(i)
};

Return

Inside a function, => followed by an expression exits the function and returns that value. To return nothing explicitly, use => nothing.
func clamp(n: int) => int {
    if (n < 0) {
        => 0
    }
    if (n > 100) {
        => 100
    }
    => n
}
See the Functions page for the full function syntax.

Goto labels

_goTo labels are described in the Hades language specification but are not yet implemented in the current interpreter. There is no label or goto handler in the interpreter’s node handlers. This syntax is documented here as a planned feature.
The planned syntax for unconditional jumps uses _goTo and named labels. A label is defined by writing LABEL_NAME: on its own line; the jump is written as _goTo LABEL_NAME.
// Planned syntax — _goTo is not yet executed by the interpreter
for (i: int = 0; i < 100; i++) {
    if (i == 50) {
        _goTo DONE
    };
    print(i)
};

DONE:
print('finished')

Build docs developers (and LLMs) love