“Where code becomes poetry, and logic sings in verse.”
A poetic programming language that unites literature and computation.
Crafted with care, elegance, and reason — by Emir Husain
“For words are not mere commands, but verses that shape the realm of computation.”
Ardent is a programming language written as literature that runs — where spells, scrolls, and truths stand in for functions, modules, and booleans. Syntax is lyrical, semantics are strong, and errors read like narrative.
Let it be proclaimed: "--- The Tale of Ardent ---"
Let it be known throughout the land, a phrase named hero is of "Aragorn".
By decree of the elders, a spell named greet is cast upon a traveler known as name:
Let it be proclaimed: "Hail, noble " + name + "!"
Invoke the spell greet upon hero
Try:
Invoke the spirit of math.divide upon 10, 0
Catch the curse as omen:
Let it be proclaimed: "Caught: " + omen
Finally:
Let it be proclaimed: "All is well in Middle Code."
Output:
--- The Tale of Ardent ---
Hail, noble Aragorn !
Caught: A curse was cast: Division by zero in spirit 'math.divide'.
All is well in Middle Code.
| Principle | Meaning |
|---|---|
| Poetry‑first Syntax | Code reads as verse — human and timeless. |
| Strong Semantics | Every expression yields a deterministic, type‑safe result. |
| Narrative Errors | Failures appear as poetic “curses.” |
| Lexical Scoping | Each verse obeys its realm. |
| Expandable Spirit | Designed to bridge into native systems and beyond. |
| Concept | Ardent Form | Equivalent |
|---|---|---|
| Variable | Let it be known … | var / int / string |
| Function | By decree of the elders … | function / def |
| Loop | Whilst the sun doth rise … | while / for |
| Conditional | Should the fates decree … | if |
| Exception | Try / Catch the curse / Finally | try / catch / finally |
| File I/O | Inscribe upon …, reading from …, Banish … | open/write/read/delete |
| Import | From the scroll of … | import/module |
| Native Bridge | Invoke the spirit of … | FFI / native call |
| Interactive | Oracle | REPL shell |
| Ardent Type | Keyword | Description | Example |
|---|---|---|---|
| Number | a number named | Integer value | Let it be known, a number named age is of 25 winters. |
| Phrase | a phrase named | String | Let it be known, a phrase named greet is of "Hail!" |
| Truth | a truth named | Boolean | Let it be known, a truth named brave is of True. |
| Order | an order named | List / Array | an order named heroes is of ["Aragorn", "Legolas", "Gimli"] |
| Tome | a tome named | Map / Object | a tome named hero is of {"name": "Aragorn", "title": "King"} |
Let it be known throughout the land, a number named count is of 5 winters.
Let it be known throughout the land, a phrase named greet is of "Hello".
Let it be known throughout the land, a truth named alive is of True.
Supports expressions and casting:
Let it be known throughout the land, a number named result is of 5 + 3 * 2.
Let it be known throughout the land, a phrase named shout is of cast result as phrase + "!"
Should the fates decree count surpasseth 5 then
Let it be proclaimed: "High!"
Else whisper "Low!"
Logical expressions:
Should the fates decree brave and not weary then
Let it be proclaimed: "Strong!"
Comparisons: is equal to, is not, is greater than, is lesser than, surpasseth, remaineth below
Whilst Loop
Let it be known throughout the land, a number named count is of 1 winters.
Whilst the sun doth rise count remaineth below 3 so shall these words be spoken
Let it be proclaimed: count
And with each dawn, let count ascend 1
For Loop
Let it be known throughout the land, a number named i is of 0 winters.
For i remaineth below 3 so shall these words be spoken
Let it be proclaimed: "Turn " + i
And with each dawn, let i ascend 1
Do‑While Loop
Let it be known throughout the land, a number named ct is of 0 winters.
Do as the fates decree so shall these words be spoken
Let it be proclaimed: "Count is " + ct
And with each dawn, let ct ascend 1
Until ct surpasseth 3
Definition:
By decree of the elders, a spell named greet is cast upon a traveler known as name:
Let it be proclaimed: "Hail, noble " + name + "!"
Invocation:
Invoke the spell greet upon "Aragorn"
With return value:
By decree of the elders, a spell named bless is cast upon a warrior known as name:
Let it be proclaimed: "Blessing " + name
And let it return "Blessed " + name
From the scroll of "heroes.ardent" draw all knowledge.
From the scroll of "spells.ardent" take the spells bless, bestow.
From the scroll of "alchemy.ardent" draw all knowledge as alch.
Unfurl the scroll "legends/warriors.ardent".
Invoke the spirit of math.add upon 2, 3
Invoke the spirit of system.len upon "abc"
Errors read like:
The spirits know not the rite 'math.divide'.
The spirits demand 2 offerings for 'math.add', yet 1 was placed.
Try:
Invoke the spirit of math.divide upon 10, 0
Catch the curse as omen:
Let it be proclaimed: "Caught: " + omen
Finally:
Let it be proclaimed: "All is well."
Inscribe upon "epic.txt" the words "In the beginning, there was code."
Let it be known throughout the land, a phrase named lines is of reading from "epic.txt".
Etch upon "epic.txt" the words "\nAnd thus Ardent was born."
Banish the scroll "epic.txt".
Tip: Run a focused demo via the binary flag:
./ardent_demo.exe --chronicles-demo
This writes, reads, appends, checks existence, and finally banishes the scroll — all within a sandboxed path policy.
Start the Oracle:
./ardent.exe --oracleExample session:
** The Oracle of Ardent **
Speak thy words (or say 'farewell' to depart).
✒️ 3 + 2
5
✒️ Let it be known, a number named age is of 18 winters.
Variable assigned: age = 18
✒️ age + 3
21
✒️ farewell
The Oracle falls silent...
Notes:
_holds the last result in the REPL.- Flags:
--color/--no-color,--emoji/--no-emoji,--poeticfor reflective lines.
| Layer | Module | Description |
|---|---|---|
| Lexical Analysis | lexer.* |
Converts poetic words to tokens |
| Syntactic Analysis | parser.* |
Builds AST of the verse |
| AST Definitions | ast.h |
Node types: Expression, Statement, Spell, … |
| Runtime Execution | interpreter.* |
Evaluates AST, manages scope stack |
| Runtime CLI / REPL | main.cpp |
Entry point, demos, and Oracle logic |
| Chronicles & Spirits | built‑ins | File I/O rites and native bridges |
Establishing the foundation for performance, predictability, and future language evolution.
Phase 1.1 introduces a disciplined memory model centered on a lightweight bump‑pointer arena with scoped frames. All transient language structures now allocate from explicit arenas, eliminating fragmentation and reducing lifetime ambiguity. This sets the stage for future optimization phases without sacrificing the poetic surface of the language.
- Bump Arena + Frames: Fast linear allocation with
pushFrame()/popFrame()for precise lifetime control. - Phrase SSO: Small strings stored inline; larger phrases promoted into the active arena — zero heap churn for ephemeral text.
- Arena‑Backed AST: All nodes constructed via placement helpers (
node<T>) eliminatingshared_ptroverhead. - Scoped Environment Stack: Each scope uses an arena‑allocated hash table; entry lifetimes tied to frames.
- Immutable Collections:
Order(sequential) andTome(key/value) are snapshot structures — stable iteration, copy‑on‑write mutation rites. - Copy‑on‑Write Rites:
expand/remove(Order) andamend/erase(Tome) build fresh snapshots in the active arena; no in‑place mutation. - Dual REPL Arenas:
globalArena_(persistent) andlineArena_(ephemeral) with promotion of “touched” values per input line. - Import Lifetime Fix: Modules parsed/executed in the interpreter’s global arena; no dangling interpreter states.
- Unified Printing Semantics: Phrases, Orders, and Tomes render consistently through
formatValue(); raw phrase output (no extraneous quoting). - Test Suite Stability: All 73 validator cases pass, establishing a correctness baseline.
| Layer | Purpose |
|---|---|
| Global Arena | Long‑lived program/runtime state (persisted values, imported definitions). |
| Line Arena | Ephemeral REPL evaluation workspace reused each input. |
| Frames | Fine‑grained lifetime scoping: pushed for blocks / evaluation phases. |
Allocation Principle: “If it won’t outlive the current evaluation frame, it belongs in the current arena — never on the general heap.”
During REPL input: beginLine() opens a fresh frame on lineArena_; any value referenced outside its ephemeral context is marked and later promoted into globalArena_ during endLine(). Untouched temporaries are discarded en masse.
Orders and Tomes store flat, arena‑linear memory blocks. Mutation rites allocate new blocks; previous snapshots remain valid for any active readers. This approach prepares future structural sharing or persistent index overlays without API change.
- Use
activeArena()for all transient allocations (AST nodes, large phrases, collection snapshots). - Avoid raw
new/delete; prefer arena placement helpers. - Do not mutate an existing Order/Tome in place — always perform a rite that constructs a new snapshot.
- Use
assignVariableAnyfor environment updates to ensure scope consistency. - Keep Phrase concatenation arena‑local; avoid constructing intermediate
std::stringunless required by an external interface.
All current behavioral tests: 73 passed, 0 failed — includes literals, collection rites, imports, phrase formatting, and REPL lifecycle.
“When words take flight as bytecode.”
“When once mere verse was read by an interpreter, now each line burns upon the scroll, a spark translated into bytecode, and the VM breathes it into life again.”
- Bytecode VM (AVM) with a compact instruction set (arithmetic, logic, comparisons, vars, jumps, print, halt).
- AST → Bytecode compiler for expressions, assignments, prints, and
if/elsewith patching. - Disassembler for human‑readable listings with constants and jump targets.
.avmbinary format: save/load compiled chunks for fast start and distribution.- VM Execution Mode: compile source and run directly via
--vm. - REPL Hot‑Reload:
--vm-replcompiles each line and preserves globals in the live VM.
- Compile and run a scroll in the VM:
./ardent_vm.exe --vm path/to/scroll.ardent
- Disassemble a scroll or an existing
.avm:./ardent_vm.exe --disassemble path/to/scroll.ardent./ardent_vm.exe --disassemble demo.avm
- Save compiled bytecode to
.avm:./ardent_vm.exe --disassemble --save-avm demo.avm path/to/scroll.ardent
- Run a prebuilt
.avm:./ardent_vm.exe --vm demo.avm
- AVM REPL (hot‑reload globals):
./ardent_vm.exe --vm-repl
opcode.h: Instruction set (OP_PUSH_CONST,OP_LOAD/STORE,OP_ADD/SUB/MUL/DIV,OP_AND/OR/NOT,OP_EQ/NE/GT/LT/GE/LE,OP_JMP/JMP_IF_FALSE,OP_PRINT,OP_HALT).bytecode.h:Chunk,BytecodeEmitter, and.avmsave/load helpers.vm.h: Stack interpreter, flat slot variables, relative jumps, phrase and numeric semantics.compiler_avm.h: AST traversal, constant pool, slot symbols, and jump patching.disassembler.h: Mnemonic listing with constants and resolved targets.
- REPL retains globals by persisting VM slots; each line compiles with a fresh emitter to avoid code accumulation.
.avmformat:AVM1magic, typed constants (int/string/bool), code bytes — stable for simple sharing.- This phase prioritizes visibility and portability of execution; loops, spells, and collections in AVM are slated next.
When the poet’s craft becomes a scholar’s tool.
- Unified CLI launcher with clear modes and tooling.
- Scroll Loader for logical imports with sensible roots.
- Utility flags for developer workflows and demos.
- Packaging and install scripts for system-style layouts.
--versionprints version banner and build info.--interpret <file>runs the classic interpreter.--compile -o out.avm <file>emits AVM bytecode.--vm <file|.avm>compiles or loads and runs on the VM.--repl/--oraclestarts an interactive REPL.--disassemble <file|.avm>shows a mnemonic listing.--benchruns micro-benchmarks with readable timing.--lintwarns on simple style/structure issues.--prettyformats scrolls to a canonical layout (stub).--bannerprints a clean banner (screenshot-friendly).--scrollslists available stdlib scrolls.
When standard scrolls whisper across the realm and the tools grow wise.
- Standard Scrolls library in
scrolls/:chronicles,truths,numbers,alchemy,time,echoes— all written in Ardent and importable. - Poetic, ANSI‑colored tracebacks with highlighted strings/variables and call stack display.
- REPL (Oracle) boosts: history, multiline input, basic autocomplete, and refined output.
- Pretty printer:
--pretty <file>formats to canonical style. - Scroll loader enhancements: hierarchical roots, relative/tilde imports, version token parsing (
name@ver), and caching. - Diagnostics:
--lint(unused vars/spells, unreachable code, “is of is of” redundancy). - Benchmarking:
--benchreports execution time and memory (AST + runtime arenas). - Prologue metadata: optional header stored for tooling (
Title,Version,Author, extras).
./ardent.exe --pretty examples/blessing_and_return.ardent
./ardent.exe --lint examples/blessing_and_return.ardent
./ardent.exe --bench examples/blessing_and_return.ardent--demoruns a short poetic showcase.
- Search roots (fallback order):
./scrolls/$ARDENT_HOME/scrolls//usr/local/lib/ardent/scrolls/(Windows equivalent under%ProgramFiles%\Ardent\scrolls)
- Logical imports like
From the scroll of "chronicles"…resolve without explicit paths. - Friendly errors for missing scrolls.
- Bytecode preference planned: load
.avmwhen present alongside source.
- CMake install target places:
bin/ardent,bin/ardentc,bin/oraclelib/ardent/scrolls/share/ardent/examples/
- Scripts:
install.sh(Unix/macOS) andinstall.bat(Windows). - Installer message: “The Scholar’s Ink now flows through your system.”
- Embedded macros (see
src/version.h):ARDENT_VERSION,ARDENT_CODENAME,ARDENT_BUILD_DATE,ARDENT_BUILD_HASH.
- Shown in
--version,--banner, and installer output.
- Run the demo:
./ardent_vm.exe --demo
- List stdlib scrolls:
./ardent_vm.exe --scrolls
- Compile to AVM and run:
./ardent_vm.exe --compile -o saga.avm saga.ardent./ardent_vm.exe --vm saga.avm
- REPL hot-reload (from 1.2) persists globals; CLI now exposes
--repl. - Pretty-printer and linter are minimal stubs intended for iterative refinement.
Where verse becomes metal. Where spells are tempered into IR, and scrolls are forged into native steel.
This phase introduces a complete LLVM-based toolchain alongside the classic interpreter and VM. You can now generate LLVM IR, JIT-execute it with ORC v2, or AOT-compile to native executables.
- AST → LLVM IR generation: Fully implemented in
src/irgen/compiler_ir.cpp(module + function lowering, values, calls, control flow). - JIT execution (ORC v2): Working and stable; verified outputs; proper symbol resolution; ABI-stable runtime calls.
- AOT compilation (.obj → .exe / .so): LLVM emits object files via
TargetMachine. Windows native EXE generation works end-to-end. Entry shim + runtime linked; final EXE successfully runs Ardent code. - ArdentValue ABI & lowering rules: Struct layout finalized; constructors for boolean/phrase/number correct; validated under JIT and AOT.
- Type inference for numeric ops: Fast paths for +, -, * with safe dynamic fallback.
- Spell calls → direct LLVM calls: Spell declarations lower to
spell_<name>functions; calls inline cleanly where possible. - Control flow lowering (if/else/while): Completed with valid block structure; verified across multiple tests.
- Debug symbols / readable IR:
--emit-llvmemits readable IR for inspection and debugging; line info optional.
--emit-llvm <scroll>: Emit LLVM IR (.ll) next to the source.--emit-o <scroll> -o out.obj: Emit an object file for the host target.--aot <scroll> -o out.exe: AOT-compile to a native executable (Windows shown;.so/.dylibnext).--target <triple>: Override target triple for cross-compilation experiments.
Example on Windows (MinGW toolchain present):
# Emit human-readable LLVM IR
./build/ardent.exe --emit-llvm test_scrolls/numbers_test.ardent
# Forge native executable (produces numbers_native.exe)
./build/ardent.exe --aot test_scrolls/numbers_test.ardent -o numbers_native.exe
./numbers_native.exeNotes:
- On Windows Ardent prefers MinGW
g++to link with the static runtime; if unavailable, it falls back tolld-link(requires proper Windows SDK/MSVCLIBpaths). - Runtime debug prints can be silenced later; they’re helpful while validating the AOT pipeline.
"Where others see syntax, we see verse. Where others run code, we recite creation."
Ardent – A bridge between artistry and algorithm. A whisper to all who believe code can be beautiful.

Ardent — The Language of Poetic Code
© 2025 Emir Husain. All rights reserved.