Documentation
Full documentation of Hexus-lang (E-Knowledge).
Welcome to the official documentation of the Hexus programming language. Hexus was designed to combine real programming languages with a very simple syntax.
Welcome to Hexus!!! Before diving into the language itself, here is a quick overview of the tools and conventions you need to get started.
The Playground is a browser-based environment where you can write and run Hexus code instantly - no installation required. It supports a single file, making it perfect for experimenting with small scripts, testing syntax, or following along with documentation examples. Just type your code and hit run.
Playground is not always updated to the latest version!!!
For larger or multi-file projects, you can download the latest version of Hexus to run it on your own machine. The download page includes a step-by-step guide for setting up Hexus with Visual Studio Code.
All Hexus source files use the .he file extension. For example:
main.he
my_program.he
game.he
When you run Hexus locally, you execute a .he file through the interpreter. The Playground also uses .he under the hood - you can copy code between the two seamlessly.
Once you have an environment ready, head to the sidebar and start exploring the language: variables, conditions, loops, functions, lists, modules, and more. Each section contains syntax reference, code examples, and practical use cases. c:
The send statement is the primary method for outputting data, strings, numbers and expression results to a destination target. By default, the output target is set to the system console, but it can also be explicitly routed to a specific target name using the to keyword.
Syntax:
send <expression>
send <expression> to <target>
Code Examples:
#Simple string output to the console
send "Welcome to the Hexus Programming Language!"
# Sending numerical values, expressions and variable
send 42
send 10 + 20 * 2
send name
# Explicitly specifying the target destination
send "Log message: Application initialized" to console
send "Database connection established" to logger
The read statement prompts the user or external system for input, displays a prompt message, and immediately stores the received value into a specified variable. Similar to the send command, it supports routing input requests from different targets using the from keyword, defaulting to the console.
Syntax:
read <prompt_expression> to <var_name>
read <prompt_expression> to <var_name> from <target>
Code Examples:
# Reading input from the console into a variable named user_name
read "Please enter your username: " to user_name
# Printing the variable back out
send "Hello, {user_name}"
# Reading input from a specific stream or target
read "Waiting for payload..." to payload_data from network
Comments are used to leave human-readable notes inside your code. Any text following the hash symbol (#) until the end of the line is completely ignored by the parser during execution.
# This is a single line comment in Hexus
send "Hello World!" # You can also add comments at the end of statements
When writing clean Hexus programs, use comments liberally to describe complex logic, mark TODO sections, or document custom function inputs.
Hexus supports multi-line block comments delimited by // at both the start and the end. Everything between the opening and closing // is ignored by the parser, allowing you to comment out large sections of code or write detailed documentation notes spanning multiple lines. This complements the single-line # comment syntax.
Syntax:
// This is a multi-line
comment block
spanning several lines
//
Code Example:
// This block comment explains the entire
initialization routine below. It sets up
the player's starting stats and inventory.
Last modified: 2025-01-15//
player_health = 100
player_mana = 50
// Temporarily disabled the following code block
for debugging purposes -- uncomment later.//
# send "Debug: player initialized"
# send "Health: {player_health}"
send "Game started!"
//============================
Section: Combat Logic
Review before next patch
============================//
Practical Use Cases:
- Temporarily disabling large blocks of code while debugging or testing.
- Adding detailed author notes, changelogs, or in-line documentation headers.
- Visually separating logical sections of a script for better readability.
Variables in Hexus are declared using either the = operator or the is keyword. You can store numbers, strings, booleans, evaluation results, or lists. List assignments are automatically detected when square brackets [] are used or when values are separated by commas.
Syntax:
<var_name> = <expression>
<var_name> is <expression>
<var_name> =/is []
<var_name> =/is <element1>, <element2>,
Code Examples:
# Variable assignments using "="
age = 25
score = 100 + 50
greeting = "Hello Hexus"
# Alternative variable assignments using "is"
speed is 60
status is "active"
is_logged_in is True
# Empty list declaration
inventory = []
users is []
#List declaration with elements
number = 1, 2, 3, 4, 5,
fruits is "apple", "banana", "cherry",
# List declaration with one element
name = "Hexus",
In list declaration end comma is very important!!!
Hexus provides shorthand operators to increment or decrement variables without writing a full assignment expression. The ++ and -- operators increase or decrease a variable by exactly 1. The += and -= operators allow you to add or subtract any numeric value from a variable. These operators modify the variable in-place.
Syntax:
<var>++
<var>--
<var> += <number>
<var> -= <number>
Code Example:
# Basic increment and decrement
score = 0
score++
send score
# Output: 1
lives = 3
lives--
send lives
# Output: 2
# Using += and -= with custom amounts
health = 100
health += 20
send health
# Output: 120
health -= 35
send health
# Output: 85
# Practical counter example
counter = 1
while counter <= 5 {
send "Round: {counter}"
counter++
}
# Using += inside a loop for accumulation
total = 0
i = 1
while i <= 10 {
total += i
i++
}
send "Sum of 1 to 10: {total}"
# Output: Sum of 1 to 10: 55
Practical Use Cases:
- Keeping score, counting kills, or tracking round numbers in games.
- Accumulating values (e.g., summing stats, building totals) in compact syntax.
- Simplifying loop counters and avoiding repetitive counter = counter + 1 lines.
Hexus provides a full set of comparison operators to compare two values. Each operator returns a boolean (True or False). Values are compared based on their types: numbers compare numerically, strings compare lexicographically (alphabetically), and booleans compare by truth value. These operators are typically used inside if, elif, while conditions, or anywhere a boolean expression is expected.
Syntax:
<expression> == <expression> # Equal to
<expression> != <expression> # Not equal to
<expression> < <expression> # Less than
<expression> > <expression> # Greater than
<expression> <= <expression> # Less than or equal to
<expression> >= <expression> # Greater then or equal to
<expression> is <expression> # Equal to (keyword alias)
<expression> is not <expression> # Not equal to (keyword alias)
Code Example:
# Equality and inequality
if 10 == 10 {
send "Ten equals ten"
}
status = "active"
if status != "inactive" {
send "Status is not inactive"
}
# Numeric comparisons
score = 85
if score >= 60 {
send "Passed! Score: {score}"
}
if score < 50 {
send "Failing score"
}
# Using is and is not (keyword aliases)
player_name = "Hero"
if player_name is "Hero" {
send "Welcome, Hero!"
}
if player_name is not "Guest" {
send "You are logged in as {player_name}"
}
# Combined with logical operators
age = 20
has_permission = True
if age >= 18 and has_permission is True {
send "Access granted"
}
# Greater than or equal, less than or equal
temperature = 30
if temperature <= 0 {
send "Freezing!"
} elif temperature >= 30 {
send "Hot!"
}
Comparison reference table:
| Operator | Meaning | Example (True) |
|---|---|---|
== | Equal to | 5 == 5 |
!= | Not equal to | 5 != 3 |
< | Less than | 3 < 5 |
> | Greater than | 5 > 3 |
<= | Less than or equal | 5 <= 5, 3 <= 5 |
>= | Greater than or equal | 5 >= 5, 7 >= 5 |
is | Equal to (alias) | "a" is "a" |
is not | Not equal to (alias) | "a" is not "b" |
Practical Use Cases:
- Validating user input (checking if a password matches, if age is within range).
- Controlling game logic (score thresholds, level completion conditions).
- Sorting or filtering data (checking if a value falls within expected bounds).
- Writing readable natural-language conditions with is and is not for string comparisons.
Hexus supports three logical operators for combining or negating boolean conditions. They allow you to build complex decision logic from simpler comparisons.
- and - returns True only if both sides evaluate to truthy.
- or - returns True if at least one side evaluates to truthy.
- not - negates a condition; returns True if the expression is falsy, and False if it is truthy.
All three operators follow short-circut evaluation: for and, if the left side is False, the right side is never evaluated; for or, if the left side is True, the right side is skipped. This can prevent errors like division by zero when used carefully.
Syntax:
<condition1> and <condition2>
<condition1> or <condition2>
not <condition>
Code Example:
# Using and - both conditions must be true
age = 25
has_id = True
if age >= 18 and has_id is True {
send "Entry granted!"
} else {
send "Entry denied."
}
# Using or - at least one condition must be true
is_weekend = False
is_holiday = True
if is_weekend or is_holiday {
send "No work today!"
}
# Using not - negating a condition
player_health = 0
if not player_health > 0 {
send "Player is defeated."
}
# Combining operators for complex logic
score = 85
lives = 2
has_powerup = True
if (score >= 100 or has_powerup is True) and lives > 0 {
send "Bonus level unlocked!"
}
# Short-circuit example - safely avoids division by zero
x = 10
if x != 0 and 10 / x > 2 {
send "This line will never run"
}
The modulo operator (%) returns the remainder of a division between two numbers. It can be used with both integer and floating-point values. This operator follows standard mathematical precedence (same level as multiplication and division), making it useful for cyclic logic, even/odd checks, and range clamping.
Syntax:
<expression1> % <expression2>
Code Example:
# Even / odd check
number = 7
if number % 2 == 0 {
send "{number} is even"
} else {
send "{number} is odd"
}
# Output: 7 is odd
# Cyclic wrapping (clamp a value to a range)
index = 0
index = (index + 1) % 4
send index
# Output: 1
# Checking divisibility
year = 2024
if year % 4 == 0 {
send "{year} is a leap year"
}
# Practical: alternating actions
for i from 1 to 6 {
if i % 2 == 0 {
send "Even turn: {1} - defensive action"
} else {
send "Odd turn: {1} - offensive action"
}
}
Practical Use Cases:
- Cycling through menu options or wrapping around array indices.
- Determining even/odd turns in turn-based game logic.
- Checking whether a number is divisible by another (e.g., leap year calculation, pagination).
Conditional blocks are used to execute specific sections of code only when certain conditions evaluate to True. In Hexus, condition blocks are wrapped in curly braces ({}), making structure visual and clean. You can chain multiple conditions using elif and provide a fallback block using else.
Syntax:
if <expression> {
# Code executed if condition is True
} elif <expression> {
# Optional alternative condition
} else {
# Optional fallback code
}
Code Examples:
# Basic conditional check
age = 18
if age >= 18 {
send "Access granted. Welcome to the system!"
} else {
send "Access denied. You must be at least 18 years old."
}
# Advanced logical evaluation with elif chains
score = 85
if score >= 90 {
send "Grade: A - Outstanding performance!"
} elif score >= 75 {
send "Grade: B - Great job!"
} elif score >= 50 {
send "Grade: C - You passed."
} else {
send "Grade: F - Needs improvement."
}
# Combining logic with boolean operators (and, or, not)
is_admin = True
has_key = False
if is_admin or has_key {
send "Security check passed. Opening door..."
}
if not has_key {
send "Warning: You are missing the required access key!"
}
Practical Use Cases:
- Validating input received from read commands before processing data.
- Creating decision paths in text-based adventure games or interactive console tools.
- Checking system flags, permissions, or game state variables.
The while loop ccontinuously executes a block of code as long as the specified expression evaluates to True. It is used then you do not know in advance how many times a loop needs to run, such as waiting for specific user input or maintaining an active game state.
Syntax:
while <expression> {
# Code executed repeatedly while condition remains True
}
Code Examples:
# Simple counter loop
count = 1
while count <= 5 {
send "Current iteration count: {count}"
count = count + 1
}
send "Loop completed successfully!"
# Interactive menu loop
user_choice = ""
while user_choice != "exit" {
read "Enter command (start/settings/exit): " to user_choice
if user_choice == "start" {
send "Starting application..."
} elif user_choice == "settings" {
send "Opening settings menu..."
}
}
send "Goodbye!"
Practical Use Cases:
- Running the main game loop until the player dies or chooses to exit.
- Polling a network socket or file system until a required resource becomes available.
- Keeping a terminal menu alive for continuous interaction.
The repeat loop allows you to execute a block of code a fixed number of times. Unlike while, which checks a conditional expression, repeat takes a number directly (or a variable containing a number) followed by the times keyword. It is cleaner and less error-prone when the total number of iterations is known in advance.
Syntax:
repeat <number_or_var> times {
# Code executed a specified number of times
}
Code Examples:
# Repeating an action a hardcoded number of times
send "Initiating launch sequence..."
repeat 3 times {
send "Beep!"
}
send "Liftoff!"
# Using a variable to control repetition count
total_rounds = 5
repeat total_rounds times {
send "Spawning enemy wave..."
}
# Nested repeat loops for grid rendering
repeat 3 times {
send "--- Row Start ---"
repeat 2 times {
send " [ Slot ]"
}
}
Practical Use Cases:
- Printing repeated separators or decorative borders in terminal interfaces.
- Generating fixed-size batches of objects, items, or enemy spawns in games.
- Performing batch mathematical calculations.
Hexus provides fine-grained control over loop execution through break and continue.
- break: Immediately terminates the active loop and jumps out of it.
- continue: Skips the rest of the current iteration and jumps directly to the next loop cycle.
Note: Using break or continue outside of an active loop block will raise a syntax error.
Syntax:
break
continue
Code Examples:
# Using break to exit an infinite loop prematurely
search_target = 7
current_num = 1
while True {
if current_num == search_target {
send "Target number found! Exiting search loop..."
break
}
}
# Using continue to skip unwanted numbers (e.g., skip even numbers)
num = 0
while num < 10 {
num = num + 1
# If the number is even, skip printing
if num % 2 == 0 {
continue
}
send "Odd number: {num}"
}
Practical Use Cases:
- Stopping an infinite searching loop the moment an item or solution is found (break).
- Filtering out invalid data or blank lines inside a processing loop without stopping the loop (continue)
Functions allow you to wrap reusable blocks of code into named units. You can pass arguments into functions, process data, and return calculated results back using the return statement. If no return value is specified, the function simply exits after executing its code block.
Syntax:
func <function_name>(<param1>, <param2>, ...) {
# Code block
return <expression>
}
Code Example:
# Simple procedure with no parameters or return value
func greet_user() {
send "----------------------------------------"
send "Welcome back to the Hexus Application!"
send "----------------------------------------"
}
# Calling the custom function
greet_user()
# Function with parameters returning a calculated result
func calculate_total(price, tax_rate) {
total = price + (price * tax_rate)
return total
}
# Storing the returned value in a variable
final_price = calculate_total(100, 0.23)
send "Total price with tax: {final_price}"
#Early return for validation
func process_age(user_age) {
if user_age < 0 {
send "Error: Invalid age provided."
return False
}
send "Age registered successfully."
return True
}
Practical Use Cases:
- Eliminating repetitive code by grouping frequently used calculations or UI displays.
- Structuring complex scripts into isolated, easy-to-maintain modules.
- Processing input validation and returning pass/fail boolean flags.
Lists in Hexus are dynamic collections. You can append new elements, insert items at specific positions, remove items by value or index, inspect list size, and access individual elements using indices.
Syntax:
- Append/Insert:
add <value> to <list_var>
add <value> to <list_var> at pos <index>
- Remove:
remove <value> from <list_var>
remove pos <index> from <list_var>
- Get length:
length of <list_var>
- Access index:
pos <index> of <list_var>
Code Examples:
# Initializing a list
inventory = "sword", "shield",
# Appending items to the end of a list
add "potion" to inventory
send inventory
# Output: ['sword', 'shield', 'potion']
# Inserting an item at a specific position
add "helmet" to inventory at pos 1
send inventory
# Output: ['helmet', 'sword', 'shield', 'potion']
# Finding the length of a list
total_items = length of inventory
send "Current inventory size: {total_items}"
# Accessing a specific element by position
first_item = pos 1 of inventory
send "Equipped item: {first_item}"
# Removing items by value
remove "shield" from inventory
# Removing items by index position
remove pos 1 from inventory
Practical Use Cases:
- Managing player inventories, active party members, or high-score leaderboards in games.
- Collecting dynamic data from user input loops before batch processing.
- Creating queue systems where items are continuously added and removed.
The for each loop allows you to iterate over every elements of a list variable. On each iteration, the current element is assigned to a temporary variable that you can use inside the loop body. The loop runs exactly once per list item, making it perfect for processing collections without manual index tracking.
Syntax:
for each <item_var> in <list_var> {
# Code executed for each element
}
Code Example:
fruits = "apple", "banana", "cherry",
for each fruit in fruits {
send "Current fruit: {fruit}"
}
# Output:
# Current fruit: apple
# Current fruit: banana
# Current fruit: cherry
# Using for each with numbers
scores = 10, 20, 30, 40,
total = 0
for each score in scores {
total = total + score
}
send "Sum of all scores: {total}"
# Output: Sum of all scores: 100
Practical Use Cases:
- Displaying all items from a player's inventory or shopping cart.
- Calculating totals, averages, or statistics from a dynamic data set.
- Filtering or transforming every element inside a list without manual indexing.
The numeric for loop lets you iterate over a sequence of numbers by declaring a loop variable, a starting value, and an end value. The loop variable automatically increments on each iteration until it exceeds the target end value. This is ideal when you know the exact numerical range you want to work through.
Syntax:
for <var> from <start_value> to <end_value> {
# Code executed for each number in range
}
Code Example:
# Simple countdown
for i from 1 to 5 {
send "Iteration number: {i}"
}
# Output:
# Iteration number: 1
# Iteration number: 2
# Iteration number: 3
# Iteration number: 4
# Iteration number: 5
# Using variables for the range boundaries
start = 0
finish = 3
for counter from start to finish {
send "Counter at: {counter}"
}
# In progress!!!
# Generating a multiplication table
for row from 1 to 3 {
for col from 1 to 3 {
send "{row} * {col} = {row * col}"
}
}
Practical Use Cases:
- Generating numbered menus or selecting items by an index range.
- Performing repetitive calculations a fixed number of times.
- Building grid-based game boards or tile maps (nested for loops).
The get random number from ... to ... command generates a pseudo-random integr within a specified inclusive range. Both the lower and upper bounds can be literal numbers, variables, or expressions. This command is an expression, so it can be used directly inside assignments, conditions, or output statements.
Syntax:
get random number from <lower_bound> to <upper_bound>
Code Example:
# Basic random number generation
dice_roll = get random number from 1 to 6
send "You rolled a: {dice_roll}"
# Using variables as bounds
min_val = 50
max_val = 100
random_score = get random number from min_val to max_val
send "Random score: {random_score}"
# Directly in an if condition
if get random number from 1 to 10 > 5 {
send "Lucky! You passed the odds check."
} else {
send "Unlucky this time."
}
Practical Use Cases:
- Creating dice-rolling mechanics or random loot tables in text-based games.
- Selecting random elements, rewards, or enemies from a weighted list.
- Adding procedural variety or randomness to simulation scripts.
The now keyword returns the current system date and time as string value. It can be used anywhere an expression is expected - in assignments, inside send output, or as part of string interpolation. This is useful for logging, timestamps, or measuring real-world time.
Syntax:
now
Code Example:
# Simple timestamp output
send "Current system time: {now}"
# Storing the timestamp in a variable
start_time = now
send "Session started at: {start_time}"
# Using now for logging
send "User login attempt recorded at {now}"
# Combine with timer to measure real elapsed time
send "Script launched at: {now}"
wait 2 s
send "Script completed at: {now}"
Practical Use Cases:
- Adding timestamps to log messages or audit trails.
- Recording when a player started or finished a game level.
- Tracking script execution windows for performance monitoring.
While Hexus does not require you to expicitly declare data types when creating variables, it features a dynamic typing system under the hood. Variables automatically infer their type based on the value assigned to them. Understanding how these types interact is crucial for writing bug-free scripts.
In Hexus, you do not write explicit type annotations like int x = 5. Instead, you simply assign values using = or is.
However, Hexus is strongly typed at runtime. This means the language will not automatically convert incompatible types during mathematical or string operations. For example, trying to add a number directly to a raw text string without proper formatting will cause a runtime evaluation error.
Hexus handles numerical values directly. Whether you work with whole integers or numbers containing decimal points, Hexus parses them into numerical expressions ready for arithmetic operations.
Code Examples:
# Whole integers
player_health = 100
enemies_killed = 0
# Decimal numbers (floating-point)
speed_multiplier = 1.5
pi_value = 3.14159
# Arithmetic with mixed numerical types
total_speed = 10 * speed_multiplier
send "Calculated speed: {total_speed}"
Strings represent sequence of characters wrapped in double quotes. They are used for console output, prompt labels, and storing text data.
Code Examples:
# Standard string variable
user_role = "Administrator"
# String concatenation (combining two text blocks)
send greeting
Booleans represent truth values and can only be set to True or False. They are primary used for condition flags inside if statements and while loops.
Code Examples:
# Boolean flag initialization
is_running = True
has_permission = False
# Logical evaluations automatically yield boolean results
can_enter = is_running and not has_permission
Variables in Hexus are used to store data in memory so it can be referenced, updated, and manipulated throughout your script. You do not need to specify a data type when creating a variable; the language automatically manages variable creation upon assignment.
Hexus provides two equivalent syntaxes for creating and updating variables:
yhe standard equal sign operator (=) and the readable descriptive keyword is.
Code Examples:
# Declaring variables using the "=" operator
user_score = 0
player_name = "Alex"
is_active = True
# Declaring variables using the "is" keyword
max_attempts is 3
server_status is "online"
game_over is False
# Reassigning and updating existing variables
user_score = user_score + 10
server_status is "offline"
send "Player {player_name} has a score of: {user_score}"
Lists are ordered containers that hold multiple items. They can be created empty or initialized with elements separated by commas or enclosed in square brackets.
Code Examples:
# Initializing lists
items = "apple", "banana", "orange",
scores = 10, 20, 30, 40,
Because Hexus enforces strict runtime evaluations, mixing non-compatible types in mathematical operations will fail.
# VALID: Adding numbers together
score = 50 + 25
# VALID: Concatenating strings together
first_name = "John"
last_name = "Doe"
full_name = "{first_name} {last_name}"
# Result: "John Doe"
# INVALID: Mixing raw strings and numbers in arithmetic directly
# age = "25" + 5 <-- This will cause an evaluation error!
# CORRECT WAY: Converting or formatting values cleanly
age_val = 25 + 5
send "Your current age is: {age_val}"
Hexus includes built-in system utility commands for pausing execution and clearing the terminal view.
Pauses execution for a specified duration using time units (s for seconds, m for minutes, h for hours, d for days).
Syntax:
wait <number> <unit>
Code Examples:
# Delaying execution for animations or timers
send "Loading resources, please wait..."
wait 2 s
send "Resources loaded successfully!"
Practical Use Cases:
- Controlling the frame pace or delay in terminal animations and text games.
Clears all text the current console display window, giving you a fresh screen
Syntax:
clear screen
Code Examples:
# Creating a timed countdown with screen clearing
send "3..."
wait 1 s
clear screen
send "2..."
wait 1 s
clear screen
send "1..."
wait 1 s
clear screen
send "GO!"
Practical Use Cases:
- Refreshing the dashboard or terminal screen to create a clean UI layout.
Hexus provides built-in keywords to convert string variables directly into all-lowercase or all-uppercase text. This modifies the target variable in-place.
Syntax:
make <var_name> lower
make <var_name> upper
Code Examples:
# Converting user input to lowercase for case-insencitive matching
read "Do you want to continue? (YES/no): " to user_response
# Convert the variable content to lowercase
make user_response lower
if user_response == "yes" or user_response == "y" {
send "Continuing execution..."
} else {
send "Aborting operation..."
}
# Converting strings to uppercase for display headers
title = "welcome to hexus"
make title upper
send title
Practical Use Cases:
- Normalizing user input received from terminal prompts so case variations (Yes, YES, yes) do not break if checks.
- Formatting title headers, badges, or output logs to stand out in terminal environments.
The built-in timer commands allow you to measure execution time down to precise fractions of a second. This is useful for benchmarking code performance or creating time-dependent mechanics.
Syntax:
timer start # Starts or resets the internal clock counter.
timer stop # Stops tracking elapsed time.
timer # Returns the current recorded time value.
Code Examples:
send "Benchmarking execution speed..."
# Start tracking time
timer start
# Perform a computational task
counter = 0
repeat 1000 times {
counter = counter + 1
}
# Stop the clock
timer stop
# Output the measured time
elapsed = timer
send "Task completed in: {elapsed} seconds."
Practical Use Cases:
- Benchmarking algorithm speeds (e.g., comparing how fast different function implementations run).
- Creating game timers to measure how quickly a player completes a level or puzzle.
- Profiling bottlenecks in your Hexus scripts.
The stop command immediately halts program execution. It can be used standalone to exit the script at any point, or with an optional string message that is displayed before termination. This is useful for controlled shutdowns, error handling, or debugging breakpoints.
Syntax:
stop
stop <message_string>
Code Example:
# Simple program termination
read "Enter your age: " to user_age
if user_age < 0 {
stop "Error: Age cannot be negative!"
}
send "Age registered successfully."
# Stopping an infinite loop
attempts = 0
while True {
read "Enter the correct password: " to input
attempts = attempts + 1
if input == "hexus123" {
send "Access granted!"
stop
}
if attempts >= 3 {
stop "Too many failed attempts. Exiting..."
}
}
Practical Use Cases:
- Exiting a script immediately when critical validation fails.
- Implementing a hard shutdown after a game-over condition.
- Debugging by placing a stop at a specific line to inspect program flow.
The unary minus (-) and unary plus (+) operators can be placed before a number, variable, or parenthesized expression. The unary minus negates the value (flips the sign), while the unary plus explicitly indicates a positive value (it has no practical effect on the value, but can improve readability).
Syntax:
-<expression>
+<expression>
Code Example:
# Negating numeric values
temperature = -5
send temperature
# Output: -5
# Using unary minus in calculations
a = 10
b = -a
send b
# Output: -10
# Unary minus with parentheses
result = -(20 + 5)
send result
# Output: -25
# Unary plus (explicitly marks positive)
positive_value = +42
send positive_value
# Output: 42
# Practical example with temperature conversion
celsius = 25
fahrenheit_negative = -(celsius * 9 / 5 + 32)
send "Negative Fahrenheit: {fahrenheit_negative}"
Practical Use Cases:
- Flipping the sign of a variable (e.g., inverting a direction vector in games)
- Working with negative offsets or coordinates in grid-based simulations.
- Making code more explicit when a positive value is intentional.
Hexus supports an extensible built-in module system that provides additional functionality beyond the core language. Modules are accessed using dot notation modulename.function. Each module encapsulates a specific domain (time, file I/O, etc.) and exposes its own set of functions and constants. The module system keeps the core language lightweight while allowing you yo tap into powerful utilities when needed.
Hexus features a powerful module system that allows you to import external Hexus files (.he) and use their functions with custom syntax patterns. When you import a file, the parser reads it, extracts all @syntax declarations, and makes them available for use under the module's name via dot notation.
There are two types of modules:
- Built-in modules - Python-based modules like time and file, loaded automatically from the modules/ directory. They are always available without an explicit import.
- User/Hexus modules - regular .he files that you import manually using import or from ... import. They can be located in the current working directory.
Syntax:
import "<module_name>"
from "<module_name>" import <name1>, <name2>, ...
- import - loads all @syntax-decorated functions from the module. You can then call them using <module_name>.<func_name> <args and/or keywords>.
- from ... import ... - loads only the specified function names from the module, keeping your namespace cleaner.
- Module names must be given with the .he extension.
File resolution order (first match wins):
1. Directory containing the current .he file
2. Its modules/ subdirectory (project modules)
3. Current working directory (absolute path or relative filename)
4. Hexus' built-in modules/ directory
How it works under the hood:
When you write a module .he file, you define functions with a @syntax decorator thet describes the expected argument pattern. For example:
# math.he
@syntax "add <number> and <number>"
func add(a, b) {
send "Result: {a + b}"
}
The @syntax string defines:
- Literal words - must appear exactly as written (e.g., add, and)
- <arg> placeholders - represent arguments that the caller provides (e.g., <number>)
When another file imports math, it can call math.add using the defined syntax. A project module with the same name takes precedence over a built-in module:
import "math.he"
math.add 5 to 3
# Output: Result: 8
Code Example:
# --- File: math.he ---
@syntax "add <number> and <number>"
func add(a, b) {
send "Result: {a + b}"
}
@syntax "multiply <number> by <number>"
func multiply(x, y) {
send "Product: {x * y}"
}
# --- File: main.he ---
# Import all functions from math module
import "math.he"
# Use the custom syntax patterns defined in the module
math.add 10 to 20
# Output: Result: 30
math.multiply 6 by 7
# Output: Product: 42
# Import only specific functions
from "math.he" import multiply
# Now only multiply is available
math.multiply 3 by 9
# Output: Product: 27
# math.add would cause an error here (not imported)
Practical Use Cases:
- Creating reusable libraries of game functions (combat, inventory, quest, logic).
- Splitting large projects into manageable, modular .he files.
- Defining domain-specific DSL-like syntax with @syntax for readability.
- Sharing and distributing Hexus code between projects or with other developers.
The Time module provides built-in functions for retrieving the current system date and time components. It supports extracting individual values (hour, minute, second, day, month, year) as well as formatted datetime strings with optional UTC offset. The module also exposes a UTC constant for timezone manipulation.
Syntax:
time.hour
time.minute
time.second
time.day
time.month
time.year
time.get time "<format_string>"
time.get time <UTC_offset>
Module Functions Reference:
| Function | Returns | Example Output |
|---|---|---|
time.hour | Current hour (00-23) | "14" |
time.minute | Current minute (00-59) | "05" |
time.second | Current second (00-59) | "47" |
time.day | Current day of month (01-31) | "19" |
time.month | Current month (01-12) | "08" |
time.year | Current year | "2026" |
time.get time "<format>" | Current datetime with custom format | "2026-08-19 14:05:47" |
time.get time UTC | Current UTC datetime | "2026-08-19 12:05:47" |
time.get time UTC+2 | Current datetime with UTC+2 offset | "2026-08-19 14:05:47" |
time.get time UTC-5 | Current datetime with UTC-5 offset | "2026-08-19 09:05:47" |
Code Example:
# Getting individual time components
send "Current hour: {time.hour}"
send "Current minute: {time.minute}"
send "Current second: {time.second}"
# Getting date components
send "Day: {time.day}"
send "Month: {time.month}"
send "Year: {time.year}"
# Custom formatted datetime using strftime patterns
send "Full time: {time.get time '%H:%M:%S'}"
# Working with UTC timezone
send "UTC time: {time.get time UTC}"
# Applying timezone offsets
send "UTC+2: {time.get time UTC+2}"
send "UTC-5: {time.get time UTC-5}"
# Storing module results in variables
current_year = time.year
send "The year is: {current_year}"
# Using UTC constant independently for timezone math
utc_plus_1 = UTC + 1
Practical Use Cases:
- Displaying real-time clocks or timestamps in terminal applications.
- Logging events with precise time and timezone information.
- Generating date-stamped filenames or save-file names.
- Building countdown timers or scheduling systems based on current time components.
- Normalizing timestamps across different timezones using UTC offsets.
The File module provides basic file input/output operations. It allows you to open files, read their contents (full or line-by-line), write data (overwrite or append), and close them. Files are opened in read-write mode, and if a file does not exist, it is automatically created.
Syntax:
file.open "<filename>" as <var>
file.read <file_var> into <var>
file.readline <file_var> into <var>
file.write <value> to <file_var>
file.append <value> to <file_var>
file.close <file_var>
Module Functions Reference:
| Function | Description |
|---|---|
file.open "<path>" as <var> | Opens a file (creates it if it doesn't exist) and stores the file handle in a variable |
file.read <file_var> into <var> | Reads the entire file content into a variable |
file.readline <file_var> into <var> | Reads a single line from the file into a variable |
file.write <value> to <file_var> | Overwrites the file with the given value |
file.append <value> to <file_var> | Appends the given value to the end of the file |
file.close <file_var> | Closes the file handle |
Code Example:
# Opening a file (creates it if it doesn't exist)
file.open "notes.txt" as myfile
# Writing data to the file (overwrites existing content)
file.write "Hello, Hexus!" to myfile
# Appending more data to the end of the file
file.append "\nThis is a new line." to myfile
# Reading the entire file content
file.read myfile into content
send "Full file content: {content}"
# Reading line by line
file.readline myfile into line1
send "First line: {line1}"
file.readline myfile into line2
send "Secound line: {line2}
# Always close the file when done
file.close myfile
# Practical example: logging
file.open "log.txt" as log
file.append "{now}: Application started" to log
file.append "{now}: Processing data..." to log
file.append "{now}: Done." to log
# Reading the log back
file.open "log.txt" as log
file.read log into log_data
send "Log contents:\n{lod_data}"
file.close log
Practical Use Cases:
- Saving and loading player progress, high scores, or game configuration.
- Writing log files with timestamps for debugging or audit trails.
- Reading structured data (CSV-like, config files) line by line
- Creating template files or exporting data from a Hexus script.