ajhahn.de
← Flash
Markdown 69 lines
# Chapter 11: Zig Interoperability

Flash is designed to compile side-by-side with Zig. It does not replace Zig entirely; instead, it coexists, allowing module-by-module porting of existing systems code.

---

## 1. The Coexistence Rule
Throughout the development of FlashOS, Flash and Zig files compile side-by-side:
* A Flash file lowers to a Zig file.
* This lowered Zig file can import existing hand-written Zig modules.
* Existing Zig files can import the lowered Flash module in turn, without knowing it was originally written in Flash.

---

## 2. Syntactic Lowering Comparison
To understand how the compiler lowers Flash code to Zig, examine the following side-by-side comparison.

### Flash Input:
```flash
use flibc

const BUF_LEN usize = 512

fn drain(fd i32) {
    var buf [BUF_LEN]u8 = undefined
    while true {
        n := flibc.sys.read(fd, &buf, buf.len)
        if n <= 0 {
            break
        }
        _ = flibc.sys.write_fd(1, &buf, #intCast(n))
    }
}
```

### Generated Zig Output:
```zig
const flibc = @import("flibc");

const BUF_LEN: usize = 512;

fn drain(fd: i32) void {
    var buf: [BUF_LEN]u8 = undefined;
    while (true) {
        const n = flibc.sys.read(fd, &buf, buf.len);
        if (n <= 0) {
            break;
        }
        _ = flibc.sys.write_fd(1, &buf, @intCast(n));
    }
}
```

---

## 3. Key Lowering Transformations
Notice the following changes made by the compiler during lowering:
1. **Type Suffixes:** In Flash, variables are typed as `var name type = value`. The compiler lowers this to Zig's `var name: type = value;`.
2. **Semicolons:** Semicolons are automatically restored in the output Zig code.
3. **Implicit Void:** Functions without a return type in Flash (like `fn drain`) are explicitly lowered to return `void` in Zig.
4. **Braces on Loops:** Loop conditions in Zig require parentheses (e.g., `while (true)`). The compiler inserts these automatically.
5. **Short-hand `:=`:** The short-hand `name := expr` lowers to constant declarations `const name = expr;` inside local scopes (always immutable).
6. **Intrinsic Sigil:** Flash spells compiler intrinsics with a `#` sigil (`#intCast`). These lower to Zig's `@`-prefixed builtins (`@intCast`); the semantics are identical, only the sigil changes.

---

## 4. Integrating with `build.zig`
To compile a Flash file in a Zig project, you first transpile it using `flashc` as part of your build pipeline (often using a `b.addRunArtifact` step or custom build command in `build.zig`), and then compile the resulting Zig file as a module or executable. This keeps the integration clean and standard.