Introduction to AzLang
AzLang is a minimal, blazingly fast, and readable systems programming language engineered for direct bare-metal execution, sub-kilobyte binary output, and zero-runtime overhead.
AzLang blends Python-like visual clarity, Rust-like memory control, and TypeScript-like type safety, stripping away heavy runtime abstractions and external runtime daemons.
Key Characteristics
- Zero-VM Execution: No virtual machines, dynamic garbage collectors, or heavy runtime initialization routines (
crt1.o). Execution lowers directly to native machine code. - Microsecond Compilations: A lean frontend passes verified AST directly to fasm assembly and native machine instructions in a single pass.
- Lean Binary Footprint: Produces standalone, self-contained ELF executables — a hello world program measures 180 bytes, and a comprehensive multi-module program stays around 2 KB.
- Absence of Moving Parts: Eliminates runtime state machines, dynamic heap leaks, and unwinding tables by design.
- Direct ABI & Syscall Interop: High-performance systems interfaces via native
@linkdirectives and direct kernel syscall invocation (x86_64register calling conventions).
Architectural Snapshot
┌───────────────────────────────────────────────────────────────────────────────────┐
│ AZLANG ARCHITECTURE │
│ │
│ [Source Code (.az)] │
│ │ │
│ ▼ │
│ [Tokenizer & Indent Engine] │
│ │ │
│ ▼ │
│ [AST Construction & Validation] │
│ │ │
│ ▼ │
│ [Transpiler → fasm Assembly (.asm)] ──► @link syscall stubs included inline │
│ │ │
│ ▼ │
│ [fasm: single-pass assembler & linker] │
│ │ │
│ ▼ │
│ [~180 Byte Bare-Metal ELF] │
└───────────────────────────────────────────────────────────────────────────────────┘
Real Syntax At a Glance
Here is an authentic snippet from the AzLang SDK illustrating low-level declarations, enumerations, ABI linking, and entry invocations:
enum FD
Stdin
Stdout
Stderr
@link("./sdk/src/write.s")
op write(FD fd, const str val, const int size): void
@link("./sdk/src/exit.s")
op exit(const int val): void
write(Stdout, "Hello, Bare Metal AzLang!\n", 26)
exit(0)
The Minimalist Doctrine
In classical aerospace and mechanical engineering, the highest reliability is achieved not by complicating safety redundancies, but by engineering unnecessary valves and moving parts out of the machine entirely.
AzLang brings this functional minimalist mindset to software engineering:
┌───────────────────────────────────────────────────────────────────────────────────┐
│ AZLANG FIELD DOCTRINE │
│ │
│ [Source Code] ──► [fasm Assembly Emission] ──► [180-Byte Bare-Metal Binary] │
│ │
│ • Self-contained toolchain with zero runtime dependencies. │
│ • Executes anywhere, compiles in microseconds, leaves zero operational footprint.│
└───────────────────────────────────────────────────────────────────────────────────┘
1. Field Reliability vs. Heavy Infrastructure
Traditional compiler architectures often assume an infinite logistical tail:
- Background daemons continuously running in memory.
- Gigabytes of backend frameworks (like giant LLVM installation footprints).
- Multi-megabyte runtime libraries and dynamic linker dependencies.
AzLang rejects this assumption.
AzLang is designed as a self-contained, field-deployable compiler:
- No background daemons: Compiles directly in one shot.
- Direct AST Lowering: AST nodes lower straight into readable fasm assembly without requiring gigabytes of compiler caches.
- Microsecond compilation: The compiler executable can be dropped onto an environment, parse code, validate semantics, emit assembly, and link a binary in milliseconds.
2. Kinetic Thrust: Direct Execution Paths
Rather than performing multi-pass combinatorial saturations that bloat compile times, AzLang focuses on kinetic thrust:
- Short, deterministic execution paths.
- Lean native assembly generated directly for target architectures.
- High thrust-to-weight ratio in generated code: no dead code bloat, no virtual dispatch tables unless explicitly constructed.
| Metric | AzLang Engineering Model | Heavy Industrial Toolchains |
|---|---|---|
| Compilation Latency | Microseconds to milliseconds | Seconds to minutes |
| Output Binary Size | Hello world: 180 bytes; ~2 KB for multi-module programs | 5 MB – 50 MB |
| Runtime Dependencies | None (Direct Kernel Syscalls) | libc, libm, libpthread, dynamic runtimes |
| Hardware Targets | Bare metal, microcontrollers, embedded, microservices | Cloud servers, heavy multi-core desktops |
3. Developer Ergonomics: The Helmet Sight
Soviet fighter aircraft pioneered Helmet-Mounted Cueing Systems (such as the Shchel-3UM) paired with clean, uncluttered analog cockpits. The pilot simply looks at a target and engages; the instruments stay out of the way.
AzLang adopts this philosophy for Developer Experience (DX):
- Readable indentation-based syntax akin to Python.
- Clear explicit boundary typing: Types are inferred automatically where obvious, and explicitly declared at structural boundaries (
enum,object, parameter signatures). - The language frontend stays clear and readable while the backend quietly outputs a lethal, high-speed native binary.
Zero-VM & Absence of Moving Parts
The most resilient system is one without excess complexity. Many modern programming runtimes inject heavy layers between application code and silicon:
- Virtual Machines (VM) with dynamic bytecode interpreters.
- Stop-the-world Garbage Collectors (GC) managing heap pages in the background.
- Complex C-runtime Initialization (
crt0.o,crt1.o,libc) running pre-main hooks. - Exception Unwinding Tables (
.eh_frame) introducing hidden branches and stack unwinding machinery.
How AzLang Achieves Safety Through Absence
AzLang eliminates every single one of these layers:
1. Direct Bare-Metal Entry (_start)
AzLang executables do not need main() wrapped in standard C-runtime setup. They target _start directly. The operating system kernel spawns the process, pushes initial stack frames (arguments, environment pointers), and transfers instruction control directly to AzLang code.
2. Zero Heap Leaks by Design
With direct register allocation and stack management, AzLang does not rely on opaque runtime memory arenas. When a program exits, it issues a direct kernel exit syscall (sys_exit, 60 on Linux x86_64).
3. Predictable State Invariants
Because there are no background scheduler threads, garbage collector pauses, or hidden asynchronous thread pools, program execution is:
- 100% Deterministic: Timing jitter is near zero.
- Traceable: Assembly instructions correspond directly to written operations.
- Inspectable: Debugging with tools like
gdb,objdump, orstracereveals pure syscalls and predictable stack frames.
[AzLang Application]
│
▼ (direct syscall: rax=1 for write, rax=60 for exit)
[Linux Kernel Ring 0]
Installation
AzLang ships as a single compiler binary. There is no runtime to install, no VM, and no LLVM-sized toolchain — the only external tool the compiler invokes is fasm.
Building from Source
cargo build --release
This generates the azcli binary executable.
Installing fasm
AzLang emits one .asm file per build and hands it to fasm, which assembles and links it into a standalone ELF executable in a single pass.
# Arch Linux
sudo pacman -S fasm
# Debian / Ubuntu
sudo apt install fasm
For other platforms, download fasm from https://flatassembler.net/ and put it on your PATH.
Next Steps
Continue to the Hello World Walkthrough to compile your first native binary.
Hello World Walkthrough
Here is a step-by-step walkthrough of writing and compiling your first native AzLang program using the real SDK syntax.
1. Writing main.az
Create a file named main.az:
enum FD
Stdin
Stdout
Stderr
@link("./sdk/src/write.s")
op write(FD fd, const str val, const int size): void
@link("./sdk/src/exit.s")
op exit(const int val): void
write(Stdout, "Hello World from AzLang!\n", 25)
exit(0)
Deconstructing the Code:
enum FD: Defines standard file descriptors (Stdin=0,Stdout=1,Stderr=2). Enum variants are inlined as immediates — no lookup table exists at runtime.@link(...): Points at a fasm assembly source containing a syscall stub that performs a direct Linuxsyscallinstruction. The source is included straight into the generated assembly — there is nothing to pre-compile.op write(...): Declares a callable operation function signature and parameter types.write(...)&exit(...): Calls the operations natively without libc overhead. The string length25accounts for the\nescape, which is resolved to a single newline byte at emission time.
2. Compiling with AzCLI
Compile main.az using azcli:
azcli build main.az
The AzLang pipeline will:
- Parse
main.azinto an AST. - Validate symbols and types.
- Emit a single assembly file (
main.asm) containing the program code, its string data, andincludedirectives forwrite.sandexit.s. - Invoke
fasm, which assembles and links that file directly into the standalone binarymainin one pass.
The only external tool required is fasm. There is no
qbe, noas, noldand no object files.
Run the resulting executable:
./main
# Output:
# Hello World from AzLang!
Check the binary size:
ls -l main
# 180 bytes
A complete, functional ELF executable in 180 bytes!
Variables & Mutability
AzLang enforces explicit distinction between immutable constants and mutable variables.
1. Constants (const)
By default, data should remain immutable. Use the const keyword to declare constants:
const int max_retries = 5
const str host = "127.0.0.1"
const float pi = 3.14159
Once defined, attempting to reassign a const identifier will produce a compile-time semantic error during the validation phase.
2. Mutable Variables (var)
When state needs to change over time, declare the variable using var:
var int counter = 0
counter = counter + 1
var str status = "pending"
status = "ready"
3. Type Inference & Annotations
AzLang supports type inference for basic expressions, while allowing explicit type annotations for maximum clarity:
// Explicit type annotation
const int port = 8080
// Mutable variable with type
var int connections = 0
connections = 1
For custom structures, enums, and module interfaces, explicit types are required at structural boundaries.
Data Types
AzLang provides a focused set of primitive and composite types that map directly to hardware registers and low-level data layouts.
1. Numeric Types
| Type | Description | Machine Mapping |
|---|---|---|
int | Standard signed integer | 32-bit / 64-bit machine word |
natural | Unsigned non-negative integer | Unsigned machine word |
bigint | Large 64-bit integer | 64-bit register |
tinyint | Small 8-bit / 16-bit integer | Byte / Half-word |
float | Floating-point number | Single / Double IEEE-754 |
Example:
const int count = 42
const bigint big_offset = 1000000000
const float ratio = 0.75
2. Textual & Character Types
char: A single character literal ('a').str: String representation. Depending on declaration, string literals are handled either as static immutable string slices (stored in data sections) or dynamic strings:
const str greeting = "Hello, world!"
const char initial = 'A'
AzLang also supports template strings (string interpolation) with backticks:
const str name = "AzLang"
const str msg = `Welcome to ${name}`
3. Boolean & Unit Types
bool: Representstrueorfalse.void: Represents an empty or absent return value from an operation.any: Universal type placeholder for dynamic dispatch or heterogeneous buffers.
4. Compound Types
list<T>: Linear collection of elements of typeT.
const list<int> numbers = [1, 2, 3, 4]
- User-defined types (
enum,object,type).
Enums
Enums in AzLang provide a zero-cost, type-safe abstraction for representing discrete states, flags, and system descriptors (such as Linux file descriptors, open flags, or socket options).
1. Syntax
Enums are declared using the enum keyword followed by the enum type name and an indented list of variants:
enum FD
Stdin
Stdout
Stderr
enum FLAG
ReadOnly
Write
enum FMODE
NoCreate
Create
2. Zero-Cost Compile-Time Inlining & Memory Representation
In AzLang, enums do not produce runtime allocation overhead or stack indirection tables.
Byte-Level Direct Inlining (Zero Footprint)
During the semantic validation stage, enum variants are registered directly as sequential numeric constants starting from 0:
Stdin -> 0Stdout -> 1Stderr -> 2
During code generation, any reference to an enum variant is directly inlined at compile-time as an immediate byte / literal value directly into the instruction stream or call site:
; Emitted assembly
; Notice that no load from memory or lookup table is generated.
; The variant is inlined directly as an immediate argument:
mov rax, 1
push rax
lea rax, [main_str0]
push rax
mov rax, 27
push rax
pop rdx
pop rsi
pop rdi
call write
Key Architectural Benefits:
- Zero Stack Allocation: No temporary register operations needed at runtime.
- Byte-Level Memory Density: Directly fits the exact ABI byte/word requirement of native syscalls with zero runtime indirection.
- Optimized Instruction Stream: Machine code directly emits immediate constants, minimizing executable binary size and instruction cache misses.
3. Usage with Operations & Native Syscalls
Enums are first-class types during semantic validation. They enforce strict compile-time type safety while passing as zero-cost inlined numbers to ABI operations:
enum FD
Stdin
Stdout
Stderr
@link("./sdk/src/write.s")
op write(FD fd, const str val, const int size): void
@link("./sdk/src/exit.s")
op exit(const int val): void
# Stdout is validated as FD type at compile-time,
# and directly inlined as literal 1 in the emitted binary
write(Stdout, "Writing to standard output...\n", 30)
exit(0)
Operations & Expressions
AzLang supports standard binary and unary operations with strict type checks enforced during compiler validation.
1. Arithmetic Operators
AzLang supports the standard arithmetic operations:
| Operator | Meaning | Example |
|---|---|---|
+ | Addition | a + b |
- | Subtraction | a - b |
* | Multiplication | a * b |
/ | Division | a / b |
% | Modulo | a % b |
Example:
const int a = 10
const int b = 3
const int sum = a + b
const int rem = a % b
2. Comparison Operators
Comparisons evaluate to a bool (true or false):
| Operator | Description |
|---|---|
== | Equal |
!= | Not equal |
> | Greater than |
>= | Greater than or equal |
< | Less than |
<= | Less than or equal |
Example:
const bool is_equal = (a == b)
const bool is_positive = (a > 0)
3. Logical Operators
AzLang provides natural keywords as well as standard symbol alternatives:
and/&&: Logical ANDor/\|\|: Logical OR!: Logical NOT
if a > 0 and b > 0
// block
Control Flow
AzLang utilizes significant whitespace and indentation (4 spaces per level) to organize execution blocks cleanly, avoiding noisy curly braces or verbose block delimiters.
1. Conditional Branching (if, elif, else)
Conditional statements evaluate boolean expressions to branch execution paths:
const int value = 42
if value == 0
write(Stdout, "Value is zero\n", 14)
elif value > 0
write(Stdout, "Value is positive\n", 18)
else
write(Stdout, "Value is negative\n", 18)
2. While Loops (while)
The while loop continuously executes an indented statement block as long as the condition remains true:
var int i = 0
while i < 10
i = i + 1
3. Infinite Loops (loop)
For continuous polling, kernel event pumps, or server request loops, use the bare loop construct:
loop
// execution body
if should_stop
break
4. Iteration (for .. in)
AzLang supports iterating through lists and collections:
const list<int> items = [10, 20, 30]
for items in item
// use item
5. Loop Control Statements
break: Terminate the loop immediately.continue: Skip the rest of the current iteration and proceed to the next cycle.
Operations & Functions (op)
In AzLang’s real SDK syntax, callable procedures and functions are declared using the op keyword. This aligns with AzLang’s low-level systems nature: procedures are atomic machine operations.
1. Declaring Internal Operations
An operation defines parameters, parameter types, a return type, and an indented block:
op add(const int a, const int b): int
return a + b
op multiply(var int x, const int factor): int
return x * factor
Mutability in Parameters
const <Type> <name>: Value parameter passed immutably.var <Type> <name>: Parameter treated as a mutable pointer reference.
2. Returning Void
When an operation does not yield a value (e.g. system exit or logging), its return type is specified as void:
op log_message(const str msg, const int len): void
write(Stdout, msg, len)
3. External Operations (@link + op)
To declare an interface to an external assembly source, place the @link directive above the op signature:
@link("./sdk/src/write.s")
op write(FD fd, const str val, const int size): void
@link("./sdk/src/exit.s")
op exit(const int val): void
@link("./sdk/src/fopen.s")
op fopen(const str val, FLAG flag, FMODE mode): File
When AzLang compiles this file, it registers the external function signature in its symbol table and, for every operation that is actually called, emits an include directive pulling the assembly source into the generated .asm — fasm then resolves the symbol statically in the same pass.
Modules & Imports
AzLang organizes codebases into self-contained modules imported using the import statement.
1. Importing Modules
To import definitions from another .az file:
import lib
write(Stdout, "Hello from imported module\n", 27)
In the AzLang SDK, sample.az imports lib.az:
// sample.az
import lib
write(Stdout, "Hello World", 11)
Where lib.az contains common type definitions, enums (FD, FLAG, FMODE), and external system call links:
// lib.az
enum FD
Stdin
Stdout
Stderr
@link("./sdk/src/exit.s")
op exit(const int val): void
@link("./sdk/src/write.s")
op write(FD fd, const str val, const int size): void
2. Compilation Model for Modules
When an import directive is encountered:
- The parser resolves the target file in the module search path.
- The imported module AST is parsed and analyzed.
- Symbol tables are merged or qualified, ensuring every
@linksource needed by the combined program is included exactly once in the emitted assembly.
Direct ABI Linking (@link)
One of AzLang’s most powerful capabilities is seamless, zero-overhead interoperability with native assembly code — no C runtime, no FFI wrappers, no dynamic loading.
1. The @link Directive
To call native code, point @link at a fasm assembly source and declare the operation’s signature:
@link("<path-to-fasm-source>")
op <function_name>(<parameters>): <return_type>
Example:
@link("./sdk/src/write.s")
op write(FD fd, const str val, const int size): void
@link("./sdk/src/exit.s")
op exit(const int val): void
2. Compiler Pipeline Integration
When the AzLang compiler encounters an @link directive:
- Parser: The AST node
Statement::ExternalFunctionDefrecords:name: Target symbol name (e.g.write).library: Path to the assembly source (e.g../sdk/src/write.s).params&return_typ: Checked against call sites.
- Validator: Registers
writeas a valid function and adds("write", "./sdk/src/write.s")to the compilation’slink_filesregistry. - Transpiler: When
writeis actually called, the compiler canonicalizes the path and emits it into the generated assembly:
include "/abs/path/to/sdk/src/write.s"
Sources of operations that are never invoked are skipped, and duplicate paths are included only once — unused stubs never reach the binary.
4. fasm: The included source and the generated code live in the same translation unit, so call write resolves statically at assembly time.
No dynamic library lookups at runtime, no dlopen overhead: the code is assembled directly into the binary image in a single fasm main.asm main pass.
Kernel Syscalls & Bare-Metal Stubs
In the AzLang architecture, standard I/O does not rely on the heavy GNU C Library (glibc or musl). Instead, core operations are mapped directly to Linux kernel system calls using lean assembly stubs.
1. System Call Assembly Implementations
The AzLang SDK provides plain fasm assembly sources for Linux x86_64 (fasm defaults to Intel syntax). These files are pulled in by @link via include — they are never assembled on their own.
write.s — Direct sys_write (Syscall 1)
write:
mov rax, 1 ; sys_write
syscall
ret
On x86_64 Linux ABI:
rdi: File descriptor (FD fd)rsi: Buffer pointer (const str val)rdx: Buffer byte count (const int size)rax: Syscall number (1forsys_write)
exit.s — Direct sys_exit (Syscall 60)
exit:
mov rax, 60 ; sys_exit
syscall
fopen.s — Direct sys_open (Syscall 2)
fopen:
mov rax, 2 ; sys_open
syscall
ret
2. Advantages of Direct Syscalls
- Zero Startup Penalty: No dynamic symbol relocations or runtime linker (
ld-linux.so) overhead. - Microscopic Footprint: Omits megabytes of standard library code that standard C programs pull in.
- Security & Attack Surface Reduction: Eliminates vulnerabilities inside complex libc string/format-string/locale handlers.
Standard SDK Library
The official AzLang SDK resides in the sdk/ directory (tracked as a git submodule). It acts as the reference standard library implementation demonstrating how systems programming is conducted in pure AzLang.
1. Structure of sdk/
sdk/
├── src/
│ ├── lib.az # Common types, enums, and @link declarations
│ ├── write.s # Linux sys_write assembly stub (fasm syntax)
│ ├── exit.s # Linux sys_exit assembly stub (fasm syntax)
│ └── fopen.s # Linux sys_open assembly stub (fasm syntax)
└── README.md
There is no build step: the .s files are fasm assembly sources referenced by @link and included directly into the compiler’s generated assembly.
2. Standard Types in lib.az
enum FD
Stdin
Stdout
Stderr
enum FLAG
ReadOnly
Write
enum FMODE
NoCreate
Create
@link("./sdk/src/exit.s")
op exit(const int val): void
@link("./sdk/src/write.s")
op write(FD fd, const str val, const int size): void
@link("./sdk/src/fopen.s")
op fopen(const str val, FLAG flag, FMODE mode): File
3. Sample Application
// hello_world.az
import lib
write(Stdout, "Hello World\n", 12)
Build it with a single command:
azcli build hello_world.az
./hello_world
Pipeline: Tokenizer to AST
AzLang’s compiler frontend transforms raw human-readable source code into a strongly-typed Abstract Syntax Tree (AST).
1. Tokenizer
The tokenizer transforms raw source text into a stream of spanned tokens:
- Indentation Tracking: Maintains an indentation stack to generate synthetic indent and dedent blocks (based on 4 spaces), giving AzLang its clean, readable syntax.
- String Templates: Handles template interpolation (
`text ${val}`) cleanly without dynamic runtime parsing. - Accurate Diagnostics: Tracks line and character offsets for precise compile-time error reporting.
2. Parser
The parser consumes tokens and builds a strongly-typed Abstract Syntax Tree (AST):
- Statements:
- Variable declarations (
const/var) - Operations and procedures (
op) - External system bindings (
@link) - Enumerations (
enum) - Conditional branching blocks (
if,elif,else) - Loops (
while,for,loop)
- Variable declarations (
- Expressions:
- Binary operations (
+,-,*,/), comparisons, identifiers, literals, function calls, and template expressions.
- Binary operations (
Semantic Validation & Symbol Resolution
Before any code generation takes place, AzLang programs pass through semantic validation.
1. Type and Symbol Verification
During semantic validation, the compiler analyzes program declarations to verify:
- Type Safety: Variable assignments, arithmetic expressions, and function arguments match expected types.
- Scope Management: Variables, constants, and functions are validated within their lexical scopes.
- Link Registry: External function declarations (
@link) are recorded as(operation, source path)pairs and prepared for assembly emission. - Unused & Mutation Tracking: Identifies immutable violations and unused bindings at compile-time.
2. Compile-Time Constant & Enum Resolution
AzLang resolves static constants and enumerations during validation:
- Enum Inlining: Enum variants are assigned zero-based sequential numbers and stored directly in the compiler’s constant table.
- Zero Runtime Memory: Any reference to an enum variant is converted directly into an immediate value before code generation. No lookup tables, dynamic allocations, or wrapper structures exist at runtime.
fasm Assembly Emission
AzLang compiles code by emitting a single, human-readable fasm (flat assembler) assembly file, which fasm turns directly into a native ELF executable in one pass.
1. Why fasm?
fasm was chosen because it aligns with AzLang’s minimalist engineering doctrine:
- One Pass, One Binary: fasm assembles and links in a single step — there is no separate
as, nold, no object files. - Small Footprint: the entire fasm distribution is a single binary of well under 1 MB.
- Readable Output: the emitted
.asmis clean, commented-friendly x86_64 assembly you can inspect directly.
2. Sample Assembly Emission
Here is the exact assembly generated for the Hello World program (paths abbreviated; the compiler canonicalizes them to absolute paths):
format ELF64 executable
entry _start
segment readable executable
include "./sdk/src/write.s"
include "./sdk/src/exit.s"
_start:
push rbp
mov rbp, rsp
sub rsp, 8
mov rax, 1
push rax
lea rax, [main_str0]
push rax
mov rax, 25
push rax
pop rdx
pop rsi
pop rdi
call write
mov rax, 0
push rax
pop rdi
call exit
xor edi, edi
mov eax, 60
syscall
main_str0 db "Hello World from AzLang!",10,0
AzLang generates this directly from the validated AST:
- Function calls lower to ordinary
call <symbol>instructions following the System V AMD64 ABI (register arguments, 16-byte stack alignment). - String literals become
dbdata directives (escape sequences such as\nare resolved to bytes at emission time). @link(...)sources that are actually invoked are pulled in withinclude, so unused SDK stubs never reach the binary.- Programs end with a direct
sys_exit(rax = 60) — no C runtime, noretto nowhere.
Single-Pass Assembly & Binary Layout
The final stage of the AzLang compiler pipeline turns the emitted assembly into a finished, standalone bare-metal executable — in one invocation, with no linker.
1. Pipeline Execution Flow
AzLang produces machine code through a deterministic two-step lowering pipeline:
- Assembly Emission: the validated AST is lowered into one
.asmfile — header,includedirectives for every invoked@linksource, the program’s code, and its string data. - Single-Pass Assembly:
fasmassembles that file directly into the final ELF executable. Assembly and linking happen in the same pass, so no intermediate object files ever exist.
fasm main.asm main
Because @link targets are fasm assembly sources (not pre-built .o files), there is nothing to pre-compile: the symbols write, exit, etc. are defined in the same translation unit and resolved statically at assembly time.
2. Resulting Binary
AzLang emits format ELF64 executable with entry _start and a single readable executable segment (a 120-byte program header). Because the program targets the system entry point _start and inlines its syscall stubs, no C runtime or dynamic linker is involved:
- No dynamic interpreter (
/lib64/ld-linux-x86-64.so.2is not required) - No section headers, no relocations — a minimal static image
- Tiny footprint: the Hello World program measures 180 bytes; a comprehensive 60-line multi-module program stays around 2 KB
- Instantaneous startup: execution begins at
_startwith direct syscalls
$ file main
main: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, no section header
$ ./main
Hello World from AzLang!