Zen C Documentation

repository·main·Indexed 26 days ago

https://github.com/zenc-lang/zenc

Zen C is a modern systems programming language that compiles to human-readable GNU C/C11, combining high-level ergonomics like type inference and pattern matching with low-level control and 100% C ABI compatibility. The documentation covers the zc CLI tool, the standard library (std), a built-in unit testing framework, and various output backends including C++, CUDA, and Objective-C. It also provides guidance on using the Actually Portable Executable (APE) build via cosmocc and configuring VS Code for debugging.

Tokens
24.1K
Snippets
86
Records
145
Agent score
82%

What's inside Zen C

  1. Overview of Zen C

    main
    Zen C is a modern systems programming language that compiles to human-readable GNU C/C11. It provides high-level features like type inference, pattern matching, generics, traits, async/await, and RAII-based manual memory management, while maintaining 100% C ABI compatibility.
  2. Zen C Project Structure and Code Style

    main

    Code Style

    • Follow the existing C style used in the codebase.
    • Use the provided .clang-format file to format your code.

    Project Structure

    • Parser: src/parser/ — Implementation of the recursive descent parser.
    • Codegen: src/codegen/ — Transpiler logic that converts Zen C to GNU C/C11.
    • Standard Library: std/ — Standard library modules written in Zen C.
  3. Zen C LSP Features

    main

    The Zen C Language Server provides the following editor features:

    • Diagnostics: Real-time syntax and type error reporting.
    • Go to Definition: Jump directly to the definitions of structures, functions, and variables.
    • Autocompletion: Context-aware suggestions for fields and methods.
    • Hover: Display type information and documentation when hovering over code elements.
  4. Install Zen C from source

    main

    To install the Zen C compiler (zc) from the source repository, clone the repository, clean previous builds, compile using make, and install to your system.

    Prerequisites:

    • A compatible build environment with make and a C compiler.

    Steps:

    1. Clone the repository.
    2. Navigate to the directory.
    3. Clean, build, and install.
    git clone https://github.com/zenc-lang/zenc.git
    cd zenc
    make clean # 移除旧的构建文件
    make
    sudo make install
  5. Build Actually Portable Executable (APE) with Zen C

    main

    You can compile Zen C into an Actually Portable Executable (APE) using Cosmopolitan Libc. This generates a single .com file that runs natively on Linux, macOS, Windows, FreeBSD, OpenBSD, and NetBSD across x86_64 and aarch64 architectures.

    Prerequisites: The cosmocc toolchain must be in your PATH.

    Build and Install:

    make ape
    sudo env "PATH=$PATH" make install-ape

    Outputs:

    • out/bin/zc.com: Portable Zen-C compiler with the standard library embedded.
    • out/bin/zc-boot.com: A self-contained bootstrap installer for new Zen-C projects.

    Usage:

    ./out/bin/zc.com build hello.zc -o hello
  6. Build and use the Portable Build (APE)

    main

    Zen C can be compiled as an Actually Portable Executable (APE) using the cosmocc toolchain. This produces a single .com binary that runs natively on Linux, macOS, Windows, FreeBSD, OpenBSD, and NetBSD across both x86_64 and aarch64 architectures.

    Prerequisites:

    • cosmocc toolchain must be in your PATH.

    Build and Install:

    make ape
    sudo env "PATH=$PATH" make install-ape

    Artifacts:

    • out/bin/zc.com: The portable compiler with the standard library embedded.
    • out/bin/zc-boot.com: A self-contained bootstrap installer.

    Usage:

    ./out/bin/zc.com build hello.zc -o hello
  7. Debug Zen C with VS Code

    main

    Zen C programs can be debugged using standard C debuggers like LLDB or GDB.

    For VS Code, install the official Zen C extension and use the C/C++ (Microsoft) or CodeLLDB extensions.

    To enable one-click debugging, create a .vscode directory in your project with the following configurations:

    // tasks.json (Build Task)
    {
        "label": "Zen C: Build Debug",
        "type": "shell",
        "command": "zc",
        "args": [ "${file}", "-g", "-o", "${fileDirname}/app", "-O0" ],
        "group": { "kind": "build", "isDefault": true }
    }
    
    // launch.json (Debugger Configuration)
    {
        "name": "Zen C: Debug (LLDB)",
        "type": "lldb",
        "request": "launch",
        "program": "${fileDirname}/app",
        "preLaunchTask": "Zen C: Build Debug"
    }
  8. Configure Zen C in Neovim using lspconfig

    main

    If you use nvim-lspconfig, you can register zc as a custom server. The following configuration uses lspconfig to define the command, filetypes, and root directory detection.

    local lspconfig = require('lspconfig')
    local configs = require('lspconfig.configs')
    
    if not configs.zenc then
      configs.zenc = {
        default_config = {
          cmd = { 'zc', 'lsp' },
          filetypes = { 'zenc', 'zc' },
          root_dir = lspconfig.util.root_pattern('.git', 'build.bat', 'Makefile'),
          settings = {},
        },
      }
    end
    
    lspconfig.zenc.setup {}
  9. Interoperate with C++ using --backend cpp

    main

    Use the --backend cpp (or --cpp) flag to generate C++ compatible code, allowing seamless integration with C++ libraries. This mode uses auto instead of __auto_type, uses function overloading instead of _Generic, and performs explicit casts for void*.

    To use C++ code within Zen C, include C++ headers and wrap the C++ code in a raw block.

    include <vector>
    include <iostream>
    
    raw {
        std::vector<int> make_vec(int a, int b) {
            return {a, b};
        }
    }
    
    fn main() {
        let v = make_vec(1, 2);
        raw { std::cout << "Size: " << v.size() << std::endl; }
    }
  10. Use Objective-C interoperability in Zen C

    main

    Compile to Objective-C (.m) using the --backend objc (or --objc) flag to utilize Objective-C frameworks like Cocoa/Foundation. Use include for headers and raw blocks for Objective-C syntax (e.g., @interface, [...]). Zen C string interpolation also works with Objective-C objects (id) by automatically calling debugDescription or description.

    //> macos: framework: Foundation
    //> linux: cflags: -fconstant-string-class=NSConstantString -D_NATIVE_OBJC_EXCEPTIONS
    //> linux: link: -lgnustep-base -lobjc
    
    include <Foundation/Foundation.h>
    
    fn main() {
        raw {
            NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
            NSLog(@"Hello from Objective-C!");
            [pool drain];
        }
        println "Zen C funktioniert ebenfalls!";
    }
  11. Use CUDA for GPU programming in Zen C

    main

    Zen C supports GPU programming by transpiling to CUDA C++ via the --backend cuda (or --cuda) flag. This requires the NVIDIA CUDA Toolkit. It provides a launch operator for calling kernels and a standard library std/cuda.zc for memory management and synchronization.

    import "std/cuda.zc"
    
    @global
    fn add_kernel(a: float*, b: float*, c: float*, n: int) {
        let i = thread_id();
        if i < n {
            c[i] = a[i] + b[i];
        }
    }
    
    fn main() {
        def N = 1024;
        let d_a = cuda_alloc<float>(N);
        let d_b = cuda_alloc<float>(N); 
        let d_c = cuda_alloc<float>(N);
        defer cuda_free(d_a);
        defer cuda_free(d_b);
        defer cuda_free(d_c);
    
        // ... init data ...
        
        launch add_kernel(d_a, d_b, d_c, N) with {
            grid: (N + 255) / 256,
            block: 256
        };
        
        cuda_sync();
    }