Nlang is a statically typed language that combines approachable syntax with systems-level performance. It provides compile-time memory safety, rigorous type checking, an interpreter for rapid iteration, and a C transpiler for portable binaries.
- Intuitive syntax and clear blocks
- Static typing with practical inference
- Compile-time memory safety with immutability-by-default, ownership, borrowing, lifetimes, and move semantics
- Standard library for I/O, strings, math, and data structures
- Multiple execution modes: interpreter and C code generation
- LSP tooling with diagnostics, quick fixes, completion, and formatting
Prerequisites:
- Rust 1.70+
- GCC or Clang (for compiling generated C; path configurable via env or API)
Build:
cargo build --release
cargo testCreate a new project:
cargo run --bin nlang -- create my_project
cd my_projectOr initialize in existing directory:
mkdir my_project && cd my_project
cargo run --bin nlang -- initUpdate module registry (after adding/removing files):
cargo run --bin nlang -- mod-recDirect execution (interpreter):
cargo run --bin nlang -- run path/to/program.nlang
# Or inside a project directory:
cargo run --bin nlang -- runC code generation and compilation:
cargo run --bin nlang -- generate-c path/to/program.nlang -o program.c
gcc program.c -o program.exe
# Or compile directly via the CLI wrapper
cargo run --bin nlang -- compile path/to/program.nlang
# Inside a project, output goes to bin/ with project name:
cargo run --bin nlang -- compile- Via environment variables (resolution order:
NLANG_GCC→CC→ systemgcc):- Windows PowerShell:
$env:NLANG_GCC = 'C:\\msys64\\usr\\bin\\gcc.exe' cargo run --bin nlang -- compile path\to\program.nlang
- Unix shells:
NLANG_GCC=/usr/local/bin/gcc cargo run --bin nlang -- compile path/to/program.nlang
- Windows PowerShell:
- Via the Rust API:
use nlang::execution_engine::ExecutionEngine; use std::path::Path; let engine = ExecutionEngine::new_with_gcc_path("C\\msys64\\usr\\bin\\gcc.exe"); // or set later // let mut engine = ExecutionEngine::new(); // engine.set_gcc_path("C\\mingw64\\bin\\gcc.exe"); engine.compile_to_executable("def main() {}", "demo", Path::new("demo.exe")).unwrap();
Variables:
store x :i32 = 42; // immutable by default
@mut store y :i32 = 5; // mutable variable
y = y + 1; // ok
x = 10; // error: x is immutable
Ownership and borrowing:
store v = create_vector();
store v2 = v; // v moved; use-after-move is a compile error
@mut store a :i32 = 5;
store r1 = &a; // immutable borrow
store r2 = &@mut a; // mutable borrow; error if r1 is active
References and lifetimes:
// Reference types can appear in signatures
def head(xs: [int; 3]) -> &int { return &xs[0]; }
def bad() -> &int {
store x :i32 = 5;
return &x; // error: returns reference to local
}
Arrays and indexing:
@mut store arr: [int; 3] = [1, 2, 3];
arr[0] = 100; // ok: arr is mutable
store first = arr[1]; // reading is always fine
Control flow:
@mut store i = 0;
while (i < 3) { i = i + 1; }
for (@mut store j = 2; j >= 0; j = j - 1) { println(j); }
repeat { i = i + 1; } until i >= 10;
loop { break; }
Imports:
import std; // lazy-loads only called std functions
from std { sin, cos, tan } // eager import of specific functions
- Immutability by default;
@mutrequired for mutation - Single ownership; moves invalidate the source binding
- Borrowing rules:
- Multiple immutable borrows
- One mutable borrow; no other borrows concurrently
- Lifetimes inferred; references cannot outlive their data
- Move semantics tracked across control flow
- All checks happen at compile time (no GC, no ref-count overhead)
LSP (src/nscan/):
- Diagnostics include memory-safety hints and spans
- Quick fix to convert
store→@mut storeon immutability errors - Completion includes
@mut, std functions, and string/array methods - Formatting, goto-definition, rename, and workspace symbols
Syntax Highlighting:
- TextMate grammar (
nscan-ext/syntaxes/nlang.tmLanguage.json) supports@mut, borrows (&,&@mut), and bitwise operators
Location: src/std_lib/
- I/O:
print,println,input - Conversions:
str,int,float - Strings:
upper,lower,trim,contains,split,replace,substring,regex - Math:
pi,e,exp,ln,log10,log2,sqrt,pow_float,sin,cos,tan,asin,acos,atan,floor,ceil,round,fmod,gcd,lcm,factorial,nPr,nCr, stats (sum_float,mean_float,median_float,variance_float,stddev_float) - Collections:
reverse,sort - Time:
time_now,time_elapsed,sleep_ms,format_duration - Environment:
env_get,env_set,env_remove,env_exists - Crypto:
sha256,sha256_random
Source (.nlang)
↓
Lexer → Parser → Semantic (type checking)
↓
MemManager (immutability/ownership/borrowing/lifetimes/moves)
↓
Interpreter C Codegen
↓ ↓
Direct run C source → GCC/Clang → Executable
src/
├── ast/ # AST definitions
├── lexer/ # Tokenizer and errors
├── parser/ # Declarations, statements, expressions, types
├── semantic/ # Type checking and analysis
├── memmanager/ # Ownership, borrowing, lifetimes, moves, drops
├── interpreter/ # Execution engine
├── c_codegen/ # C transpiler (portable runtime helpers)
├── execution_engine/ # Unified orchestration for run/compile
├── module_sys/ # Module resolution and registry (mod-rec.toml)
├── nlang_libs/ # Built-in libraries (std_lib, env_man, etc.)
├── diagnostics/ # Error reporting and formatting
├── nscan/ # LSP server and tooling
├── cli.rs # CLI subcommands
├── lib.rs # Public API exports
└── main.rs # Application entry point
A typical NLang project:
my_project/
├── mod-rec.toml # Module registry (auto-generated)
├── src/
│ └── main.nlang # Entry point
└── bin/ # Compiled output
See nlang_examples/ for runnable samples:
- Hello world, loops, control flow, functions
- Arrays and multi-dimensional arrays (
13_comprehensive_array_test.nlang) - String library demos (
25_string_library_advanced.nlang) - Math std lib demo (
26_math_std_lib_demo.nlang) - Time library demo (
28_time_library_demo.nlang) - Environment variables (
29_test_env_man.nlang) - SHA-256 (pure nlang and built-in) (
21_sha256.nlang) - Memory safety showcase (
27_memory_safety_showcase.nlang)
cargo testMIT License. See LICENSE.
- Rust community
- Contributors and users of Nlang