C, But Friendlier
- Functions with return types
- Struct methods and extensions
- Top-level constants and globals
- Named initializers
Experimental language prototype
CX is an experiment in building a friendlier C-like language and toolchain that transpiles to readable C. It works for examples and small programs, but the language and standard library are still changing.
Command line
cx new hello-cx
cd hello-cx
cx run
cx test
cx test --std Transpiles to C
CX keeps the language close to C and lowers features into ordinary C shapes: structs, functions, enums, tagged records, function pointers, and explicit allocator calls.
fn add(a: int, b: int) -> int {
let total: int = a + b;
return total;
} int add(int a, int b)
{
int total = a + b;
return total;
} Language tour
Examples
import c.stdio;
fn main() -> int {
let values = Vec<int>.create();
values.add(10);
values.add(20);
values.add(30);
foreach value in values {
printf("Value %d\n", value);
}
values.free();
return 0;
} union Value {
Number: int;
Position: Point;
}
fn score(value: Value*) -> int {
match value {
Number: n => return n;
Position: p => return p.x + p.y;
_ => return 0;
}
} test "stack length" {
let stack = Stack<int>.create();
stack.push(10);
expect(stack.length == 1);
stack.free();
} Standard library
Vec<T> can use the default C allocator or a caller-provided
allocator, so the same container works with heap memory, fixed buffers,
arenas, and future allocator shapes.
import std.core;
fn main() -> int {
let buffer: u8[256];
let fixed: FixedBufferAllocator =
FixedBufferAllocator.from_buffer(&buffer[0], 256);
let allocator: Allocator = fixed;
let values: Vec<int> = Vec<int>.with_allocator(&allocator, 4);
values.add(10);
values.add(20);
values.add(30);
let total: int = 0;
foreach value in values {
total += value;
}
values.free();
return 0;
} let values = Vec<int>.create();
values.add(10);
values.add(20);
values.free(); let text = StringView.from_cstr(" hi ");
let trimmed = text.trim();
let ok = trimmed.equals_cstr("hi"); let builder = StringBuilder.create();
builder.append_cstr("hello");
builder.append_char(' ');
builder.append_cstr("cx");
builder.free(); let routes = HashMap<StringView, int>.create();
routes.put(StringView.from_cstr("/health"), 200);
let status = routes.get(StringView.from_cstr("/health"));
routes.free(); let seen = HashSet<int>.create();
seen.add(10);
let ok = seen.contains(10);
seen.free(); let value = StringView.from_cstr("123").parse_int();
if (value.has_value) {
return value.value;
} let file = File.open("data.txt");
if (file.is_ok) {
file.value.free();
} let file = File.create("notes.txt");
file.write_cstr("hello cx");
file.free(); let path = StringView.from_cstr("src/main.cx");
let name = Path.file_name(path);
let ext = Path.extension(path); let bitmap = Bitmap.create(64, 64);
bitmap.clear(Color32 { r: 16, g: 16, b: 16, a: 255 });
bitmap.save("image.bmp");
bitmap.free(); let buffer: u8[256];
let fixed = FixedBufferAllocator.from_buffer(&buffer[0], 256);
let allocator: Allocator = fixed; let json = JsonWriter.create();
json.begin_object();
json.name("ok");
json.bool_value(true);
json.end_object();
json.free(); Current shape
CX is not a finished language yet. It is a working prototype for exploring better C ergonomics: native output, explicit memory, generics, tagged unions, interfaces, and a small standard library.