Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
57fc54c
Add break and continue statements
Dec 31, 2025
a22c056
Fix nested match codegen panic
Dec 31, 2025
978f14b
Use break in sort example
Dec 31, 2025
d9e0aa3
Add for loop support with range syntax
Dec 31, 2025
a6fe98f
Add string comparison operators == and !=
Dec 31, 2025
9b746d3
Add index syntax [] and change generics to <>
Dec 31, 2025
aa09a93
check tests properly
Dec 31, 2025
7555204
Change default target name from capable
Jan 1, 2026
f64de33
Remove outdated plan file
Jan 1, 2026
4bd4f97
remove outdated progress file
Jan 1, 2026
529b9ed
move docs
Jan 1, 2026
4c6e29e
Simple ok+err handlers
Jan 1, 2026
f0b3345
Add Vec indexing syntax and fix for-loop range parsing
Jan 1, 2026
c167d11
Move Result<T, E> enum from compiler builtin to stdlib
Jan 1, 2026
2f28e94
[WIP] Move Result methods from compiler special-case to stdlib
Jan 1, 2026
993e805
Fix some stuff
Jan 1, 2026
7416ad8
Fix loop linearity, indexing constraints, and call conv
Jan 1, 2026
3f2aca3
Add docs and TODO list
Jan 1, 2026
fc93b87
Add never type and Vec<T> specializations
Jan 1, 2026
d925d5b
Add top-level defer statement
Jan 1, 2026
4763187
Make defer scope-based
Jan 1, 2026
a29d59b
Improve net listener and string helpers
Jan 1, 2026
c53e84d
Add if let statement sugar
Jan 1, 2026
15276b0
Add for {} infinite loop sugar
Jan 1, 2026
4ee669e
Add char literals and string helpers
Jan 1, 2026
48b63f0
stdlib: flesh out string/vec helpers
Jan 2, 2026
1df8699
codegen: lower struct returns via sret/result-out
Jan 2, 2026
29effac
docs: describe ABI lowering for struct returns
Jan 2, 2026
09a908c
Fix ABI lowering and reserved type test
Jan 2, 2026
72e9a9f
Make string userland and update ABI/runtime
Jan 2, 2026
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
39 changes: 39 additions & 0 deletions FIXME.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# FIXME

Commits on this branch (main..HEAD), in order:

- 57fc54c Add break and continue statements
- a22c056 Fix nested match codegen panic
- 978f14b Use break in sort example
- d9e0aa3 Add for loop support with range syntax
- a6fe98f Add string comparison operators == and !=
- 9b746d3 Add index syntax [] and change generics to <>
- aa09a93 check tests properly
- 7555204 Change default target name from capable
- f64de33 Remove outdated plan file
- 4bd4f97 remove outdated progress file
- 529b9ed move docs
- 4c6e29e Simple ok+err handlers
- f0b3345 Add Vec indexing syntax and fix for-loop range parsing
- c167d11 Move Result<T, E> enum from compiler builtin to stdlib
- 2f28e94 [WIP] Move Result methods from compiler special-case to stdlib
- 993e805 Fix some stuff
- 7416ad8 Fix loop linearity, indexing constraints, and call conv
- 3f2aca3 Add docs and TODO list
- fc93b87 Add never type and Vec<T> specializations
- d925d5b Add top-level defer statement
- 4763187 Make defer scope-based
- a29d59b Improve net listener and string helpers
- c53e84d Add if let statement sugar
- 15276b0 Add for {} infinite loop sugar
- 4ee669e Add char literals and string helpers
- 48b63f0 stdlib: flesh out string/vec helpers
- 1df8699 codegen: lower struct returns via sret/result-out
- 29effac docs: describe ABI lowering for struct returns

Fixes applied from review:

- Allow user-defined `string` type names now that `string` is userland; update reserved-name test to `i32`.
- Support sret lowering in runtime wrapper emission to avoid ABI mismatches.
- Use return lowering in `try` error path to avoid returning wrong signature.
- Initialize zero values for non-opaque structs to avoid null deref when building Result payloads.
85 changes: 0 additions & 85 deletions PLAN.md

This file was deleted.

3 changes: 0 additions & 3 deletions PROGRESS.md

This file was deleted.

