From ae5e6cd507b0843569c66308d7e2d20deafa1c75 Mon Sep 17 00:00:00 2001 From: agra Date: Wed, 18 Feb 2026 03:22:06 +0200 Subject: [PATCH] ... --- src/codegen.zig | 25 +++++++++---------------- src/comptime.zig | 4 ++++ src/parser.zig | 11 ++++++++++- 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/src/codegen.zig b/src/codegen.zig index b94b7ff..08b3436 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -1662,15 +1662,6 @@ pub const CodeGen = struct { /// Walk an AST body to find a struct declaration (from `return struct { ... }` or bare struct expr). fn findDeclInBody(comptime T: type, comptime tag: std.meta.FieldEnum(@TypeOf(@as(Node, undefined).data)), body: *Node) ?T { - const extract = struct { - fn get(node: *Node) ?T { - return if (@field(node.data, @tagName(tag)) != @as(?T, null)) - @field(node.data, @tagName(tag)) - else - null; - } - }; - _ = extract; if (body.data == tag) return @field(body.data, @tagName(tag)); if (body.data == .block) { for (body.data.block.stmts) |stmt| { @@ -3258,7 +3249,6 @@ pub const CodeGen = struct { const uname = result_type.union_type; const resolved = self.resolveAlias(uname); const info = self.lookupTaggedEnumInfo(resolved) orelse return self.emitError("unknown tagged enum type"); - const tag_ty = self.getEnumLLVMType(resolved); var lhs_val = try self.genExprAsType(binop.lhs, result_type); var rhs_val = try self.genExprAsType(binop.rhs, result_type); @@ -3270,7 +3260,6 @@ pub const CodeGen = struct { // Extract tags (field 0) and compare const lhs_tag = self.extractValue(lhs_val, 0, "lhs_tag"); const rhs_tag = self.extractValue(rhs_val, 0, "rhs_tag"); - _ = tag_ty; const pred: c_uint = if (binop.op == .eq) c.LLVMIntEQ else c.LLVMIntNE; return self.icmp(pred, lhs_tag, rhs_tag, "tag_cmp"); } @@ -5498,6 +5487,7 @@ pub const CodeGen = struct { // Generate arguments with type conversion to match parameter types const num_params = c.LLVMCountParamTypes(fn_type); + if (num_params > 64) return self.emitErrorFmt("function has {d} parameters, exceeding maximum of 64", .{num_params}); var param_llvm_types: [64]c.LLVMTypeRef = undefined; if (num_params > 0) { c.LLVMGetParamTypes(fn_type, ¶m_llvm_types); @@ -5645,6 +5635,7 @@ pub const CodeGen = struct { // Build LLVM function type from FunctionTypeInfo const ptr_ty_llvm = self.ptrType(); + if (fti.param_types.len > 64) return self.emitErrorFmt("indirect call has {d} parameters, exceeding maximum of 64", .{fti.param_types.len}); var param_llvm_types: [64]c.LLVMTypeRef = undefined; for (fti.param_types, 0..) |pt, i| { // [N]T and [:0]T params are pointers at the ABI level @@ -5963,8 +5954,8 @@ pub const CodeGen = struct { // Find the cast argument and extract the runtime type tag + any value source var cast_arg_idx: usize = 0; - var type_tag_node: *Node = undefined; - var any_val_node: *Node = undefined; + var type_tag_node: ?*Node = null; + var any_val_node: ?*Node = null; for (call_node.args, 0..) |arg, i| { if (arg.data == .call and arg.data.call.callee.data == .identifier) { const name = arg.data.call.callee.data.identifier.name; @@ -5978,8 +5969,8 @@ pub const CodeGen = struct { } // Generate the runtime type tag value and the Any value - const type_tag_val = try self.genExpr(type_tag_node); - const any_val = try self.genExpr(any_val_node); + const type_tag_val = try self.genExpr(type_tag_node orelse return self.emitError("runtime dispatch requires a cast() argument")); + const any_val = try self.genExpr(any_val_node orelse return self.emitError("runtime dispatch requires a cast() argument")); // Generate non-cast arguments (evaluated once, before the switch) var other_arg_vals = std.ArrayList(?c.LLVMValueRef).empty; for (call_node.args, 0..) |arg, i| { @@ -6469,7 +6460,7 @@ pub const CodeGen = struct { try self.pushScope(); 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 }); + try self.registerVariable(idx_name, idx_alloca, Type.s(64)); } } @@ -6502,6 +6493,7 @@ pub const CodeGen = struct { if (!std.mem.eql(u8, for_expr.capture_name, "_")) { // Alias mode: capture points directly to element in array/slice + try self.saveShadowed(for_expr.capture_name); try self.named_values.put(for_expr.capture_name, .{ .ptr = elem_gep, .ty = elem_ty, @@ -6578,6 +6570,7 @@ pub const CodeGen = struct { if (subject_ty.isEnum()) enum_name = subject_ty.enum_type; if (subject_ty.isUnion()) union_name = subject_ty.union_type; + // Get the switch value: for unions, load the tag from field 0; for enums, use the value directly // Get the switch value: for unions, load the tag from field 0; for enums, use the value directly const subject_val: c.LLVMValueRef = if (union_name != null) blk: { // Union: load tag from field 0 of the alloca diff --git a/src/comptime.zig b/src/comptime.zig index 3168664..1ee6069 100644 --- a/src/comptime.zig +++ b/src/comptime.zig @@ -81,6 +81,7 @@ pub const Value = union(enum) { return switch (self) { .bool_val => |bv| bv, .int_val => |iv| iv != 0, + .null_val => false, else => true, }; } @@ -881,7 +882,10 @@ pub const Compiler = struct { // without sema info): assume fat pointer layout {ptr=0, len=1} if (std.mem.eql(u8, fa.field, "len")) { try self.emit(.{ .get_field = 1 }); + } else if (std.mem.eql(u8, fa.field, "ptr")) { + try self.emit(.{ .get_field = 0 }); } else { + // Other fields (e.g. union promoted fields) default to field 0 try self.emit(.{ .get_field = 0 }); } }, diff --git a/src/parser.zig b/src/parser.zig index 0663784..eeea3c7 100644 --- a/src/parser.zig +++ b/src/parser.zig @@ -363,7 +363,16 @@ pub const Parser = struct { if (self.current.tag == .int_literal) { const arg_start = self.current.loc.start; const text = self.tokenSlice(self.current); - const value = std.fmt.parseInt(i64, text, 10) catch 0; + const base: u8 = if (text.len > 2 and text[0] == '0' and (text[1] == 'x' or text[1] == 'X')) + 16 + else if (text.len > 2 and text[0] == '0' and (text[1] == 'b' or text[1] == 'B')) + 2 + else + 10; + const digits = if (base != 10) text[2..] else text; + const value = std.fmt.parseInt(i64, digits, base) catch { + return self.fail("invalid integer literal in type argument"); + }; self.advance(); try args.append(self.allocator, try self.createNode(arg_start, .{ .int_literal = .{ .value = value } })); } else {