feat: execute existing hash maps through Honey

This commit is contained in:
2026-10-30 11:46:49 +01:00
parent 31a1bf1995
commit e90d4f0829
19 changed files with 761 additions and 47 deletions
+20 -1
View File
@@ -23,6 +23,7 @@ LoopTargets :: struct {
continue_target ir.BlockId
exit ir.BlockId
cleanup_depth usize
break_reached bool = false
}
@hide:file
@@ -770,7 +771,14 @@ lower_while proc(state @mut State, id ast.NodeId) void ! (mem.AllocError | diagn
}
}
state.block = exit
state.terminated = false
state.terminated = (
loop.capture == null
and ast.expr_kind(state.tree, loop.condition) == .literal_bool
and mem.eql(ast.literal_text(state.tree, loop.condition), "true")
and !state.loop?.break_reached
)
if (state.terminated)
state.module.functions.items[state.function].blocks.items[usize(exit)].terminator = ir.Terminator{ kind = .unreachable, span = loop.span }
}
@hide:file
@@ -920,6 +928,12 @@ lower_statement proc(state @mut State, id ast.NodeId) void ! (mem.AllocError | d
.if_stmt: try lower_if(state, id)
.while_stmt: try lower_while(state, id)
.for_stmt: try lower_for(state, id)
.unreachable_stmt: {
state.module.functions.items[state.function].blocks.items[usize(state.block)].terminator = ir.Terminator{
kind = .unreachable, span = ast.node_span(tree, id),
}
state.terminated = true
}
.break_stmt, .continue_stmt: {
if (trap_type(state, id)) return
if (state.loop) |targets| {
@@ -928,6 +942,11 @@ lower_statement proc(state @mut State, id ast.NodeId) void ! (mem.AllocError | d
if (ast.stmt_kind(tree, id) == .continue_stmt) target = targets.continue_target
try lower_cleanups(state, targets.cleanup_depth, ir.no_value)
if (state.terminated) return
if (ast.stmt_kind(tree, id) == .break_stmt) {
reached := targets
reached.break_reached = true
state.loop = reached
}
state.module.functions.items[state.function].blocks.items[usize(state.block)].terminator = ir.Terminator{
kind = .jump, target = target, span = ast.node_span(tree, id),
}
+2 -2
View File
@@ -992,7 +992,7 @@ zero_iteration_body_errors_are_checked_but_not_executed test {
}
}
loop_returns_do_not_guarantee_return_and_assignment_arithmetic_still_checks_overflow test {
terminal_true_loops_and_assignment_arithmetic_preserve_runtime_behavior test {
sources [5][]u8 :: [
"main proc() int {\n while true { return 42 }\n}\n",
"main proc() int {\n while false { return 42 }\n}\n",
@@ -1005,7 +1005,7 @@ loop_returns_do_not_guarantee_return_and_assignment_arithmetic_still_checks_over
defer diagnostics.deinit(&diagnostic_store)
module := try compile_owned(source, &diagnostic_store)
defer ir.deinit(&module)
if (index != 2) {
if (index != 0 and index != 2) {
try testing.expect_equal(1, diagnostics.count(&diagnostic_store))
diagnostic :: diagnostics.get(&diagnostic_store, diagnostics.DiagnosticId(0))?
try testing.expect_equal(diagnostics.Code.missing_return, diagnostic.code)