-
Notifications
You must be signed in to change notification settings - Fork 0
Jm/elseif break continue #24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Implements break and continue for while loops: - Lexer: Break/Continue tokens - Parser: parse_break/parse_continue functions - AST/HIR: BreakStmt/ContinueStmt nodes - Type checker: validates break/continue are inside loops - Codegen: LoopTarget struct tracks header/exit blocks for jumps Includes positive and negative test cases. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Previously, nested matches where all arms terminate would panic with
"you cannot add an instruction to a block already filled".
Example that crashed:
```
fn test(x: i32) -> i32 {
match (x > 0) {
true => {
match (x > 5) {
true => { return 2 }
false => { return 1 }
}
}
false => { return 0 }
}
}
```
The issue: after the inner match terminates all paths (adds trap to
merge_block), the outer match still thinks control continues and tries
to add a `jump` to the already-terminated block.
The fix has two parts:
1. emit_hir_match_stmt now returns `Result<bool, Error>` where the bool
indicates whether all paths diverged (no arm continues to merge_block)
2. HirStmt::Expr special-cases unit-type match expressions - calls
emit_hir_match_stmt directly and returns Flow::Terminated if diverged
This approach is pragmatic: the clean solution would have all expressions
return divergence info, but that requires updating ~50 call sites. Since
match is currently the only expression type that can diverge, special-casing
it in HirStmt::Expr is reasonable.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Now that break is supported, replace the `j = 0 // break` workaround with an actual break statement. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement for loops with the syntax `for i in start..end { body }`:
- Lexer: Add For, In, DotDot tokens
- AST: Add ForStmt struct
- Parser: Add parse_for() function
- HIR: Add HirForStmt struct
- Type checker: Validate range bounds are i32, check affine moves
- Lowering: Lower ForStmt to HirForStmt with fresh local for loop var
- Monomorphization: Handle for loop monomorphization
- Codegen: Generate loop with separate increment block for proper
continue semantics (increment before jumping to header)
Add comprehensive tests:
- Runtime: for_basic, for_break, for_continue, for_nested, for_sum,
for_empty_range, for_break_nested, for_continue_nested
- Typecheck: for_non_i32_start, for_non_i32_end, for_loop_move
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add capable_rt_string_eq runtime function for byte-by-byte comparison - Add emit_string_eq helper in codegen to call the runtime function - Add match cases for BinaryOp::Eq/Neq with ValueRepr::Pair (strings) - Add string_compare test program Strings can now be compared directly with == and != operators instead of requiring the .eq() method call. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add string indexing with str[i] syntax (returns u8) - Add Slice/MutSlice indexing support - Change generic syntax from [] to <> (e.g., Result<T, E>, Box<i32>) - [] now unambiguously means indexing - Add heuristic to distinguish <> generics from < comparison - Update all stdlib and test .cap files to new syntax - Add string_index and generic_and_index test programs 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit adds several improvements to the language:
## Parser fix for for-loop ranges
Fixed a bug where `for i in 0..n { ... }` would fail to parse when
using a variable as the range bound. The issue was that `parse_primary`
would see `n {` and try to parse it as a struct literal `n { ... }`.
Added a new `parse_range_bound` function that accepts only:
- Integer literals
- Boolean literals (for type error at check time, not parse time)
- Simple paths (identifiers, possibly with :: separators)
This prevents struct literal ambiguity while still allowing variables
in range bounds.
## Vec indexing with [] syntax
Added support for indexing VecString, VecI32, and VecU8 with bracket
syntax:
- `lines[i]` now works and returns `Result<string, VecErr>`
- `indices[j]` returns `Result<i32, VecErr>`
- `bytes[k]` returns `Result<u8, VecErr>`
Implementation:
- Type checker recognizes Vec types and returns appropriate Result type
- Lowering phase desugars `vec[i]` to `vec.get(i)` call
- Reuses existing runtime functions, no codegen changes needed
## Updated examples
All examples now use idiomatic Capable with new language features:
- For loops with variable bounds (`for i in 0..n`)
- Vec indexing with `[]` syntax
- `is_ok()`, `is_err()`, `ok()`, `err()` Result methods
- `break` and `continue` in loops
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Result is now defined as a regular generic enum in stdlib/sys/result.cap instead of being a compiler-hardcoded type. Changes: - Remove "Result" from RESERVED_TYPE_PARAMS - Add stdlib/sys/result.cap with Result<T, E> enum definition - Update all path checks from "Result" to "sys.result.Result" in: - typeck/mod.rs (type capability/kind checks) - typeck/check.rs (pattern matching, ? operator, Vec indexing) - typeck/lower.rs (pattern lowering, try operator) - typeck/monomorphize.rs (type monomorphization, ABI handling) - codegen/emit.rs (code generation for Result patterns) - Fix parser error messages with broken format strings The is_ok/is_err/ok/err/unwrap_or methods are still compiler special-cased and will be moved to stdlib in a follow-up change. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Progress:
- Added panic() intrinsic that lowers to HirTrap
- Fixed parser bug: struct literals in match/if/while scrutinee positions
- Added parse_expr_no_struct() to prevent `x {` being parsed as struct literal
- Applied consistently to match, if, while conditions
- Added impl block support for enums (was only structs before)
- Added Result methods to stdlib/sys/result.cap:
- is_ok(), is_err(), unwrap_or(), unwrap_err_or()
- Removed Result method special-casing from check.rs (~115 lines)
- Removed Result method desugaring from lower.rs (~295 lines)
- Fixed pattern matching for qualified paths like Result::Ok(_)
Remaining issues:
- ok() and err() methods cannot be implemented yet because panic()
is typed as unit, not "never" (a diverging type)
- Need to add a "never" type that can unify with any type to properly
support panic() in expression contexts
- The test should_pass_result_ok_err.cap uses .ok() and .err() which
are now missing - this test will fail until never type is added
The stdlib Result now has 4 working methods. The .ok() and .err()
methods require panic() to have a proper never/diverging type.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Only applies to non-opaque structs and Result payloads; no inline struct ABI yet.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
No description provided.