Skip to content

cnegative

A hackable systems language built for explicit low-level control and clear semantics.

cnegative is meant for people who want direct control, visible rules, and a compiler they can inspect without inheriting the full historical weight of C on day one.

It keeps behavior explicit, makes rules visible, and avoids hidden surprises where possible.

current status

This is v0.5.2. The language and compiler are under active development, but the current surface is already large enough for real small tools and learning projects.

Who this is for

cnegative is a good fit if you want:

  • a beginner path into systems programming
  • explicit control over values, memory, and errors
  • a language you can read end to end without a huge standard library
  • a compiler you can inspect and learn from

It is not trying to be:

  • a giant batteries-included platform
  • a high-level scripting language
  • a polished replacement for C, C++, Rust, or Zig

The mental model

Think of cnegative like this:

  1. Values have explicit types.
  2. Conditions must be real bool values.
  3. Non-void functions return explicitly.
  4. Public API is marked explicitly.
  5. Heap-backed values that you own should be freed explicitly.

If you keep those five ideas in mind, most of the language will feel straightforward.

What to learn first

If you are new, do not start with the compiler pages.

Start in this order:

  1. Quick Start
  2. Functions & Variables
  3. Types & Control Flow
  4. Memory & Results
  5. Strings & Ownership
  6. Standard Library Overview

After that, move into modules, structs, arrays, and compiler internals.

What to ignore for now

If you are just learning the language, you can safely ignore these on your first pass:

  • LLVM IR
  • typed IR
  • std.term low-level terminal control, timed key/mouse/resize/paste events, capability queries, styles, and diff rendering
  • std.bytes, std.lines, and std.text for growable byte, line, and text storage on top of core slices
  • std.x11
  • TCP/UDP helpers in std.net
  • release/build pipeline details

Those are useful later. They are not needed to write your first small program.

A first example

cneg
fn:int main() {
    let a:int = 2;
    let b:int = 3;
    let sum:int = a + b;
    println(sum);
    return 0;
}

What is happening here:

  • fn:int main() says main returns an int
  • let creates named values
  • types are written explicitly
  • println(sum); prints the value and appends a newline
  • return 0; ends the program successfully

Core rules at a glance

  • Semicolons are required for simple statements, import lines, and struct fields.
  • Conditions must be bool.
  • Non-void functions must return explicitly on every path.
  • Visibility is explicit: pfn, pstruct, and pconst are the public forms.
  • byte is just an alias for u8.

common beginner mistake

if x {} is rejected when x is an int. Write a real boolean expression like if x > 0 {}.

What exists today

  • fn, pfn, struct, pstruct, const, and pconst
  • int, u8, bool, str, void, ptr T, result T, and slice T
  • byte as a readable alias for u8
  • source-level null for pointer values
  • if, while, loop, range for, narrow if expressions, defer, and try
  • arrays, structs, indexing, and field access
  • imports, qualified calls, qualified types, and qualified public constants
  • alloc, addr, deref, free, ok, err, print, println, input, str_copy, and str_concat
  • stdlib modules for math, bytes, IPC, lines, strings, parsing, files, IO, terminal control, env, paths, time, networking, process helpers, and the experimental Linux-only std.x11
  • main may return int, u8, result int, result u8, or void
  • typed IR, LLVM IR, object generation, and linked binaries

Platform support

FeatureLinux x86_64macOS arm64Windows x86_64
Compiler (C)YESYESYES
LLVM pathYESYESYES
Lexer hot-path ASMYESYESfallback C
Prebuilt releaseYESYESYES

cnegative docs track the current v0.5.2 compiler surface.