A modern, expressive, human-readable programming language built for clarity, safety, native performance, and compiler-grounded AI tooling.
Getting Started • Language Tour • CLI Reference • Standard Library • VS Code Extension • Contributing
Fidan is a general-purpose programming language that prioritizes human readability without sacrificing power. It reads almost like English, yet compiles to native code and runs real threads. It is statically typed with full inference, null-safe by design, and ships a complete toolchain: formatter, linter, fixer, LSP server, REPL, interpreter, Cranelift JIT, Cranelift AOT, optional LLVM AOT, package manager, self/toolchain installer, and compiler-backed AI explain/fix/improve workflows.
object Person extends Creature {
var name oftype string
var age oftype integer
new with (certain name oftype string, optional age oftype integer = 18) {
this.name = name
this.age = age
parent(species set "Human")
}
action introduce returns nothing {
print("My name is {this.name} and I am {this.age} years old!")
}
}
action main {
var john = Person("John" also 20)
john.introduce()
print("Hello, {john.name}!")
}
main()
Most languages make a trade-off: either readable (Python) or fast (C++/Rust) or safe (Rust) — but rarely all three at once without significant ceremony. Fidan's goal is to hit all three without requiring you to understand lifetimes, borrow checkers, or cryptic syntax.
| Goal | How Fidan achieves it |
|---|---|
| Readable code | English-like syntax (and, or, not, is, certain, otherwise when…) |
| Safety without ceremony | Null-safety analysis, certain non-null guarantees, data-race detection at compile time |
| Performance | MIR-level optimization passes + Cranelift JIT (@precompile, auto hot-path with safe interpreter fallback) + Cranelift/LLVM AOT |
| Real concurrency | parallel uses OS threads; spawn/await and concurrent provide structured same-thread async-style scheduling |
| AI-native tooling | explain --ai, fix --ai, fix --improve, and exec ai mcp are grounded in compiler facts: diagnostics, inferred types, reads/writes, call graphs, type maps, and static traces |
| Great tooling | Formatter, linter, fixer, REPL, LSP, VS Code extension, package flow, self updates, optional toolchains — all built-in, not plugins |
| Reproducible debugging | --replay captures stdin and replays crashes exactly |
| Readable errors | Ariadne-rendered diagnostics with source context, inline carets, fix-it patches |
| Feature | Fidan | Python | TypeScript | Go | Rust |
|---|---|---|---|---|---|
| English-like readable syntax | ✅ | ❌ | ❌ | ❌ | |
| Static typing + full inference | ✅ | ❌ | ✅ | ✅ | ✅ |
| Null safety (compile-time) | ✅ | ❌ | ✅ | ||
certain non-null parameter contract |
✅ | ❌ | ❌ | ❌ | |
| Data-race detection (compile-time) | ✅ | N/A | N/A | ✅ | |
| Real OS thread parallelism | ✅ | ❌ (GIL) | ❌ | ✅ | ✅ |
Built-in spawn/await model |
✅ | ✅ | ✅ goroutines | ✅ | |
JIT compilation (@precompile) |
✅ | ❌ | ❌ | ❌ | ❌ |
| Built-in formatter | ✅ | ❌ (black) | ❌ (prettier) | ✅ | ✅ |
| Built-in linter + auto-fixer | ✅ | ❌ (ruff) | ❌ | ✅ clippy | |
| Built-in REPL | ✅ | ✅ | ❌ | ❌ | ❌ |
| Built-in LSP server | ✅ | ❌ (pylsp) | ✅ (tsserver) | ||
| Replay-based crash reproduction | ✅ | ❌ | ❌ | ❌ | ❌ |
explain line-level static analysis |
✅ | ❌ | ❌ | ❌ | ❌ |
| Compiler-grounded AI explain/fix/improve | ✅ | ❌ | ❌ | ❌ | ❌ |
| First-class test blocks | ✅ | ❌ (unittest) | ❌ (jest) | ✅ | ✅ |
Hot reload (--reload) |
✅ | ❌ | ❌ | ❌ | ❌ |
String synonyms (is, equals, and, …) |
✅ | ❌ | ❌ | ❌ | ❌ |
check pattern matching |
✅ | ❌ | ❌ | ✅ | |
| Multi-line comments (nested) | ✅ | ❌ | ❌ | ❌ | ✅ |
If you just want to use Fidan, you do not need to build the compiler from source.
Use the bootstrap script from this repository:
# Linux / macOS
curl -fsSL https://fidan.dev/install.sh | sh# Windows (PowerShell)
iwr https://fidan.dev/install.ps1 -UseBasicParsing | iexThe bootstrap scripts above download the latest published Fidan release for your host, install it into the standard Fidan install directory, and make the first installed version active.
On Windows, the bootstrap script and the Inno Setup installer automatically ensure the required Microsoft Visual C++ Redistributable is present before activating Fidan. The WinGet package also declares that dependency so WinGet can install it first when needed.
On Windows, each release cycle also ships an Inno Setup bootstrap installer and submits a matching WinGet package update.
# Windows (Winget)
winget install --id Fidan.Fidan --exactFor the Inno Setup installer asset (fidan_windows_bootstrap_v<release>.exe):
- the
Versionbootstrap parameter defaults to the installer's own release version - you can override that default to the newest release by setting version to
latest - unattended override example:
/VERSION=latest
Published archives are also available from GitHub Releases if you prefer downloading them manually:
Stable release archives also ship the libfidan embedding bundle:
- the platform
libfidanshared library - the platform
libfidanstatic library include/fidan.h- a tiny C embedding example under
examples/embed_c/
On Windows, manual .tar.gz extraction still assumes the Microsoft Visual C++ Redistributable for your architecture is already installed on the machine.
For Rust hosts built from source, the workspace also includes a small safe wrapper crate:
crates/fidan-embed
After bootstrap install, verify it with:
fidan --versionTo install or refresh the latest published version:
fidan self installTo switch to the newest installed version:
fidan self useTo uninstall:
fidan self removefidan self install defaults to latest, so you only need to pass an explicit version when installing or refreshing a specific release.
- To build from source: Rust toolchain (1.82+): rustup.rs
git clone https://github.com/fidan-lang/fidan.git
cd Fidan
cargo build --releaseThe fidan binary will be at target/release/fidan. Add it to your PATH:
# Linux / macOS
export PATH="$PWD/target/release:$PATH"
# Windows (PowerShell)
$env:PATH = "$PWD\target\release;" + $env:PATHfidan --versionIf you are embedding Fidan into another host application, use the libfidan
artifacts shipped in the stable release archives rather than linking directly
against the internal workspace crates.
Current embedding contract:
- create a VM with
fidan_vm_new() - evaluate source or a file with
fidan_eval()/fidan_eval_file() - inspect values through the
fidan_value_*helpers - free returned values with
fidan_value_free()
The initial libfidan slice returns the top-level result binding when the
program defines one. If no result binding exists, a successful run returns
nothing.
For Rust embedders working from the repository, crates/fidan-embed wraps the
raw C ABI with safe Vm / Value types and Result-based error handling.
Create a file hello.fdn:
print("Hello, world!")
Run it:
fidan run hello.fdnvar name = "Alice" # inferred: string
var age = 30 # inferred: integer
var score = 9.5 # inferred: float
var active = true # inferred: boolean
var nothing_here = nothing # nothing (null)
var count oftype integer # declared, not yet assigned — defaults to nothing
var pi oftype float = 3.14159 # explicit type + value
Type inference is full and bidirectional. Explicit oftype annotations are optional but always respected.
Multi-line strings are supported directly in both normal and raw string literals. Normal strings still process escapes and interpolation; raw strings preserve the body verbatim.
var plain = "First line
Second line
Third line"
var raw = r"alpha
{value}
omega"
var name = "Ada"
var interp = "Hello,
{name}!
Done."
For a runnable smoke example, use test/examples/multiline_strings.fdn:
fidan run test/examples/multiline_strings.fdn
fidan build --backend cranelift test/examples/multiline_strings.fdn
fidan build --backend llvm test/examples/multiline_strings.fdnaction greet with (certain name oftype string) returns string {
return "Hello, {name}!"
}
print(greet("Fidan")) # Hello, Fidan!
certainmeans the parameter must be non-null at call time — enforced at compile timeoptional(default) parameters can benothing- Parameters can use
alsoor,as separators
Named arguments work at every call site:
action create_user with (certain name oftype string, optional age oftype integer = 18) {
print("{name} is {age} years old")
}
create_user(name set "Alice", age = 25) # both forms work
create_user("Bob") # positional, age defaults to 18
object Animal {
var sound oftype string
new with (certain sound oftype string) {
this.sound = sound
}
action speak returns string {
return "I say: {this.sound}"
}
}
object Dog extends Animal {
var name oftype string
new with (certain name oftype string) {
this.name = name
parent(sound set "Woof")
}
action fetch returns nothing {
print("{this.name} fetches the ball!")
}
}
var rex = Dog("Rex")
print(rex.speak()) # I say: Woof
rex.fetch() # Rex fetches the ball!
Extension actions let you add methods to existing objects without modifying them:
action bark extends Dog {
print("{this.name} goes WOOF WOOF!")
}
rex.bark()
# if / otherwise when / else
if age greaterthan 18 {
print("Adult")
} otherwise when age equals 18 {
print("Just turned 18!")
} else {
print("Minor")
}
# Synonyms: use whichever reads most naturally
if score > 9 and score <= 10 {
print("Excellent")
}
Ternary expressions:
var label = "pass" if score >= 5 else "fail"
# Implicit-subject shorthand (Fidan-specific)
var display = person if is not nothing else defaultPerson
# Equivalent to:
var display = person if (person != nothing) else defaultPerson
# Or simply:
var display = person ?? defaultPerson # null-coalescing operator
# for with range (exclusive)
for i in 1..10 {
print(i)
}
# for with inclusive range
for i in 1...10 {
print(i)
}
# for over a list
var fruits = ["apple", "banana", "cherry"]
for fruit in fruits {
print(fruit)
}
# while
var n = 0
while n < 5 {
n += 1
}
var code = 404
check code {
200 => print("OK")
404 => print("Not found")
500 => print("Server error")
_ => print("Unknown code: {code}")
}
# Inline check expression
var message = check code {
200 => "OK"
404 => "Not found"
_ => "Other"
}
var name = "Fidan"
var version = 1
print("Welcome to {name} v{version}!") # simple variable
print("2 + 2 = {2 + 2}") # expression
print("{name.upper()} is awesome!") # method call
print("Pi is approximately {floor(3.14159)}") # function call
Nested multi-line comments are fully supported:
#/
This is a comment.
#/ And this is nested. /#
Still in the outer comment.
/#
attempt {
var data = readFile("config.json")
print(data)
} catch error {
print("Failed: {error}")
} otherwise {
print("File read successfully.") # runs only when no error
} finally {
print("Cleanup always runs.")
}
You can annotate the error type:
attempt {
riskyOperation()
} catch error -> string {
print("Got a string error: {error}")
}
Fidan has three concurrency models:
action fetch_data with (certain url oftype string) returns string {
# ... HTTP call ...
return "data from {url}"
}
var handle1 = spawn fetch_data("https://api.example.com/users")
var handle2 = spawn fetch_data("https://api.example.com/posts")
var users = await handle1
var posts = await handle2
print("Got {users} and {posts}")
spawn is lazy: the task is scheduled on the current thread and runs at
await/join checkpoints. Same-thread tasks are driven by a cooperative FIFO
scheduler, so concurrent blocks and nested spawn/await yield to other
ready same-thread tasks instead of starting OS threads.
parallel {
task { heavyComputation() }
task { processBigFile("data.csv") }
task { renderChart() }
}
# All three tasks ran in parallel — execution continues here when all finish
parallel for item in largeDataset {
processItem(item) # each item processed on a separate thread
}
concurrent {
task { readFromDatabase() }
task { callExternalAPI() }
}
concurrent is cooperative and same-thread: it shares the caller thread,
preserves normal mutable-state semantics, and lets await yield to sibling
ready tasks in the block.
var counter = Shared(0)
parallel for i in 1..100 {
counter.update(action with (val) { return val + 1 })
}
print(counter.get()) # 99 (safe, no data races)
The compiler enforces this: writing to a non-Shared variable from a parallel block is a compile-time error (E0401).
action divide with (certain a oftype integer, certain b oftype integer) returns float {
return a / b
}
divide(10, 0) # runtime panic — but never a null pointer crash
divide(nothing, 5) # compile-time error — `certain` blocks this
Variables default to nothing. The null-safety pass (W2006) warns whenever a possibly-null value is used in an unsafe context:
var name oftype string # nothing by default
print(name.upper()) # W2006: `name` may be nothing here
var numbers = [1, 2, 3, 4, 5]
var doubled = [x * 2 for x in numbers] # [2, 4, 6, 8, 10]
var evens = [x for x in numbers if x % 2 == 0] # [2, 4]
var squares = [x * x for x in 1..6] # [1, 4, 9, 16, 25]
# Dict comprehension
var sq_map = {x: x * x for x in numbers} # {"1": 1, "2": 4, ...}
var filtered_map = {x: x * 2 for x in numbers if x > 2}
No test framework to install. Tests live in your source files:
action add with (certain a oftype integer, certain b oftype integer) returns integer {
return a + b
}
test "basic addition" {
assert(add(2, 3) == 5)
assert_eq(add(0, 0), 0)
assert_ne(add(1, 1), 3)
}
test "negative numbers" {
assert_eq(add(-5, 5), 0)
assert(add(-10, -10) < 0)
}
Run them with fidan test yourfile.fdn. Each test reports pass/fail with coloured output.
@precompile # JIT-compile this action at startup (eager, not lazy)
action fibonacci with (certain n oftype integer) returns integer {
if n <= 1 { return n }
return fibonacci(n - 1) + fibonacci(n - 2)
}
@deprecated("Use fibonacci2 instead")
action fibonacci_old with (certain n oftype integer) returns integer {
# ...
}
Fidan can import native functions from shared libraries through @extern.
@extern("./mylib.dll", symbol = "add_i64")
action addNative with (a oftype integer, b oftype integer) returns integer
assert_eq(addNative(20, 22), 42)
Native ABI @extern currently supports:
- arbitrary numbers of parameters
- parameter types:
integer,float,boolean,handle - return types:
integer,float,boolean,nothing,handle
Example with mixed native types:
@extern("./mylib.dll", symbol = "mix_values")
action mixValues with (
a oftype integer,
b oftype float,
c oftype boolean,
d oftype handle
) returns integer
assert_eq(mixValues(7, 8.0, true, 9), 124)
For richer values such as strings, lists, dicts, tuples, or dynamic objects, use the boxed Fidan ABI:
@unsafe
@extern("./mylib.dll", symbol = "echo_boxed", abi = "fidan")
action echoBoxed with (text oftype string) returns string
@extern rules:
@externactions must be top-level and must omit their body- native ABI is for scalar types only
abi = "fidan"requires@unsafe@precompilecannot be combined with@externparallel actioncannot be combined with@extern
For AOT builds, add link = "..." so the native import library is available at link time:
@extern("./mylib.dll", symbol = "add_i64", link = "./mylib.lib")
action addNative with (a oftype integer, b oftype integer) returns integer
There is a complete local smoke demo in LOCAL/extern-cpp/.
# Standard library modules
use std.io
use std.math
use std.math.{sqrt, floor, ceil}
use std.collections
# User modules (file-relative)
use mymodule # → mymodule.fdn or mymodule/init.fdn
use utils.helpers # → utils/helpers.fdn
# Aliased import
use "./other.fdn" as other
# Re-export
export use std.math # consumers of this module also get std.math
Hot functions are automatically JIT-compiled by Cranelift after a configurable number of calls (default: 500). You can force eager compilation:
@precompile
action hot_inner_loop with (certain n oftype integer) returns integer {
var sum = 0
for i in 0..n { sum += i }
return sum
}
Or tune from the CLI:
fidan run app.fdn --jit-threshold 100 # compile after 100 calls
fidan run app.fdn --jit-threshold 0 # disable JIT entirelyFidan's AI features are implemented as first-party tooling around the compiler, not as a prompt-only layer beside it.
The deterministic analysis path can produce structured context for a file or line range:
- selected source text
- diagnostics and stable diagnostic codes
- inferred types
- reads and writes
- line-level risk notes such as possible division by zero or out-of-bounds access
- module outline and imports
- related symbols
- call graph
- type map
- static runtime trace
That context feeds the optional AI analysis toolchain used by explain --ai, fix --ai, fix --improve, and editor commands.
fidan toolchain add ai-analysis
fidan exec ai setup
fidan exec ai doctor
fidan explain app.fdn --line 42 --ai "focus on data flow"
fidan fix app.fdn --ai --in-place
fidan fix app.fdn --improve "simplify without changing behavior" --in-place
fidan exec ai mcpThe AI toolchain supports OpenAI-compatible APIs, Anthropic, local Ollama or LM Studio endpoints, and custom OpenAI-compatible endpoints. API keys can be stored through the OS keychain or supplied through environment variables.
fix --ai and fix --improve return structured hunks with exact old/new text and reasons. The CLI validates hunks before applying them, rejects empty or no-op edits, and still runs deterministic compiler fixes first. This keeps AI assistance inside a reviewable source-editing workflow instead of bypassing the compiler.
The built-in MCP mode exposes the same compiler-grounded context to compatible AI clients:
fidan exec ai mcpfidan <COMMAND> [OPTIONS] [FILE]
| Command | Description |
|---|---|
fidan run <file> |
Run a Fidan source file |
fidan build <file> |
Compile to a native binary |
fidan check <file> |
Type-check and lint without running |
fidan fix <file> |
Auto-apply high-confidence fixes |
fidan format <file> |
Format source code |
fidan test <file> |
Run inline test {} blocks |
fidan profile <file> |
Run with profiling output |
fidan repl |
Start the interactive REPL |
fidan lsp |
Start the Language Server (used by editors) |
fidan explain --diagnostic <code> |
Show detailed explanation of a diagnostic code |
fidan explain <file> --line N |
Explain what line N does (static analysis) |
fidan new <name> |
Scaffold a new Fidan project |
fidan new <name> --package |
Scaffold a Dal-ready package with dal.toml and src/init.fdn |
fidan self <command> |
Install, switch, list, and remove self-managed Fidan versions |
fidan toolchain <command> |
Install and inspect optional toolchains such as LLVM and AI analysis |
fidan exec <namespace> |
Run commands registered by installed toolchains, such as fidan exec ai ... |
fidan dal <command> |
Work with the Dal package registry |
| Command | Description |
|---|---|
fidan dal login |
Store a Dal API token in the OS keychain for CLI use |
fidan dal logout |
Remove the stored Dal API token from the OS keychain |
fidan dal whoami |
Show the authenticated Dal account |
fidan dal search <query> |
Search packages on Dal |
fidan dal info <package> |
Show package metadata and published versions |
fidan dal add <package> |
Download and vendor a package into a local importable module directory |
fidan dal remove <package> |
Remove a local or global package install |
fidan dal package [path] |
Validate the package layout locally and build a canonical Dal .tar.gz archive |
fidan dal publish [path] |
Run the same local validation, build the archive, and publish it to Dal |
fidan dal yank <package> <version> |
Yank a published version |
fidan dal unyank <package> <version> |
Unyank a published version |
fidan dal add installs packages into an import-safe local module directory.
For example, a Dal package named my-package is installed so you can import it
in Fidan as:
use my_package
Package requests can include semver constraints and feature selections:
fidan dal add my-package[json,cli] --version "^1.2"
fidan dal add my-tool --globalDal resolves dependencies into dal.lock, supports optional dependencies through feature wiring, and can install package-provided CLI entries declared in [cli] metadata.
Dal token lookup order:
--tokenargument tofidan dal loginFIDAN_DAL_API_TOKENenvironment override- OS keychain / credential manager
Registry lookup order:
--registryFIDAN_DAL_REGISTRY- default:
https://api.dal.fidan.dev
Dal package preflight validation happens locally before archive creation or upload. A package must contain:
dal.tomlsrc/init.fdn- only allowed top-level entries such as
README*,LICENSE*,CHANGELOG.md,src/,examples/,tests/,docs/, andassets/ - no symlinks, path traversal, or unsafe archive paths
| Flag | Description |
|---|---|
--reload |
Watch source files and re-run on change |
--strict |
Treat select warnings as errors |
--trace short|full|compact |
Show call stack on panic |
--jit-threshold N |
JIT after N calls (0 = off) |
--sandbox |
Deny file and environment access by default |
--allow-read <paths> |
Whitelist read paths (sandbox mode) |
--allow-write <paths> |
Whitelist write paths (sandbox mode) |
--allow-env |
Allow environment variable access (sandbox) |
--time-limit <secs> |
Hard wall-time limit |
--mem-limit <mb> |
Hard memory limit |
--max-errors N |
Stop after N errors |
--suppress W1005,W2006 |
Suppress specific diagnostic codes |
--emit tokens|ast|hir|mir |
Dump an intermediate representation |
--replay <id|path> |
Replay a captured crash scenario |
| Flag | Description |
|---|---|
--output <path> |
Output binary path |
--release |
Enable the release preset (O3, full LTO, strip all, native CPU unless overridden) |
--opt O0|O1|O2|O3|Os|Oz |
Select optimization level |
--lto off|full |
Control link-time optimization |
--strip off|symbols|all |
Control symbol stripping |
--backend auto|cranelift|llvm |
Select native backend |
--target-cpu <spec> |
Use generic, native, a CPU name, or a CPU plus feature string where supported |
--lib-dir <path> |
Add native library search path for AOT linking |
--link-runtime static|dynamic |
Choose runtime linkage mode |
--linker <path-or-name> |
Override the linker used for AOT output |
--emit tokens|ast|hir|mir|obj |
Dump intermediate representation or object output |
Fidan can manage its own installed versions and optional toolchains from the same CLI.
fidan self list
fidan self install
fidan self use
fidan self remove
fidan toolchain available
fidan toolchain add llvm
fidan toolchain add ai-analysis
fidan toolchain list
fidan exec ai help
fidan exec ai setup
fidan exec ai doctor
fidan exec ai mcpOptional toolchains are versioned release artifacts with compatibility metadata. The LLVM toolchain powers fidan build --backend llvm; the AI analysis toolchain powers model-backed explain/fix/improve workflows and exposes the ai exec namespace.
fidan run app.fdn --reload
# [↻ reload] app.fdn changed — re-runningAny .fdn file in the same directory triggers a re-run. Useful during development.
When your program crashes and it read from stdin, Fidan saves the input sequence:
error[R0001]: division by zero
→ replay.fdn:7
hint: fidan run replay.fdn --replay a3f82c91
Run that command to reproduce the exact crash, every time, without re-typing inputs.
fidan repl
>>> var x = 10
>>> x * x
100
>>> :type x * x
: integer
>>> :last
R0001: division by zero at line 3
>>> :last --full
... full error history ...The REPL supports multi-line input, continuation prompts (...), :cancel to abort a block, and :type <expr> to inspect inferred types.
fidan fix app.fdn
fidan fix app.fdn --in-place
fidan fix app.fdn --ai
fidan fix app.fdn --ai "preserve public API" --in-place
fidan fix app.fdn --improve "reduce duplication" --in-placeThe default mode prints the proposed result so you can review it first. --in-place rewrites the file.
Deterministic high-confidence fixes always run first. With the AI analysis toolchain installed, --ai asks for additional diagnostic-oriented repairs and --improve / --refactor asks for behavior-preserving cleanups. AI edits are returned as exact hunks and validated before application.
fidan explain app.fdn # explain the whole file
fidan explain app.fdn --line 42
fidan explain app.fdn --end-line 20
fidan explain app.fdn --line 10 --end-line 20
fidan explain app.fdn:42-45 # alias for range form
fidan explain file.fdn --ai # AI-powered explanation of the whole file (requires toolchain)
fidan explain --diagnostic E0401
fidan explain --last-errorFor each line in range, Fidan reports:
- What it does (plain-English description)
- Inferred type of the expression
- Reads (variables accessed)
- Writes (variables modified)
- Could go wrong (division by zero, out-of-bounds index, overflow…)
Fidan's diagnostics are designed to be read, not feared.
Every diagnostic includes:
- Source context — the offending line(s) with line numbers
- Inline caret — exactly which token is wrong and why
- Fix-it patch — a green
+block showing the corrected version where applicable - Cause chain — if error A caused error B, both are shown linked
fidan fix— automatically applies all high-confidence patches
Diagnostic codes:
| Prefix | Category | Example |
|---|---|---|
E01xx |
Undefined names / scoping | E0101 unknown name |
E02xx |
Type mismatches | E0201 type mismatch on assignment |
E03xx |
Call errors | E0301 missing required argument |
E04xx |
Parallelism / data race | E0401 shared write in parallel block |
E02xx |
Null safety | E0205 non-null operand used as null |
W10xx |
Code quality | W1005 unused import |
W20xx |
Null safety warnings | W2006 possibly-null dereference |
W50xx |
Performance hints | W5001 dynamic type in hot loop |
R9xxx |
Runtime errors | R9001 parallel task failed |
fidan explain --diagnostic E0401 # print a full page of documentation for this code| Module | What it provides |
|---|---|
std.async |
Same-thread Pending helpers: sleep, ready, gather, waitAny, timeout |
std.collections |
range, hashset, Queue, Stack, zip, enumerate, chunk, window, partition, groupBy, reducers, set operations |
std.env |
Environment variable access and script arguments |
std.io |
Console I/O, files, directories, paths, environment convenience, terminal helpers |
std.json |
Parse, validate, stringify, pretty-print, read, and write JSON with soft-error mode |
std.math |
sqrt, abs, floor, ceil, round, pow, log, trig, randomness, numeric predicates, constants |
std.regex |
Match, find, capture, replace, split, and validate regular expressions |
std.string |
Casing, trimming, splitting, joining, replacing, slicing, padding, parsing, character/codepoint helpers |
std.test |
assert, assertEq, assertNe, ordering/type/nothing assertions, fail, skip |
std.parallel |
parallelMap, parallelFilter, parallelForEach, parallelReduce |
std.time |
sleep, timestamps, duration helpers |
Usage:
use std.math.{sqrt, PI}
use std.collections
var stack = Stack()
stack.push(1)
stack.push(2)
print(stack.pop()) # 2
print(sqrt(144)) # 12.0
print(PI) # 3.141592653589793
Install from the VS Code Marketplace or build locally:
git clone https://github.com/fidan-lang/fidan-editors.git
cd fidan-editors/vscode
npm install
npm run compile
# Press F5 to launch the Extension Development HostFeatures:
| Feature | Status |
|---|---|
| Syntax highlighting (TextMate grammar) | ✅ |
| Semantic token highlighting | ✅ |
| Error and warning diagnostics (LSP) | ✅ |
| Hover documentation (type + declaration) | ✅ |
| Auto-completion (dot-trigger, named args, cross-module) | ✅ |
| Signature help | ✅ |
| Go to definition | ✅ |
| Find all references | ✅ |
| Rename symbol | ✅ |
| Format on save | ✅ |
| Inlay hints (inferred types) | ✅ |
| Code actions / fix-it patches | ✅ |
| Folding ranges | ✅ |
| Document outline | ✅ |
| 19 built-in code snippets | ✅ |
| Bracket / comment auto-close | ✅ |
| All CLI commands in Command Palette | ✅ |
| Debug adapter | 🔜 planned |
Commands available in the Command Palette (Ctrl+Shift+P):
| Command | Description |
|---|---|
Fidan: Run Current File |
Run the open file (with mode picker: once / reload) |
Fidan: Check File |
Type-check and lint (with strict mode option) |
Fidan: Fix File |
Apply fixes (apply or dry-run preview) |
Fidan: Format Current File |
Format via LSP |
Fidan: Build File |
Build binary (debug or release) |
Fidan: Run Tests in Current File |
Run test {} blocks |
Fidan: Profile Current File |
Profile execution |
Fidan: Explain Diagnostic Code |
Prompt for a code → fidan explain --diagnostic |
Fidan: Explain Current Line(s) |
Selection-aware fidan explain |
Fidan: New Project |
Scaffold project with folder picker |
Fidan: Open REPL |
Open the interactive REPL |
Fidan: Restart Language Server |
Restart LSP |
Fidan is written in Rust and organized as a Cargo workspace of focused crates:
Source Text → Lexer → Parser → AST
↓
Type Checker + Symbol Resolution
↓
HIR (typed, desugared)
↓
MIR (SSA / control-flow graph)
↓
Optimization Passes (constant folding, inlining,
copy propagation, DCE, unreachable pruning)
↓
┌─────────────────────┼──────────────────────┐
Interpreter Cranelift JIT LLVM AOT
(always works) (@precompile, hot (fidan build
functions ≥ N calls) --release)
The same MIR feeds all three backends — no behavioral divergence between run modes.
| Crate | Role |
|---|---|
fidan-config |
Shared language metadata for builtins, decorators, types, aliases, and receiver methods |
fidan-source |
SourceFile, Span, SourceMap |
fidan-lexer |
Tokenizer, synonym normalization |
fidan-ast |
All AST node types, arena allocator |
fidan-parser |
Recursive-descent + Pratt expression parser |
fidan-secrets |
OS keychain / credential storage helpers used by registry and AI tooling |
fidan-diagnostics |
Diagnostic types, ariadne rendering, fix engine, stable code explanations |
fidan-typeck |
Symbol tables, type inference, null-safety, data-race detection |
fidan-hir |
Typed, desugared high-level IR |
fidan-mir |
SSA-form mid-level IR, CFG |
fidan-passes |
Optimization and analysis passes |
fidan-runtime |
Value model, COW collections, object model, Shared<T> |
fidan-interp |
MIR tree-walking interpreter |
fidan-extern-fixture |
Native interop test fixture library |
libfidan |
C ABI embedding surface |
fidan-embed |
Safe Rust wrapper around libfidan |
fidan-codegen-cranelift |
Cranelift JIT backend |
fidan-codegen-llvm |
LLVM AOT backend |
fidan-llvm-helper |
Packaged helper binary for the optional LLVM toolchain |
fidan-ai-analysis-helper |
Packaged helper binary for AI explain/fix/improve and MCP workflows |
fidan-stdlib |
Rust-backed standard library |
fidan-driver |
Compiler driver and CLI-facing orchestration across frontends/backends/toolchains |
fidan-fmt |
Canonical source formatter |
fidan-lsp |
Full LSP server |
fidan-cli |
fidan binary — all subcommands |
| Milestone | Status |
|---|---|
| Lexer + Parser | ✅ Complete |
| Type checker + null safety + data-race detection | ✅ Complete |
| HIR + MIR lowering | ✅ Complete |
| MIR optimization passes | ✅ Complete |
| Interpreter (tree-walking + MIR) | ✅ Complete |
Real OS thread parallelism (parallel, spawn/await) |
✅ Complete |
Cranelift JIT (@precompile, auto hot-path with interpreter fallback for unsupported MIR) |
✅ Complete |
Standard library (std.async, std.collections, std.env, std.io, std.json, std.math, std.parallel, std.regex, std.string, std.test, std.time) |
✅ Complete |
| Full LSP server | ✅ Complete |
| VS Code extension | ✅ Complete |
Hot reload (--reload) |
✅ Complete |
Replay-based crash reproduction (--replay) |
✅ Complete |
LLVM AOT backend (fidan build --release) |
✅ Complete |
| Package manager (DAL) | ✅ Complete |
AI analysis toolchain (explain --ai, fix --ai, fix --improve, MCP) |
✅ Complete |
| Debug adapter (VS Code breakpoints) | 🔜 Planned |
| Playground (browser WASM) | 🔜 Planned |
Contributions are welcome! By submitting a pull request or patch you acknowledge that you have read CONTRIBUTING.md — your contribution becomes part of the Fidan project under its license terms.
- Fork the repository
- Create a feature branch (
git checkout -b feature/my-feature) - Make your changes and ensure
cargo test --workspacepasses - Open a pull request with a clear description
Please sign the CLA before your first PR is merged (the bot will prompt you automatically).
This repository ships git hooks in .githooks.
Install them after cloning:
.\scripts\install-git-hooks.ps1That script sets core.hooksPath to .githooks for this repository.
You can verify the hook path with:
git config --get core.hooksPathThe current pre-commit hook automatically runs cargo fmt --all when staged .rs files are present, then re-stages the formatted files for you.
Development setup:
# Build all crates
cargo build
# Run all tests
cargo test --workspace
# Run a specific example
cargo run -- run test/examples/test.fdn
# Run with MIR dump
cargo run -- run test/examples/test.fdn --emit mir
# Build the VS Code extension
git clone https://github.com/fidan-lang/fidan-editors.git
cd fidan-editors/vscode && npm install && npm run compileThe Fidan programming language — including its source code, compiler, interpreter, runtime, and official distributions — is licensed under the Apache License 2.0 with Fidan Additional Terms.
Key points:
- ✅ You can use Fidan to write and ship programs — those programs are entirely yours
- ✅ You can contribute to this repository
- ✅ You can study and read the source
- ❌ You cannot commercially redistribute or sell the Fidan compiler/runtime as a competing product
- ❌ You cannot use the Fidan™ name or logo for derivative languages without permission
See LICENSE for the full text.
Fidan™ is a trademark of Kaan Gönüldinc (AppSolves).

