Skip to content

Language reference

xcc is a small, statically-typed language with C-family syntax, ObjC-like classes and protocols, and a focus on producing dense code on machines that cannot afford waste. Every page below carries a worked example that compiles and runs — the programs live in the repository and are built by a script, so a code block here cannot drift from what the compiler actually does.

If you’re reading top-to-bottom, this is the recommended order:

  1. Lexical structure — comments, identifiers, numeric and string literals, reserved words.
  2. Preprocessor#include / #import, #define, conditional compilation.
  3. Types — the fixed-width scalars including i64/u64, structs, enums, pointers, arrays, inference, casting.
  4. Operators — the full precedence table, including the rotate (<: :>) and byte-extract (< > >> >>>) operators.
  5. Statements & control flow — declaration modifiers, if, switch, the two for loops, while, defer, :unroll.
  6. Functions — declarations, multiple return values, varargs, overloading, function annotations.
  7. Classes — heap and stack allocation, methods, properties, init / dealloc.
  8. Inheritance & protocols — single inheritance, virtual dispatch, downcasts ((Dog*)a and the failable (Dog* ?)a), protocols and optional methods.
  9. Bound methods & callbacks^, target/action, and why a callback needs no context pointer.
  10. Errors — the throws effect, throw, typed and untyped catch arms, the Error protocol.
  11. Heap, ARC & weak refsnew / delete, automatic reference counting, weak: references, manual -farc=off mode.
  12. Collections & stringsArray<T>, Map<V>, Set<T>, String, and how element types are checked then erased.
  13. ThreadingThread, Mutex, Atomic, Pool, and the automatic atomic-refcount decision. Native targets only.
  14. Modules & shared libraries--emit-lib, #import <Lib>, what crosses a library boundary, and extern globals.
  15. Inline assemblyasm { … } blocks, byte-extract operators, reaching xcc variables, the clobbers annotation.

For day-to-day reference, jump straight to the page you need from the sidebar.

Worth knowing before you write the first program:

  • The pointer sigil binds to the type. u8* a, b; declares two pointers, not a pointer and an integer.
  • No promotion to int. Same-width arithmetic stays at that width, so u8 + u8 wraps at 8 bits. Only genuinely mixed-width operands widen.
  • printf widths are explicit. %d is 16-bit, %ld is 32-bit and %lld is 64-bit; all three are signed, so use the %u family (%u, %lu, %llu) for unsigned. The compiler checks the format string against the argument types — and widens a conversion whose argument is statically wider, so %d on an i64 prints the whole value rather than truncating.
  • Source files are .xc
  • Compiler flags, optimisation levels, memory-model selection live in Compiler usage — they shape the output but are not part of the language. Start with Install.
  • Standard library classes (Stdio, Math, Heap, Assert, …) live in the Standard library reference.
  • Memory-model internals (the two bank windows, the hardware stack) are summarised where they affect semantics; the full map is in Compiler usage → Memory models.