4 changes: 4 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Done:
- Result<T, E> + is_ok/is_err/ok/err/unwrap_* implemented in stdlib (panic uses never type).
- Stdlib APIs updated to use Vec<T> (compiler maps Vec<u8>/Vec<i32>/Vec<string> to VecU8/VecI32/VecString).
- Codex reviewed Claude-generated commits.
3 changes: 0 additions & 3 deletions capc/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@ pub enum AbiType {
Bool,
Handle,
Ptr,
String,
Result(Box<AbiType>, Box<AbiType>),
/// ABI-only return lowering for `Result<String, i32>`.
ResultString,
/// ABI-only return lowering for `Result<T, E>` where out params are used.
ResultOut(Box<AbiType>, Box<AbiType>),
}
41 changes: 41 additions & 0 deletions capc/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,13 @@ pub struct Block {
pub enum Stmt {
Let(LetStmt),
Assign(AssignStmt),
Defer(DeferStmt),
Return(ReturnStmt),
Break(BreakStmt),
Continue(ContinueStmt),
If(IfStmt),
While(WhileStmt),
For(ForStmt),
Expr(ExprStmt),
}

Expand All @@ -161,6 +165,16 @@ pub struct ReturnStmt {
pub span: Span,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BreakStmt {
pub span: Span,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ContinueStmt {
pub span: Span,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct IfStmt {
pub cond: Expr,
Expand All @@ -176,6 +190,15 @@ pub struct WhileStmt {
pub span: Span,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ForStmt {
pub var: Ident,
pub start: Expr,
pub end: Expr,
pub body: Block,
pub span: Span,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ExprStmt {
pub expr: Expr,
Expand All @@ -189,14 +212,24 @@ pub struct AssignStmt {
pub span: Span,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DeferStmt {
pub expr: Expr,
pub span: Span,
}

impl Stmt {
pub fn span(&self) -> Span {
match self {
Stmt::Let(s) => s.span,
Stmt::Assign(s) => s.span,
Stmt::Defer(s) => s.span,
Stmt::Return(s) => s.span,
Stmt::Break(s) => s.span,
Stmt::Continue(s) => s.span,
Stmt::If(s) => s.span,
Stmt::While(s) => s.span,
Stmt::For(s) => s.span,
Stmt::Expr(s) => s.span,
}
}
Expand All @@ -209,6 +242,7 @@ pub enum Expr {
Call(CallExpr),
MethodCall(MethodCallExpr),
FieldAccess(FieldAccessExpr),
Index(IndexExpr),
StructLiteral(StructLiteralExpr),
Unary(UnaryExpr),
Binary(BinaryExpr),
Expand Down Expand Up @@ -288,6 +322,13 @@ pub struct FieldAccessExpr {
pub span: Span,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct IndexExpr {
pub object: Box<Expr>,
pub index: Box<Expr>,
pub span: Span,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct MethodCallExpr {
pub receiver: Box<Expr>,
Expand Down
36 changes: 17 additions & 19 deletions capc/src/codegen/abi_quirks.rs
Original file line number Diff line number Diff line change
@@ -1,35 +1,38 @@
//! ABI quirks and lowering helpers.
//!
//! These helpers are the single source of truth for the special-case ABI
//! shapes we use to lower `Result` values (ResultString and ResultOut).
//! shapes we use to lower `Result` values (ResultOut).

use crate::abi::AbiType;

use super::FnSig;

/// ResultString ABI uses a u64 length slot across targets.
pub fn result_string_len_bytes() -> u32 {
8
}

/// Return true if the ABI type is lowered as ResultString.
pub fn is_result_string(ty: &AbiType) -> bool {
matches!(ty, AbiType::ResultString)
}

/// Return true if the ABI type is lowered using ResultOut parameters.
pub fn is_result_out(ty: &AbiType) -> bool {
matches!(ty, AbiType::ResultOut(_, _))
}

/// Return true if the ABI type uses any Result lowering.
pub fn is_result_lowering(ty: &AbiType) -> bool {
is_result_string(ty) || is_result_out(ty)
is_result_out(ty)
}

/// Return true if a signature mismatch is explained by Result lowering.
fn is_sret_lowering(abi_sig: &FnSig, sig: &FnSig) -> bool {
if sig.ret != AbiType::Ptr || abi_sig.ret != AbiType::Unit {
return false;
}
if abi_sig.params.len() != sig.params.len() + 1 {
return false;
}
if abi_sig.params.first() != Some(&AbiType::Ptr) {
return false;
}
abi_sig.params[1..] == sig.params
}

/// Return true if a signature mismatch is explained by Result or sret lowering.
pub fn abi_sig_requires_lowering(abi_sig: &FnSig, sig: &FnSig) -> bool {
abi_sig != sig && is_result_lowering(&abi_sig.ret)
abi_sig != sig && (is_result_lowering(&abi_sig.ret) || is_sret_lowering(abi_sig, sig))
}

/// Error message used when a layout is requested for a lowered Result ABI.
Expand All @@ -46,8 +49,3 @@ pub fn result_abi_mismatch_error() -> &'static str {
pub fn result_out_params_error() -> &'static str {
"result out params"
}

/// Error message used when ResultString lowering is requested but unsupported.
pub fn result_string_params_error() -> &'static str {
"result abi"
}
Loading