Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions COMPILER_CLEANUP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Compiler Cleanup

This pass is complete.

The goal was to remove the worst architectural accidents in `capc/` without
turning the compiler into a rewrite project.

## What Landed

- stable expression identity and an explicit desugar pass are already in place
- lowering now has real lexical scopes instead of fake scope helpers
- parser, checker, monomorphization support, and codegen helpers are split by
concern instead of living in a few giant files
- multi-file diagnostics now attach the correct source file for imported-module
parse and type-check failures, and the driver has the plumbing needed for
codegen diagnostics to do the same
- runtime-backed stdlib functions now come from one shared runtime-binding
registry instead of a stringly boolean table in one place and a separate
signature registry in another
- the immediate MIR question is settled for now: do not add a full MIR/CFG
layer yet; if codegen needs another normalization step, start with a smaller
control-flow-normalized HIR pass first

## Final Status

- [x] Stable expression identity and explicit desugaring
- [x] Real lowering scopes
- [x] Match / `try` control-flow cleanup
- [x] `typeck` split by concern
- [x] Parser split by syntactic domain
- [x] Monomorphization helper split
- [x] Codegen helper split
- [x] Multi-file diagnostics for imported-module compiler errors
- [x] Shared runtime interface registry
- [x] Decision on MIR vs narrower normalization

## Result

The compiler is still direct, but the worst remaining problems are now
deliberate tradeoffs instead of accidental ones:

- diagnostics are no longer effectively entry-file-only
- runtime-backed stdlib functions have one source of truth
- the next control-flow step is bounded and explicit instead of “probably add
MIR someday”

## Verification

- `PATH="$HOME/.cargo/bin:$PATH" cargo test -p capc`
40 changes: 34 additions & 6 deletions CURRENT_STATUS.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,17 @@ repository. It is based on code and tests, not older design docs.

## Types and ownership

- Built-in types: i32, u32, u8, bool, unit, never.
- Built-in types: i32, i64, u32, u64, u8, bool, unit, never.
- `string` is a stdlib struct (a view over bytes), not a compiler builtin.
- Pointers (`*T`) and borrows (`&T`) are supported in the type system.
- Affine/linear ownership rules are enforced for non-copy values (including
capability and linear types).
- Integer literals type as i32; char literals are u8.
- Plain data is unrestricted by default.
- `opaque struct` and `capability struct` are the main move-tracked categories.
- Structs/enums become move-tracked by containment when they contain
move-tracked fields.
- Borrows are deliberately narrow: refs cannot be stored in structs/enums or
returned, and ref locals must be initialized from another local.
- Unsuffixed integer literals type as i32; suffixed integer literals currently
support `u8`, `i64`, and `u64`. Char literals are `u8`.

## Standard library and runtime

Expand All @@ -42,6 +47,31 @@ repository. It is based on code and tests, not older design docs.
- Buffer/Alloc malloc/free/casts.
- Math wrap helpers and byte whitespace checks.

## Current capability algebra

- Reusable use operations borrow the capability/resource where possible:
- `ReadFS.read_to_string/read_bytes/list_dir/exists`
- `Dir.read_to_string/read_bytes/list_dir/exists`
- `Stdin.read_to_string`
- `TcpConn.read_to_string/read/write`
- `TcpListener.accept`
- Attenuation operations still consume the stronger capability:
- `Filesystem.root_dir`
- `Dir.subdir`
- Child handles remain linear where appropriate:
- `FileRead`
- `TcpConn`
- On move-tracked capabilities, borrowed receivers can return fresh linear
child capabilities, but they cannot return reusable capabilities. This is
why `Dir.open_read` can borrow `Dir`, while attenuation like `Dir.subdir`
still consumes `self`.
- Deliberately copyable capabilities currently include:
- `RootCap`
- `Console`
- `Args`
- `Net`
- `TcpListener`

## ABI and codegen

- Codegen targets native code via Cranelift.
Expand All @@ -51,8 +81,6 @@ repository. It is based on code and tests, not older design docs.

## Known limitations and gaps

- i64 is parsed but rejected by the current backend; only 32-bit integer types
are supported.
- Inline-by-value struct returns are not implemented (sret only).
- Vec element types are restricted to u8, i32, string, or type parameters.
- Variable shadowing is not currently modeled in lowering.
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

104 changes: 0 additions & 104 deletions FIXME-GENERICS.md

This file was deleted.

43 changes: 43 additions & 0 deletions FUTURE_COMPILER_WORK.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Future Compiler Work

These items are intentionally deferred. They are real architectural projects,
not cleanup chores.

## High-Risk Work

- Add a real MIR / CFG layer.
Current decision: do not do this yet. If codegen needs another simplification
step, first try a smaller control-flow-normalized HIR pass that lowers
`match`, `try`, `defer`, and loop exits into a flatter form without adding a
whole new compiler IR family.

- Change the typecheck / lowering contract.
Current decision: do not rewrite this boundary yet. The compiler is stable
enough now that the next version of this work should only happen if a
normalized-HIR pass or incremental compilation effort makes the current
side-table contract too expensive to keep.

- Replace the current build / link pipeline.
Current decision: do not tackle this in the cleanup pass. The compiler still
shells out through `cargo` and `rustc` and writes a small Rust stub at link
time. That is architecturally awkward, but it is isolated and working. It
should become its own project if cross-compilation, packaging, reproducible
builds, or compile-time performance make it worth paying down.

## Trigger Conditions

Re-open the work above only if one of these becomes true:

- codegen complexity starts growing faster than localized helper extraction can
control
- diagnostics or optimization work need an explicit CFG-level representation
- incremental compilation or separate compilation becomes a real goal
- the current shell-driven build pipeline becomes a meaningful product problem

## Order

If this work is reopened, the preferred order is:

1. Try control-flow-normalized HIR before full MIR.
2. Revisit the typecheck / lowering contract only after that.
3. Tackle the build / link pipeline as a separate delivery project.
36 changes: 0 additions & 36 deletions PLAN.md

This file was deleted.

Loading
Loading