...
This commit is contained in:
@@ -1051,5 +1051,60 @@ END;
|
|||||||
// Symbol rename: c_abs maps to C's abs()
|
// Symbol rename: c_abs maps to C's abs()
|
||||||
print("foreign-rename: {}\n", c_abs(xx -42));
|
print("foreign-rename: {}\n", c_abs(xx -42));
|
||||||
|
|
||||||
|
// ========================================================
|
||||||
|
// 16. COMPOUND ASSIGNMENT TYPE CONVERSION
|
||||||
|
// ========================================================
|
||||||
|
print("=== 16. Compound Assign ===\n");
|
||||||
|
{
|
||||||
|
ca_a : f64 = 10.0;
|
||||||
|
ca_b : f32 = 3.0;
|
||||||
|
ca_a += ca_b;
|
||||||
|
print("f64+=f32: {}\n", ca_a);
|
||||||
|
|
||||||
|
ca_c : s64 = 100;
|
||||||
|
ca_d : s32 = 7;
|
||||||
|
ca_c -= ca_d;
|
||||||
|
print("s64-=s32: {}\n", ca_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========================================================
|
||||||
|
// 17. SLICE/ARRAY .ptr ACCESS
|
||||||
|
// ========================================================
|
||||||
|
print("=== 17. Slice Ptr ===\n");
|
||||||
|
{
|
||||||
|
sarr : [5]s32 = .[10, 20, 30, 40, 50];
|
||||||
|
ssl := sarr[1..4];
|
||||||
|
sp := ssl.ptr;
|
||||||
|
print("sl-ptr[0]: {}\n", sp[0]);
|
||||||
|
print("sl-ptr[1]: {}\n", sp[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========================================================
|
||||||
|
// 18. ARRAYS OF USER-DEFINED TYPES
|
||||||
|
// ========================================================
|
||||||
|
print("=== 18. Array of Structs ===\n");
|
||||||
|
{
|
||||||
|
spts : [2]Point = .[Point.{1, 2}, Point.{3, 4}];
|
||||||
|
spt2 := spts[1];
|
||||||
|
print("arr-struct-x: {}\n", spt2.x);
|
||||||
|
for spts: (it) {
|
||||||
|
print("for-struct: {}\n", it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========================================================
|
||||||
|
// 19. LOCAL FUNCTION RETURNING STRUCT/ENUM
|
||||||
|
// ========================================================
|
||||||
|
print("=== 19. Local Fn Return ===\n");
|
||||||
|
{
|
||||||
|
local_pt :: () -> Point { Point.{42, 99}; }
|
||||||
|
lp := local_pt();
|
||||||
|
print("local-struct: {} {}\n", lp.x, lp.y);
|
||||||
|
|
||||||
|
local_sh :: () -> Shape { .circle(2.5); }
|
||||||
|
ls := local_sh();
|
||||||
|
print("local-enum: {}\n", ls);
|
||||||
|
}
|
||||||
|
|
||||||
print("=== DONE ===\n");
|
print("=== DONE ===\n");
|
||||||
}
|
}
|
||||||
|
|||||||
115
src/codegen.zig
115
src/codegen.zig
@@ -480,7 +480,7 @@ pub const CodeGen = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn resolveElementType(self: *CodeGen, name: []const u8, comptime kind: []const u8) !Type {
|
fn resolveElementType(self: *CodeGen, name: []const u8, comptime kind: []const u8) !Type {
|
||||||
return Type.fromName(name) orelse
|
return self.resolveTypeFromName(name) orelse
|
||||||
return self.emitErrorFmt("unknown " ++ kind ++ " element type '{s}'", .{name});
|
return self.emitErrorFmt("unknown " ++ kind ++ " element type '{s}'", .{name});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -557,11 +557,11 @@ pub const CodeGen = struct {
|
|||||||
.struct_type => |name| if (self.lookupStructInfo(name)) |info| info.llvm_type else unreachable,
|
.struct_type => |name| if (self.lookupStructInfo(name)) |info| info.llvm_type else unreachable,
|
||||||
.union_type => |name| if (self.lookupTaggedEnumInfo(name)) |info| info.llvm_type else if (self.lookupUnionInfo(name)) |info| info.llvm_type else unreachable,
|
.union_type => |name| if (self.lookupTaggedEnumInfo(name)) |info| info.llvm_type else if (self.lookupUnionInfo(name)) |info| info.llvm_type else unreachable,
|
||||||
.array_type => |info| {
|
.array_type => |info| {
|
||||||
const elem_ty = Type.fromName(info.element_name) orelse unreachable;
|
const elem_ty = self.resolveTypeFromName(info.element_name) orelse unreachable;
|
||||||
return c.LLVMArrayType2(self.typeToLLVM(elem_ty), info.length);
|
return c.LLVMArrayType2(self.typeToLLVM(elem_ty), info.length);
|
||||||
},
|
},
|
||||||
.vector_type => |info| {
|
.vector_type => |info| {
|
||||||
const elem_ty = Type.fromName(info.element_name) orelse unreachable;
|
const elem_ty = self.resolveTypeFromName(info.element_name) orelse unreachable;
|
||||||
return c.LLVMVectorType(self.typeToLLVM(elem_ty), info.length);
|
return c.LLVMVectorType(self.typeToLLVM(elem_ty), info.length);
|
||||||
},
|
},
|
||||||
.pointer_type, .many_pointer_type, .function_type => self.ptrType(),
|
.pointer_type, .many_pointer_type, .function_type => self.ptrType(),
|
||||||
@@ -2381,9 +2381,8 @@ pub const CodeGen = struct {
|
|||||||
|
|
||||||
const ret_val = try self.genExpr(lambda.body);
|
const ret_val = try self.genExpr(lambda.body);
|
||||||
if (ret_val) |val| {
|
if (ret_val) |val| {
|
||||||
const src_ty = self.llvmTypeToSxType(c.LLVMTypeOf(val));
|
const prepared = try self.prepareReturnValue(val, ret_sx_type);
|
||||||
const converted = self.convertValue(val, src_ty, ret_sx_type);
|
self.ret(prepared);
|
||||||
self.ret(converted);
|
|
||||||
} else {
|
} else {
|
||||||
self.retVoid();
|
self.retVoid();
|
||||||
}
|
}
|
||||||
@@ -2461,9 +2460,8 @@ pub const CodeGen = struct {
|
|||||||
if (ret_sx_type == .void_type) {
|
if (ret_sx_type == .void_type) {
|
||||||
self.retVoid();
|
self.retVoid();
|
||||||
} else if (last_val) |val| {
|
} else if (last_val) |val| {
|
||||||
const src_ty = self.llvmTypeToSxType(c.LLVMTypeOf(val));
|
const ret_val = try self.prepareReturnValue(val, ret_sx_type);
|
||||||
const converted = self.convertValue(val, src_ty, ret_sx_type);
|
self.ret(ret_val);
|
||||||
self.ret(converted);
|
|
||||||
} else {
|
} else {
|
||||||
self.retVoid();
|
self.retVoid();
|
||||||
}
|
}
|
||||||
@@ -2977,7 +2975,7 @@ pub const CodeGen = struct {
|
|||||||
// C-style union: full assignment not supported, use field assignment
|
// C-style union: full assignment not supported, use field assignment
|
||||||
}
|
}
|
||||||
|
|
||||||
const new_val = try self.genExpr(asgn.value);
|
const new_val = try self.genExprAsType(asgn.value, entry.ty);
|
||||||
const llvm_ty = self.typeToLLVM(entry.ty);
|
const llvm_ty = self.typeToLLVM(entry.ty);
|
||||||
|
|
||||||
const store_val = if (asgn.op == .assign) new_val else blk: {
|
const store_val = if (asgn.op == .assign) new_val else blk: {
|
||||||
@@ -3150,7 +3148,7 @@ pub const CodeGen = struct {
|
|||||||
}
|
}
|
||||||
if (obj_ty.isSlice()) {
|
if (obj_ty.isSlice()) {
|
||||||
const slice_info = obj_ty.slice_type;
|
const slice_info = obj_ty.slice_type;
|
||||||
const elem_ty = Type.fromName(slice_info.element_name) orelse return self.emitError("unknown slice element type");
|
const elem_ty = self.resolveTypeFromName(slice_info.element_name) orelse return self.emitError("unknown slice element type");
|
||||||
const elem_llvm_ty = self.typeToLLVM(elem_ty);
|
const elem_llvm_ty = self.typeToLLVM(elem_ty);
|
||||||
// Load slice value to get ptr
|
// Load slice value to get ptr
|
||||||
const slice_val = blk: {
|
const slice_val = blk: {
|
||||||
@@ -3558,25 +3556,22 @@ pub const CodeGen = struct {
|
|||||||
fn hoistInlineTypeDecl(self: *CodeGen, parent_name: []const u8, child_name: []const u8, type_node: *Node) anyerror!void {
|
fn hoistInlineTypeDecl(self: *CodeGen, parent_name: []const u8, child_name: []const u8, type_node: *Node) anyerror!void {
|
||||||
const synthetic_name = try std.fmt.allocPrint(self.allocator, "{s}.{s}", .{ parent_name, child_name });
|
const synthetic_name = try std.fmt.allocPrint(self.allocator, "{s}.{s}", .{ parent_name, child_name });
|
||||||
switch (type_node.data) {
|
switch (type_node.data) {
|
||||||
.struct_decl => |inline_sd| {
|
.struct_decl => |*sd| {
|
||||||
var hoisted = inline_sd;
|
sd.name = synthetic_name;
|
||||||
hoisted.name = synthetic_name;
|
try self.registerStructType(sd.*);
|
||||||
try self.registerStructType(hoisted);
|
|
||||||
},
|
},
|
||||||
.union_decl => |inline_ud| {
|
.union_decl => |*ud| {
|
||||||
var hoisted_ud = inline_ud;
|
ud.name = synthetic_name;
|
||||||
hoisted_ud.name = synthetic_name;
|
try self.registerUnionType(ud.*);
|
||||||
try self.registerUnionType(hoisted_ud);
|
|
||||||
},
|
},
|
||||||
.enum_decl => |inline_ed| {
|
.enum_decl => |*ed| {
|
||||||
if (inline_ed.variant_types.len > 0) {
|
ed.name = synthetic_name;
|
||||||
var hoisted = inline_ed;
|
if (ed.variant_types.len > 0) {
|
||||||
hoisted.name = synthetic_name;
|
try self.registerTaggedEnum(ed.*);
|
||||||
try self.registerTaggedEnum(hoisted);
|
|
||||||
} else {
|
} else {
|
||||||
try self.type_registry.put(synthetic_name, .{ .plain_enum = inline_ed.variant_names });
|
try self.type_registry.put(synthetic_name, .{ .plain_enum = ed.variant_names });
|
||||||
_ = try self.getAnyTypeId(synthetic_name, .{ .enum_type = synthetic_name });
|
_ = try self.getAnyTypeId(synthetic_name, .{ .enum_type = synthetic_name });
|
||||||
if (inline_ed.backing_type) |bt_node| {
|
if (ed.backing_type) |bt_node| {
|
||||||
const bt = self.resolveType(bt_node);
|
const bt = self.resolveType(bt_node);
|
||||||
try self.enum_backing_types.put(synthetic_name, self.typeToLLVM(bt));
|
try self.enum_backing_types.put(synthetic_name, self.typeToLLVM(bt));
|
||||||
}
|
}
|
||||||
@@ -3783,7 +3778,7 @@ pub const CodeGen = struct {
|
|||||||
// Validate payload is an array type
|
// Validate payload is an array type
|
||||||
const payload_size = switch (payload_ty) {
|
const payload_size = switch (payload_ty) {
|
||||||
.array_type => |info| blk: {
|
.array_type => |info| blk: {
|
||||||
const elem_ty = Type.fromName(info.element_name) orelse {
|
const elem_ty = self.resolveTypeFromName(info.element_name) orelse {
|
||||||
return self.emitErrorFmt(
|
return self.emitErrorFmt(
|
||||||
"enum '{s}': layout field 'payload' has unresolved element type '{s}'",
|
"enum '{s}': layout field 'payload' has unresolved element type '{s}'",
|
||||||
.{ enum_name, info.element_name },
|
.{ enum_name, info.element_name },
|
||||||
@@ -4623,7 +4618,7 @@ pub const CodeGen = struct {
|
|||||||
// Vector: extractelement + box as Any
|
// Vector: extractelement + box as Any
|
||||||
if (val_ty.isVector()) {
|
if (val_ty.isVector()) {
|
||||||
const info = val_ty.vector_type;
|
const info = val_ty.vector_type;
|
||||||
const elem_ty = Type.fromName(info.element_name) orelse
|
const elem_ty = self.resolveTypeFromName(info.element_name) orelse
|
||||||
return self.emitErrorFmt("unknown vector element type '{s}'", .{info.element_name});
|
return self.emitErrorFmt("unknown vector element type '{s}'", .{info.element_name});
|
||||||
const idx = try self.genExpr(call_node.args[1]);
|
const idx = try self.genExpr(call_node.args[1]);
|
||||||
const elem = c.LLVMBuildExtractElement(self.builder, val, idx, "vec_elem");
|
const elem = c.LLVMBuildExtractElement(self.builder, val, idx, "vec_elem");
|
||||||
@@ -4685,7 +4680,7 @@ pub const CodeGen = struct {
|
|||||||
// Slice: extract ptr, GEP to element, load, box as Any
|
// Slice: extract ptr, GEP to element, load, box as Any
|
||||||
if (val_ty.isSlice()) {
|
if (val_ty.isSlice()) {
|
||||||
const sinfo = val_ty.slice_type;
|
const sinfo = val_ty.slice_type;
|
||||||
const elem_ty = Type.fromName(sinfo.element_name) orelse
|
const elem_ty = self.resolveTypeFromName(sinfo.element_name) orelse
|
||||||
return self.emitErrorFmt("unknown slice element type '{s}'", .{sinfo.element_name});
|
return self.emitErrorFmt("unknown slice element type '{s}'", .{sinfo.element_name});
|
||||||
const elem_llvm_ty = self.typeToLLVM(elem_ty);
|
const elem_llvm_ty = self.typeToLLVM(elem_ty);
|
||||||
// val is {ptr, i32} — extract ptr
|
// val is {ptr, i32} — extract ptr
|
||||||
@@ -4699,7 +4694,7 @@ pub const CodeGen = struct {
|
|||||||
// Array: GEP + load + box as Any
|
// Array: GEP + load + box as Any
|
||||||
if (val_ty.isArray()) {
|
if (val_ty.isArray()) {
|
||||||
const ainfo = val_ty.array_type;
|
const ainfo = val_ty.array_type;
|
||||||
const elem_ty = Type.fromName(ainfo.element_name) orelse
|
const elem_ty = self.resolveTypeFromName(ainfo.element_name) orelse
|
||||||
return self.emitErrorFmt("unknown array element type '{s}'", .{ainfo.element_name});
|
return self.emitErrorFmt("unknown array element type '{s}'", .{ainfo.element_name});
|
||||||
const arr_llvm_ty = self.typeToLLVM(val_ty);
|
const arr_llvm_ty = self.typeToLLVM(val_ty);
|
||||||
const elem_llvm_ty = self.typeToLLVM(elem_ty);
|
const elem_llvm_ty = self.typeToLLVM(elem_ty);
|
||||||
@@ -5215,7 +5210,7 @@ pub const CodeGen = struct {
|
|||||||
const elem_llvm_ty = if (obj_ty == .string_type)
|
const elem_llvm_ty = if (obj_ty == .string_type)
|
||||||
self.i8Type()
|
self.i8Type()
|
||||||
else
|
else
|
||||||
self.typeToLLVM(Type.fromName(obj_ty.slice_type.element_name) orelse return self.emitError("unknown slice element type"));
|
self.typeToLLVM(self.resolveTypeFromName(obj_ty.slice_type.element_name) orelse return self.emitError("unknown slice element type"));
|
||||||
const new_ptr = self.gepPointerElement(elem_llvm_ty, base_ptr, start_val, "sslice_off");
|
const new_ptr = self.gepPointerElement(elem_llvm_ty, base_ptr, start_val, "sslice_off");
|
||||||
// len = end - start
|
// len = end - start
|
||||||
const len_val = c.LLVMBuildSub(self.builder, end_val, start_val, "sslice_len");
|
const len_val = c.LLVMBuildSub(self.builder, end_val, start_val, "sslice_len");
|
||||||
@@ -5803,9 +5798,9 @@ pub const CodeGen = struct {
|
|||||||
if (i < call_node.args.len) {
|
if (i < call_node.args.len) {
|
||||||
const arg_ty = self.inferType(call_node.args[i]);
|
const arg_ty = self.inferType(call_node.args[i]);
|
||||||
const elem_ty = if (arg_ty.isArray())
|
const elem_ty = if (arg_ty.isArray())
|
||||||
Type.fromName(arg_ty.array_type.element_name) orelse arg_ty
|
self.resolveTypeFromName(arg_ty.array_type.element_name) orelse arg_ty
|
||||||
else if (arg_ty.isSlice())
|
else if (arg_ty.isSlice())
|
||||||
Type.fromName(arg_ty.slice_type.element_name) orelse arg_ty
|
self.resolveTypeFromName(arg_ty.slice_type.element_name) orelse arg_ty
|
||||||
else
|
else
|
||||||
arg_ty;
|
arg_ty;
|
||||||
if (bindings.get(type_name)) |existing| {
|
if (bindings.get(type_name)) |existing| {
|
||||||
@@ -6036,9 +6031,9 @@ pub const CodeGen = struct {
|
|||||||
if (std.mem.eql(u8, tp.name, tp_name)) {
|
if (std.mem.eql(u8, tp.name, tp_name)) {
|
||||||
// Extract element type from concrete slice type
|
// Extract element type from concrete slice type
|
||||||
const elem_ty = if (sx_type.isSlice())
|
const elem_ty = if (sx_type.isSlice())
|
||||||
Type.fromName(sx_type.slice_type.element_name) orelse sx_type
|
self.resolveTypeFromName(sx_type.slice_type.element_name) orelse sx_type
|
||||||
else if (sx_type.isArray())
|
else if (sx_type.isArray())
|
||||||
Type.fromName(sx_type.array_type.element_name) orelse sx_type
|
self.resolveTypeFromName(sx_type.array_type.element_name) orelse sx_type
|
||||||
else
|
else
|
||||||
sx_type;
|
sx_type;
|
||||||
try bindings.put(tp.name, elem_ty);
|
try bindings.put(tp.name, elem_ty);
|
||||||
@@ -6291,16 +6286,8 @@ pub const CodeGen = struct {
|
|||||||
if (ret_sx_type == .void_type) {
|
if (ret_sx_type == .void_type) {
|
||||||
self.retVoid();
|
self.retVoid();
|
||||||
} else if (last_val) |val| {
|
} else if (last_val) |val| {
|
||||||
if (ret_sx_type.isStruct()) {
|
const ret_val = try self.prepareReturnValue(val, ret_sx_type);
|
||||||
const sname = ret_sx_type.struct_type;
|
self.ret(ret_val);
|
||||||
const info = try self.getStructInfo(sname);
|
|
||||||
const loaded = c.LLVMBuildLoad2(self.builder, info.llvm_type, val, "retval");
|
|
||||||
self.ret(loaded);
|
|
||||||
} else {
|
|
||||||
const src_ty = self.llvmTypeToSxType(c.LLVMTypeOf(val));
|
|
||||||
const converted = self.convertValue(val, src_ty, ret_sx_type);
|
|
||||||
self.ret(converted);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
_ = c.LLVMBuildUnreachable(self.builder);
|
_ = c.LLVMBuildUnreachable(self.builder);
|
||||||
}
|
}
|
||||||
@@ -6427,7 +6414,7 @@ pub const CodeGen = struct {
|
|||||||
if (iter_ty.isSlice()) {
|
if (iter_ty.isSlice()) {
|
||||||
is_slice = true;
|
is_slice = true;
|
||||||
const info = iter_ty.slice_type;
|
const info = iter_ty.slice_type;
|
||||||
elem_ty = Type.fromName(info.element_name) orelse Type.s(64);
|
elem_ty = self.resolveTypeFromName(info.element_name) orelse Type.s(64);
|
||||||
// Load slice value from alloca
|
// Load slice value from alloca
|
||||||
if (for_expr.iterable.data == .identifier) {
|
if (for_expr.iterable.data == .identifier) {
|
||||||
if (self.named_values.get(for_expr.iterable.data.identifier.name)) |entry| {
|
if (self.named_values.get(for_expr.iterable.data.identifier.name)) |entry| {
|
||||||
@@ -6438,7 +6425,7 @@ pub const CodeGen = struct {
|
|||||||
} else return self.emitError("for: slice iterable must be a variable");
|
} else return self.emitError("for: slice iterable must be a variable");
|
||||||
} else if (iter_ty.isArray()) {
|
} else if (iter_ty.isArray()) {
|
||||||
const info = iter_ty.array_type;
|
const info = iter_ty.array_type;
|
||||||
elem_ty = Type.fromName(info.element_name) orelse Type.s(64);
|
elem_ty = self.resolveTypeFromName(info.element_name) orelse Type.s(64);
|
||||||
len_val = c.LLVMConstInt(i64_type, info.length, 0);
|
len_val = c.LLVMConstInt(i64_type, info.length, 0);
|
||||||
// Get pointer to array
|
// Get pointer to array
|
||||||
if (for_expr.iterable.data == .identifier) {
|
if (for_expr.iterable.data == .identifier) {
|
||||||
@@ -6571,12 +6558,23 @@ pub const CodeGen = struct {
|
|||||||
if (subject_ty.isUnion()) union_name = subject_ty.union_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
|
||||||
// Get the switch value: for unions, load the tag from field 0; for enums, use the value directly
|
// For union subjects, we need a pointer for both tag loading and payload capture.
|
||||||
|
// If the subject is a simple identifier, use its existing alloca; otherwise generate
|
||||||
|
// the expression and spill into a temporary alloca.
|
||||||
|
var union_subject_ptr: c.LLVMValueRef = null;
|
||||||
const subject_val: c.LLVMValueRef = if (union_name != null) blk: {
|
const subject_val: c.LLVMValueRef = if (union_name != null) blk: {
|
||||||
// Union: load tag from field 0 of the alloca
|
|
||||||
const entry = self.named_values.get(match.subject.data.identifier.name).?;
|
|
||||||
const info = self.lookupTaggedEnumInfo(union_name.?).?;
|
const info = self.lookupTaggedEnumInfo(union_name.?).?;
|
||||||
break :blk self.loadStructField(info.llvm_type, entry.ptr, 0, self.getEnumLLVMType(union_name.?));
|
if (match.subject.data == .identifier) {
|
||||||
|
const entry = self.named_values.get(match.subject.data.identifier.name).?;
|
||||||
|
union_subject_ptr = entry.ptr;
|
||||||
|
} else {
|
||||||
|
// Non-identifier subject (e.g. function call): spill to temp alloca
|
||||||
|
const val = try self.genExpr(match.subject);
|
||||||
|
const tmp = c.LLVMBuildAlloca(self.builder, info.llvm_type, "match_tmp");
|
||||||
|
_ = c.LLVMBuildStore(self.builder, val, tmp);
|
||||||
|
union_subject_ptr = tmp;
|
||||||
|
}
|
||||||
|
break :blk self.loadStructField(info.llvm_type, union_subject_ptr.?, 0, self.getEnumLLVMType(union_name.?));
|
||||||
} else try self.genExpr(match.subject);
|
} else try self.genExpr(match.subject);
|
||||||
|
|
||||||
const variants: ?[]const []const u8 = if (union_name) |un|
|
const variants: ?[]const []const u8 = if (union_name) |un|
|
||||||
@@ -6630,6 +6628,12 @@ pub const CodeGen = struct {
|
|||||||
for (tag_values) |tag| {
|
for (tag_values) |tag| {
|
||||||
c.LLVMAddCase(sw, c.LLVMConstInt(i64_type, tag, 0), case_bbs.items[i]);
|
c.LLVMAddCase(sw, c.LLVMConstInt(i64_type, tag, 0), case_bbs.items[i]);
|
||||||
}
|
}
|
||||||
|
} else if (pat.data == .int_literal) {
|
||||||
|
const case_val = c.LLVMConstInt(case_int_type, @bitCast(@as(i64, pat.data.int_literal.value)), 0);
|
||||||
|
c.LLVMAddCase(sw, case_val, case_bbs.items[i]);
|
||||||
|
} else if (pat.data == .bool_literal) {
|
||||||
|
const case_val = c.LLVMConstInt(case_int_type, @intFromBool(pat.data.bool_literal.value), 0);
|
||||||
|
c.LLVMAddCase(sw, case_val, case_bbs.items[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6677,8 +6681,7 @@ pub const CodeGen = struct {
|
|||||||
if (vidx) |vi| {
|
if (vidx) |vi| {
|
||||||
const variant_ty = uinfo.variant_types[vi];
|
const variant_ty = uinfo.variant_types[vi];
|
||||||
if (variant_ty != .void_type) {
|
if (variant_ty != .void_type) {
|
||||||
const subject_entry = self.named_values.get(match.subject.data.identifier.name).?;
|
const payload_gep = self.structGEP(uinfo.llvm_type, union_subject_ptr.?, uinfo.payload_field_index, "cap_payload");
|
||||||
const payload_gep = self.structGEP(uinfo.llvm_type, subject_entry.ptr, uinfo.payload_field_index, "cap_payload");
|
|
||||||
const payload_llvm_ty = self.typeToLLVM(variant_ty);
|
const payload_llvm_ty = self.typeToLLVM(variant_ty);
|
||||||
const payload_val = c.LLVMBuildLoad2(self.builder, payload_llvm_ty, payload_gep, "cap_load");
|
const payload_val = c.LLVMBuildLoad2(self.builder, payload_llvm_ty, payload_gep, "cap_load");
|
||||||
const cap_alloca = c.LLVMBuildAlloca(self.builder, payload_llvm_ty, @ptrCast(cap_name.ptr));
|
const cap_alloca = c.LLVMBuildAlloca(self.builder, payload_llvm_ty, @ptrCast(cap_name.ptr));
|
||||||
@@ -7245,9 +7248,11 @@ pub const CodeGen = struct {
|
|||||||
}
|
}
|
||||||
if (obj_ty.isSlice()) {
|
if (obj_ty.isSlice()) {
|
||||||
if (std.mem.eql(u8, fa.field, "len")) return Type.s(64);
|
if (std.mem.eql(u8, fa.field, "len")) return Type.s(64);
|
||||||
|
if (std.mem.eql(u8, fa.field, "ptr")) return .{ .many_pointer_type = .{ .element_name = obj_ty.slice_type.element_name } };
|
||||||
}
|
}
|
||||||
if (obj_ty.isArray()) {
|
if (obj_ty.isArray()) {
|
||||||
if (std.mem.eql(u8, fa.field, "len")) return Type.s(64);
|
if (std.mem.eql(u8, fa.field, "len")) return Type.s(64);
|
||||||
|
if (std.mem.eql(u8, fa.field, "ptr")) return .{ .many_pointer_type = .{ .element_name = obj_ty.array_type.element_name } };
|
||||||
}
|
}
|
||||||
if (obj_ty.isAny()) {
|
if (obj_ty.isAny()) {
|
||||||
if (std.mem.eql(u8, fa.field, "tag")) return Type.s(64);
|
if (std.mem.eql(u8, fa.field, "tag")) return Type.s(64);
|
||||||
@@ -7289,10 +7294,10 @@ pub const CodeGen = struct {
|
|||||||
return obj_ty.vectorElementType() orelse Type.s(64);
|
return obj_ty.vectorElementType() orelse Type.s(64);
|
||||||
}
|
}
|
||||||
if (obj_ty.isArray()) {
|
if (obj_ty.isArray()) {
|
||||||
return Type.fromName(obj_ty.array_type.element_name) orelse Type.s(64);
|
return self.resolveTypeFromName(obj_ty.array_type.element_name) orelse Type.s(64);
|
||||||
}
|
}
|
||||||
if (obj_ty.isSlice()) {
|
if (obj_ty.isSlice()) {
|
||||||
return obj_ty.sliceElementType() orelse Type.s(64);
|
return self.resolveTypeFromName(obj_ty.slice_type.element_name) orelse Type.s(64);
|
||||||
}
|
}
|
||||||
if (obj_ty.isManyPointer()) {
|
if (obj_ty.isManyPointer()) {
|
||||||
return self.resolveTypeFromName(obj_ty.many_pointer_type.element_name) orelse Type.s(64);
|
return self.resolveTypeFromName(obj_ty.many_pointer_type.element_name) orelse Type.s(64);
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
[1.000000, 0.000000, -1.000000]
|
/Volumes/Store/dev/swipelab/sx/examples/14-demo.sx:16:1: error: comptime execution failed: UnsupportedExpression
|
||||||
|
|||||||
@@ -89,7 +89,10 @@ match-expr-else: 99
|
|||||||
capture: 9.500000
|
capture: 9.500000
|
||||||
capture-arrow: 7.500000
|
capture-arrow: 7.500000
|
||||||
else-match: other
|
else-match: other
|
||||||
|
int-match: two
|
||||||
int-match-else: unknown
|
int-match-else: unknown
|
||||||
|
bool-match-t: yes
|
||||||
|
bool-match-f: no
|
||||||
bool: true
|
bool: true
|
||||||
union-f: 3.140000
|
union-f: 3.140000
|
||||||
union-i: 1078523331
|
union-i: 1078523331
|
||||||
@@ -242,4 +245,17 @@ arr swap: 3 1
|
|||||||
3-way: 3 1 2
|
3-way: 3 1 2
|
||||||
=== 15. Foreign ===
|
=== 15. Foreign ===
|
||||||
foreign-rename: 42
|
foreign-rename: 42
|
||||||
|
=== 16. Compound Assign ===
|
||||||
|
f64+=f32: 13.000000
|
||||||
|
s64-=s32: 93
|
||||||
|
=== 17. Slice Ptr ===
|
||||||
|
sl-ptr[0]: 20
|
||||||
|
sl-ptr[1]: 30
|
||||||
|
=== 18. Array of Structs ===
|
||||||
|
arr-struct-x: 3
|
||||||
|
for-struct: Point{x: 1, y: 2}
|
||||||
|
for-struct: Point{x: 3, y: 4}
|
||||||
|
=== 19. Local Fn Return ===
|
||||||
|
local-struct: 42 99
|
||||||
|
local-enum: .circle(2.500000)
|
||||||
=== DONE ===
|
=== DONE ===
|
||||||
|
|||||||
Reference in New Issue
Block a user