Advanced Execution Through Endless Recursion
AETHER is a compiled programming language with indentation-based syntax, ownership-aware memory safety, and LLVM-backed code generation. It combines the structural clarity of Python with the type safety and performance of systems languages.
- AETHER
- Indentation-based syntax — no braces, blocks defined by colon + indent,
;for bodyless declarations - Strong static typing — OOP type system with
I64,F64,String,Boolean, and user-defined types - Class system — single inheritance, interfaces, virtual dispatch,
Readonlyandfinalmodifiers - Structs — value types with constructors and methods
- Generics — monomorphized at compile time with constraint support
- No
T[]arrays — useMemory<T>(LLVM intrinsic) for raw memory,ArrayList<E>for dynamic arrays - Nullable types —
?Typesyntax withNoneliteral - Error handling —
try/except/finallywithraise - Ownership & borrow checking — move semantics, borrow rules, use-after-move detection
- Pattern matching —
matchstatements with enum dispatch - Defer — LIFO deferred execution before function return
- Boolean keywords —
and/or/notinstead of&&/||/! - C FFI —
extern functiondeclarations for direct C interop - LLVM backend — compiles to native executables via LLVM 14
- REPL — interactive mode for quick prototyping
- AST optimizer — constant folding, strength reduction, dead code elimination, tail-call optimization
# Build the compiler
cmake -B build -DCMAKE_BUILD_TYPE=Release
make -C build -j$(nproc)
# Compile and run
./build/aether examples/testing/testing.ae -o hello
./hellopackage main
extern function puts(String s) -> I32
public function main() -> I32:
puts("Hello, AETHER!")
return 0
# Typed variable declaration
I64 count = 42
F64 pi = 3.14159
String name = "AETHER"
Boolean flag = True
# Compound assignment
count += 10
count -= 3
count *= 2
# Increment / decrement
count++
count--
Built-in OOP types: I8, I16, I32, I64, U8, U16, U32, U64, F32, F64, String, Boolean, Char, Byte, NoneType, Void.
# Regular function
public function add(I64 a, I64 b) -> I64:
return a + b
# Recursive function
public function factorial(I64 n) -> I64:
if n <= 1:
return 1
return n * factorial(n - 1)
# Nested function
public function outer(I64 x) -> I64:
function square(I64 n) -> I64:
return n * n
return square(x) + 1
Declarations without a body end with ; — declarations with a body end with : followed by an indented block:
# Bodyless (extern, forward, abstract) — use semicolon
extern function printf(String fmt, ...) -> I32;
class Node;
# Body present — use colon + indent
public function greet() -> Void:
puts("hello")
# Empty body — use pass or ...
public function placeholder() -> Void:
pass
# If / elif / else
if x > 100:
puts("big")
elif x > 0:
puts("positive")
else:
puts("non-positive")
# Match on enum
match direction:
Direction.North =>
return 0
Direction.South =>
return 1
Direction.East =>
return 2
Direction.West =>
return 3
# While loop
while i <= 10:
total += i
i += 1
# Infinite while with break
while True:
if done:
break
# C-style for
for I64 i = 0; i < 10; i++:
printf("%d ", i)
# Range for (exclusive)
for I64 i in 0..10:
printf("%d ", i)
# Range for (inclusive)
for I64 i in 1...10:
printf("%d ", i)
# String iteration
for Char c in "AETHER":
printf("%c ", c)
# Basic class
class Point:
public I64 x
public I64 y
public function Point(self, I64 x, I64 y) -> Void:
self.x = x
self.y = y
public function sum(self) -> I64:
return self.x + self.y
# Inheritance with virtual dispatch
class Animal:
public String name
public function Animal(self, String name) -> Void:
self.name = name
public virtual function speak(self) -> Void:
puts("...")
class Dog extends Animal:
public function Dog(self, String name) -> Void:
self.name = name
public override function speak(self) -> Void:
puts("Woof!")
# Readonly class (immutable after construction)
Readonly class Config:
public I64 port
public String host
public function Config(self, I64 port, String host) -> Void:
self.port = port
self.host = host
# Forward declaration
class Node;
class Node:
public I64 value
public function Node(self, I64 v) -> Void:
self.value = v
struct Vec3:
public F64 x
public F64 y
public F64 z
public function Vec3(self, F64 x, F64 y, F64 z) -> Void:
self.x = x
self.y = y
self.z = z
public function length_sq(self) -> F64:
return self.x * self.x + self.y * self.y + self.z * self.z
enum Direction:
North
South
East
West
public function describe(Direction d) -> Void:
match d:
Direction.North =>
puts("North")
Direction.South =>
puts("South")
Direction.East =>
puts("East")
Direction.West =>
puts("West")
interface Describable:
public function describe(self) -> Void
interface Measurable:
public function measure(self) -> I64
# Implement single interface
class Circle implements Describable:
public F64 radius
public function Circle(self, F64 r) -> Void:
self.radius = r
public function describe(self) -> Void:
printf("Circle(%.1f)\n", self.radius)
# Implement multiple interfaces
class Square implements Describable, Measurable:
public I64 side
public function Square(self, I64 s) -> Void:
self.side = s
public function describe(self) -> Void:
printf("Square(%d)\n", self.side)
public function measure(self) -> I64:
return self.side * self.side
# Extends + implements
class Rect extends Shape implements Describable:
pass
# Generic class
class Box<T>:
public T value
public function Box(self, T value) -> Void:
self.value = value
public function get(self) -> T:
return self.value
# Generic struct
struct Pair<K, V>:
public K key
public V value
public function Pair(self, K key, V value) -> Void:
self.key = key
self.value = value
# Usage
Box<I64> intBox = new Box<I64>(42)
I64 val = intBox.get()
Pair<String, I64> entry = new Pair<String, I64>("age", 25)
Generic types are monomorphized at compile time — each instantiation (Box<I64>, Box<String>) produces a specialized type. Constraints are validated during instantiation:
class Container<T: Hashable>:
pass
Note: AETHER has no
T[]array syntax. For raw contiguous memory, useMemory<T>fromaether.memory.memory. For dynamic arrays, useArrayList<E>fromaether.collection.array-list.
?String name = None
?String greeting = "Hello"
if name == None:
puts("no name")
if greeting != None:
puts(greeting)
name = "Alice"
Prefix ? before any type makes it nullable. None is assignable to any nullable type.
public function divide(I64 a, I64 b) -> I64:
if b == 0:
raise "division by zero"
return a / b
try:
I64 result = divide(10, 0)
except as e:
puts("caught error")
finally:
puts("cleanup")
Only types implementing Throwable or string literals can be used with raise. Multiple except clauses supported:
except DivisionError as e:
pass
except IndexError|KeyError as e:
pass
except as e:
pass
except:
pass
# Heap allocation
Point pt = new Point(10, 20)
# Manual deallocation
delete pt
The borrow checker enforces ownership rules: move semantics, single mutable or multiple immutable borrows, use-after-move detection, and double-free prevention.
AETHER has NO
T[]array syntax. There is no built-in array literal or bracket-based indexing. For contiguous raw memory, useMemory<T>fromaether.memory.memory. For high-level dynamic arrays, useArrayList<E>fromaether.collection.array-list.
Memory<T> is a final native class — its methods are compiler intrinsics that emit LLVM instructions directly:
from aether.memory.memory import Memory
# Allocate raw memory for 16 I64 slots
Memory<I64> buffer = new Memory<I64>(16)
# Write and read via index
buffer.set(0, 42)
buffer.set(1, 99)
I64 first = buffer.get(0) # 42
I64 second = buffer.get(1) # 99
# Bulk copy to another buffer
Memory<I64> copy = new Memory<I64>(16)
buffer.copyTo(copy, 16)
# Free when done
buffer.free()
copy.free()
Under the hood:
new Memory<T>(cap)→malloc(cap * sizeof(T)).get(index)→getelementptr+load.set(index, value)→getelementptr+store.copyTo(dest, len)→llvm.memcpy.free()→free(pointer)
Memory<T> is the backbone of all standard library collections (ArrayList, HashMap, HashSet). It provides zero-overhead memory access with full type safety.
public function work() -> Void:
defer puts("cleanup third")
defer puts("cleanup second")
puts("doing work first")
# Output: doing work first, cleanup second, cleanup third
# Block form
defer:
puts("deferred block")
Deferred statements execute in LIFO order before every function return.
# Import module
import mathlib
# Dotted path (resolves to modules/utils/strings.ae)
import utils.strings
# Selective import
from aether.errors.error import Error
# Wildcard import
from aether.collection import *
# Re-export (Maybe i'll remove this feature in future)
public import aether.errors.error
# Private import (Maybe i'll remove this feature in future)
private from aether.utils import helper
Package declaration follows file path: file at examples/testing/arithmetic.ae uses package aether.examples.testing.arithmetic.
AETHER compiles through a classic multi-stage pipeline:
Source (.ae)
│
▼
Lexer ──── INDENT/DEDENT token emission
│
▼
Parser ─── AST construction
│
▼
Semantic ─ Type checking, two-pass (register types, then analyze bodies)
│
▼
Borrow ─── Ownership & borrowing validation
│
▼
Optimizer ─ AST-level: constant folding, DCE, strength reduction, TCO
│
▼
Codegen ── LLVM IR generation
│
▼
LLVM ───── Native executable
Orchestrated by CompilationDriver. Entry point is src/aether.cpp.
src/aether/
├── ast/ # AST nodes, visitor, printer
├── codegen/ # LLVM IR generation
├── common/ # Shared utilities
├── descriptor/ # Built-in type registry (OOP types, methods, IR generators)
├── driver/ # Compilation pipeline orchestration, REPL
├── lexer/ # Tokenizer with indentation tracking
├── opt/ # AST-level optimizer passes
├── parser/ # Recursive descent parser
├── semantic/ # Semantic analysis, type system, borrow checker
└── toolchain/ # System linker integration
- C++17 compiler (GCC 12+ or Clang 14+)
- LLVM 14 (via
llvm-config) - CMake 3.16+
- fmt, spdlog, argparse, GoogleTest
cmake -B build -DCMAKE_BUILD_TYPE=Release
make -C build -j$(nproc)# Run all tests (unit + integration)
./build/aether-tests
# Run a single test
./build/aether-tests --gtest_filter="ParserTest.ParsesSimpleFunction"# Compile to executable
./build/aether source.ae -o program
# Emit LLVM IR
./build/aether source.ae --emit-llvm -o output.ll
# Dump AST
./build/aether source.ae --dump-ast
# Dump token stream
./build/aether source.ae --dump-tokens
# Optimization level
./build/aether source.ae -O3 -o program
# Link external library
./build/aether source.ae -l m -o program
# Start REPL
./build/aether --repl./build/aether --replInteractive mode for quick prototyping. Variables and declarations persist across inputs.
ae(1)> I64 x = 42
OK
ae(2)> :type x
i64
ae(3)> :ast x + 1
(BinaryExpr + ...)
ae(4)> :clear
Session cleared.
ae(5)> :quit
Commands: :quit/:q, :help, :type <expr>, :ast <code>, :tokens <code>, :clear.
Located in modules/:
| Module | Description |
|---|---|
language/ |
OOP type wrappers (I64, String, Boolean, Char, Byte, etc.) |
errors/ |
Exception hierarchy (Throwable, Error, Exception, Warning) |
memory/ |
Memory<T> — native LLVM memory intrinsic (no T[] syntax in AETHER) |
collection/ |
Generic collections (ArrayList, HashMap, HashSet, Pair, Tuple) |
iterators/ |
Iterator, Iterable, Traversable interfaces |
operators/ |
Operator interfaces (Comparable, Equatable, Hashable, etc.) |
functions/ |
Builtin functions and C FFI extern declarations (printf, puts) |
threading/ |
Thread, Mutex, RwLock — concurrency primitives |
coroutine/ |
async/await support and coroutine runtime |
io/ |
I/O operations |
cli/ |
Command-line argument and terminal utilities |
subprocess/ |
Child process management |
fiber/ |
Lightweight fiber/green thread support |
processing/ |
Data processing utilities |
Error types (Error, Exception, Warning) are auto-imported as prelude.
The examples/testing/ directory contains compilable examples for every language feature:
| File | Features |
|---|---|
testing.ae |
Complete syntax showcase in one file |
arithmetic.ae |
Arithmetic, compound assignment, F64, recursion |
control-flow.ae |
if/elif/else, match, boolean logic |
loops.ae |
while, c-style for, range ../..., string iteration, break/continue |
classes.ae |
Class, inheritance, virtual, readonly, generics, forward decl |
structs.ae |
Struct with self, constructors, methods |
enums.ae |
Enum declaration, match dispatch |
interfaces.ae |
Interface, implements, multiple interfaces |
functions.ae |
Recursion, nested functions, defer |
nullable.ae |
Nullable ?Type, None, null checks |
error.ae |
try/except/finally, raise, nested try |
memory.ae |
new, delete, heap lifecycle |
strings.ae |
String literals, char iteration |
hash-map.ae |
HashMap<K,V> — put, get, containsKey, remove |
hash-set.ae |
HashSet<E> — add, exists, remove, size |
hierarchy.ae |
Multi-level inheritance, inherited method/property resolution |
traits.ae |
Trait declarations and implementations |
lambdas.ae |
Lambda expressions and closures |
generators.ae |
Generator functions with yield |
properties.ae |
Property accessors |
operators.ae |
Operator overloading |
threading.ae |
Thread creation, Mutex, synchronization |
async.ae |
Async/await and futures |
Benchmarks (in examples/benchmarks/): binary-trees.ae, fannkuch-redux.ae, mandelbrot.ae, n-body.ae, spectral-norm.ae.
Compile any example:
./build/aether examples/testing/testing.ae -o showcase && ./showcaseAETHER is currently a research-oriented compiler in its early development stage. It has not been audited for security, memory safety, or performance stability. We strongly advise against using AETHER for any mission-critical applications or production environments at this stage. By using this software, you acknowledge that:
- The syntax and API are subject to breaking changes without notice.
- The generated code may contain unintended bugs or undefined behavior.
- High-level optimizations are still experimental.
As AETHER is in active development, your feedback is crucial for its stability. If you encounter any crashes, incorrect LLVM IR generation, or memory leaks:
- Check Existing Issues: Please search the Issue Tracker to see if the bug has already been reported.
- Open a New Issue: If not, feel free to Open a New Issue.
- Provide Details: To help us fix it faster, please include your environment details (Parrot OS version, LLVM version), a minimal reproducible code snippet, and the expected vs. actual output.
Give spirit to the developer, no matter how many donations given will still be accepted
paypal.me/hxAri
All AETHER source code is licensed under the GNU General Public License v3. Please see the original document for more details.
