for arr: (it) {}
This commit is contained in:
@@ -296,6 +296,7 @@ pub const CodeGen = struct {
|
||||
const NamedValue = struct {
|
||||
ptr: c.LLVMValueRef, // alloca pointer
|
||||
ty: Type, // sx type
|
||||
is_const: bool = false,
|
||||
};
|
||||
|
||||
/// Unified value lookup result — avoids sequential hash lookups at hot paths.
|
||||
@@ -2881,6 +2882,8 @@ pub const CodeGen = struct {
|
||||
return self.emitErrorFmt("undefined variable '{s}'", .{name});
|
||||
const entry = lookup.asNamedValue() orelse
|
||||
return self.emitErrorFmt("cannot assign to constant '{s}'", .{name});
|
||||
if (entry.is_const)
|
||||
return self.emitErrorFmt("cannot assign to '{s}'", .{name});
|
||||
|
||||
// Meta type reassignment: x = Vec4, x = f64, x = test
|
||||
if (entry.ty == .meta_type and asgn.op == .assign) {
|
||||
@@ -6345,15 +6348,17 @@ pub const CodeGen = struct {
|
||||
|
||||
const elem_llvm_ty = self.typeToLLVM(elem_ty);
|
||||
|
||||
// Allocate it_index (s64) and it (element type)
|
||||
const idx_alloca = self.buildEntryBlockAlloca(i64_type, "it_index");
|
||||
// Allocate index variable
|
||||
const idx_alloca = self.buildEntryBlockAlloca(i64_type, "for_idx");
|
||||
_ = c.LLVMBuildStore(self.builder, c.LLVMConstInt(i64_type, 0, 0), idx_alloca);
|
||||
const it_alloca = self.buildEntryBlockAlloca(elem_llvm_ty, "it");
|
||||
|
||||
// Push scope and bind it, it_index
|
||||
// Push scope and bind index if requested
|
||||
try self.pushScope();
|
||||
try self.named_values.put("it", .{ .ptr = it_alloca, .ty = elem_ty });
|
||||
try self.named_values.put("it_index", .{ .ptr = idx_alloca, .ty = Type.s(64) });
|
||||
if (for_expr.index_name) |idx_name| {
|
||||
if (!std.mem.eql(u8, idx_name, "_")) {
|
||||
try self.named_values.put(idx_name, .{ .ptr = idx_alloca, .ty = Type.s(64), .is_const = true });
|
||||
}
|
||||
}
|
||||
|
||||
// Create basic blocks
|
||||
const cond_bb = self.appendBB("for.cond");
|
||||
@@ -6363,29 +6368,32 @@ pub const CodeGen = struct {
|
||||
|
||||
self.br(cond_bb);
|
||||
|
||||
// Condition: it_index < len
|
||||
// Condition: index < len
|
||||
self.positionAt(cond_bb);
|
||||
const cur_idx = c.LLVMBuildLoad2(self.builder, i64_type, idx_alloca, "cur_idx");
|
||||
const cond_val = self.icmp(c.LLVMIntSLT, cur_idx, len_val, "for_cond");
|
||||
self.condBr(cond_val, body_bb, after_bb);
|
||||
|
||||
// Body: load it = iterable[it_index], then execute body
|
||||
// Body: compute element GEP, bind capture, execute body
|
||||
self.positionAt(body_bb);
|
||||
const body_idx = c.LLVMBuildLoad2(self.builder, i64_type, idx_alloca, "body_idx");
|
||||
|
||||
if (is_slice) {
|
||||
// Slice: GEP through data pointer
|
||||
const gep = self.gepPointerElement(elem_llvm_ty, iter_ptr, body_idx, "for_elem");
|
||||
const elem_val = c.LLVMBuildLoad2(self.builder, elem_llvm_ty, gep, "it_val");
|
||||
_ = c.LLVMBuildStore(self.builder, elem_val, it_alloca);
|
||||
} else {
|
||||
// Array: GEP with [0, idx]
|
||||
const elem_gep = if (is_slice)
|
||||
self.gepPointerElement(elem_llvm_ty, iter_ptr, body_idx, "for_elem")
|
||||
else blk: {
|
||||
const arr_llvm_ty = self.typeToLLVM(iter_ty);
|
||||
const zero = c.LLVMConstInt(i64_type, 0, 0);
|
||||
var indices = [_]c.LLVMValueRef{ zero, body_idx };
|
||||
const gep = c.LLVMBuildGEP2(self.builder, arr_llvm_ty, iter_ptr, &indices, 2, "for_elem");
|
||||
const elem_val = c.LLVMBuildLoad2(self.builder, elem_llvm_ty, gep, "it_val");
|
||||
_ = c.LLVMBuildStore(self.builder, elem_val, it_alloca);
|
||||
break :blk c.LLVMBuildGEP2(self.builder, arr_llvm_ty, iter_ptr, &indices, 2, "for_elem");
|
||||
};
|
||||
|
||||
if (!std.mem.eql(u8, for_expr.capture_name, "_")) {
|
||||
// Alias mode: capture points directly to element in array/slice
|
||||
try self.named_values.put(for_expr.capture_name, .{
|
||||
.ptr = elem_gep,
|
||||
.ty = elem_ty,
|
||||
.is_const = true,
|
||||
});
|
||||
}
|
||||
|
||||
// Save and set loop context for break/continue
|
||||
@@ -6405,7 +6413,7 @@ pub const CodeGen = struct {
|
||||
self.br(incr_bb);
|
||||
}
|
||||
|
||||
// Increment it_index, then branch back to condition
|
||||
// Increment index, then branch back to condition
|
||||
self.positionAt(incr_bb);
|
||||
const inc_idx = c.LLVMBuildLoad2(self.builder, i64_type, idx_alloca, "inc_idx");
|
||||
const next_idx = c.LLVMBuildAdd(self.builder, inc_idx, c.LLVMConstInt(i64_type, 1, 0), "next_idx");
|
||||
|
||||
Reference in New Issue
Block a user