name: "mach-language" description: "Concise Mach language reference: syntax, types, conventions, and short examples for authoring valid Mach code."
Purpose
A compact, actionable summary to help agents and contributors write correct Mach code and use the compiler toolchain for fast validation.
Language basics
- Single-line comments only:
# comment - Keywords are summarized below; for full syntax details, see
doc/keywords.md. - One file = one module. Module path follows file path (e.g.,
src/driver/pipeline.mach→project.driver.pipeline).
Keywords (quick)
| keyword | meaning | common form |
|---|---|---|
use |
import another module (optionally under an alias) | use [alias:] project.module; |
pub |
export a top-level symbol from the current module | pub val x: i32 = 0; |
ext |
declare an external (FFI) binding | ext "C:printf" printf: fun(fmt: *u8, ...) i32; |
def |
define a type alias | def Age: u32; |
rec |
define a record (struct-like) type | rec Point { x: f32; y: f32; } |
uni |
define a tagged union (optionally generic) | uni Result[T] { ok: T; err: T; } |
val |
declare an initialized, immutable binding | val pi: f32 = 3.14; |
var |
declare a mutable binding (initializer optional) | var i: i32 = 0; |
fun |
declare a function or method | fun add(a: i32, b: i32) i32 { ret a + b; } |
ret |
return from a function (with an expression if required) | ret 0; |
if |
conditional branch | if (cond) { ... } |
or |
else / else-if branch for if |
or (cond) { ... } or { ... } |
for |
loop (conditional or infinite) | for (cond) { ... } / for { ... } |
cnt |
continue to next loop iteration | cnt; |
brk |
break out of the nearest loop | brk; |
fin |
deferred statement (runs when scope exits) | fin cleanup(); |
masm |
inline masm block (backend/target-specific) | masm { ... } |
Types & pointers
- Primitives:
u8u16u32u64i8i16i32i64f32f64ptrstr. - Builtin value:
nil(null pointer). - Pointers:
*T(mutable pointer),&T(read-only pointer). - Arrays:
[N]T. - Constructs:
rec { ... }(records),uni { ... }(tagged unions). - Address-of:
?x— when applied to avarit yields a*T; when applied to avalit yields an&T. Deref:@ptr. - Casting:
value::TargetTypeis a pure bit reinterpretation; sizes must match exactly (this does not perform numeric conversion). - No type inference; types must be explicit.
- Literal coercion only happens at declaration.
Expressions (common)
- Field access / module access:
obj.field - Indexing:
arr[i](arrays and pointer-like values) - Calls:
func(a, b)and methods via dot:obj.method() - Generic instantiation/calls:
Type[T]andfunc[T](...) - Composite literals:
Type { field: value, ... }andType[T] { ... } - Cast:
value::TargetType(bit reinterpret; same-size only) - Address-of / deref:
?expr,@expr
Control flow & methods
- Conditional and loops:
if (cond) { .. } or { .. },for (cond) { .. },for { .. }(infinite). - Deferred finalizers:
fin stmt;(deferred in scope). - Methods with receivers:
fun (this: *T) method() { ... }— method calls auto-convert between value and pointer receivers as needed. - Mach does NOT have tertiary (C-style) for loop syntax.
foris effectively equivalent towhilein C. - Mach does NOT have a
whilestatement.
Entry point convention
- Use for native executables:
use std.runtime;
$main.symbol = "main";
fun main(argc: i64, argv: &&u8) i64 {
ret 0;
}
Note the $main.symbol assignment to set the entry point symbol (defined as and required by the standard library runtime).
Minimal examples
- Simple
main:
use std.runtime;
$main.symbol = "main";
fun main(argc: i64, argv: &&u8) i64 {
ret 0;
}
- Pointer & method examples:
rec Counter { value: i32; }
fun (this: *Counter) inc() { this.value = this.value + 1; }
var n: i32 = 3;
val pn: *i32 = ?n;
val m: i32 = @pn;
Documentation
- Mach documentation follows a pattern as seen below:
# Summary and description of the function, method, record, etc.
# ---
# param: description of parameter
# param2: description of another parameter
# ret: description of return value
- The
---line separates the summary from parameter/return docs and is not required where not relevant (e.g no parameters). The same goes for the entirety of the parameter/return section. - In the above example,
paramandparam2are placeholder names; use the actual parameter names.retis NOT a placeholder; always useretfor return value documentation. - Attempt to keep parameter descriptions aligned for readability (as shown above with space-padding).
chat Comments (0)
Sign in to join the discussion and leave a comment.
Skill Details
GitHub Stars
76
GitHub Forks
1
Created
Jan 2026
Last Updated
4 months ago
tools
tools ide plugins
Related Skills
Build your own?
Join 12,000+ developers contributing to the Claude ecosystem.
No comments yet. Be the first to share your thoughts!