...
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 });
|
||||
}
|
||||
},
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user