Skip to content

Commit 2c85b06

Browse files
committed
Implements lowering without result type for all non container types
1 parent e085e41 commit 2c85b06

File tree

1 file changed

+66
-16
lines changed

1 file changed

+66
-16
lines changed

src/Sema/LowerZon.zig

Lines changed: 66 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ pub fn run(
3333
sema: *Sema,
3434
file: *File,
3535
file_index: Zcu.File.Index,
36-
res_ty: InternPool.Index,
36+
res_ty_interned: InternPool.Index,
3737
import_loc: LazySrcLoc,
3838
block: *Sema.Block,
3939
) CompileError!InternPool.Index {
@@ -53,13 +53,63 @@ pub fn run(
5353
.base_node_inst = tracked_inst,
5454
};
5555

56-
try lower_zon.checkType(.fromInterned(res_ty));
56+
if (res_ty_interned == .none) {
57+
return lower_zon.lowerExprAnonResTy(.root);
58+
} else {
59+
const res_ty: Type = .fromInterned(res_ty_interned);
60+
try lower_zon.checkType(res_ty);
61+
return lower_zon.lowerExprKnownResTy(.root, res_ty);
62+
}
63+
}
5764

58-
return lower_zon.lowerExpr(.root, .fromInterned(res_ty));
65+
fn lowerExprAnonResTy(self: *LowerZon, node: Zoir.Node.Index) CompileError!InternPool.Index {
66+
const gpa = self.sema.gpa;
67+
const ip = &self.sema.pt.zcu.intern_pool;
68+
switch (node.get(self.file.zoir.?)) {
69+
.true => return .bool_true,
70+
.false => return .bool_false,
71+
.null => return .null_value,
72+
.pos_inf => return self.fail(node, "infinity requires a known result type", .{}),
73+
.neg_inf => return self.fail(node, "negative infinity requires a known result type", .{}),
74+
.nan => return self.fail(node, "nan requires a known result type", .{}),
75+
.int_literal => |int| switch (int) {
76+
.small => |val| return self.sema.pt.intern(.{ .int = .{
77+
.ty = .comptime_int_type,
78+
.storage = .{ .i64 = val },
79+
} }),
80+
.big => |val| return self.sema.pt.intern(.{ .int = .{
81+
.ty = .comptime_int_type,
82+
.storage = .{ .big_int = val },
83+
} }),
84+
},
85+
.float_literal => |val| {
86+
const result = try self.sema.pt.floatValue(.fromInterned(.comptime_float_type), val);
87+
return result.toIntern();
88+
},
89+
.char_literal => |val| return self.sema.pt.intern(.{ .int = .{
90+
.ty = .comptime_int_type,
91+
.storage = .{ .i64 = val },
92+
} }),
93+
.enum_literal => |val| return self.sema.pt.intern(.{
94+
.enum_literal = try ip.getOrPutString(
95+
self.sema.gpa,
96+
self.sema.pt.tid,
97+
val.get(self.file.zoir.?),
98+
.no_embedded_nulls,
99+
),
100+
}),
101+
.string_literal => |val| {
102+
const ip_str = try ip.getOrPutString(gpa, self.sema.pt.tid, val, .maybe_embedded_nulls);
103+
const result = try self.sema.addStrLit(ip_str, val.len);
104+
return result.toInterned().?;
105+
},
106+
.empty_literal, .array_literal, .struct_literal => @panic("unimplemented"),
107+
}
59108
}
60109

61-
/// Validate that `ty` is a valid ZON type. If not, emit a compile error.
62-
/// i.e. no nested optionals, no error sets, etc.
110+
/// Validate that `ty` is a valid ZON type, or is `.none`. If it is not, emit a compile error.
111+
///
112+
/// Rules out nested optionals, error sets, etc.
63113
fn checkType(self: *LowerZon, ty: Type) !void {
64114
var visited: std.AutoHashMapUnmanaged(InternPool.Index, void) = .empty;
65115
try self.checkTypeInner(ty, null, &visited);
@@ -201,9 +251,9 @@ fn fail(
201251
return self.sema.failWithOwnedErrorMsg(self.block, err_msg);
202252
}
203253

204-
fn lowerExpr(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) CompileError!InternPool.Index {
254+
fn lowerExprKnownResTy(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) CompileError!InternPool.Index {
205255
const pt = self.sema.pt;
206-
return self.lowerExprInner(node, res_ty) catch |err| switch (err) {
256+
return self.lowerExprKnownResTyInner(node, res_ty) catch |err| switch (err) {
207257
error.WrongType => return self.fail(
208258
node,
209259
"expected type '{}'",
@@ -213,7 +263,7 @@ fn lowerExpr(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) CompileError!
213263
};
214264
}
215265

216-
fn lowerExprInner(
266+
fn lowerExprKnownResTyInner(
217267
self: *LowerZon,
218268
node: Zoir.Node.Index,
219269
res_ty: Type,
@@ -227,7 +277,7 @@ fn lowerExprInner(
227277
break :b .none;
228278
} else b: {
229279
const child_type = res_ty.optionalChild(pt.zcu);
230-
break :b try self.lowerExprInner(node, child_type);
280+
break :b try self.lowerExprKnownResTyInner(node, child_type);
231281
},
232282
},
233283
}),
@@ -239,7 +289,7 @@ fn lowerExprInner(
239289
.base_addr = .{
240290
.uav = .{
241291
.orig_ty = res_ty.toIntern(),
242-
.val = try self.lowerExprInner(node, .fromInterned(ptr_info.child)),
292+
.val = try self.lowerExprKnownResTyInner(node, .fromInterned(ptr_info.child)),
243293
},
244294
},
245295
.byte_offset = 0,
@@ -486,7 +536,7 @@ fn lowerArray(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.
486536
);
487537

488538
for (0..nodes.len) |i| {
489-
elems[i] = try self.lowerExpr(nodes.at(@intCast(i)), array_info.elem_type);
539+
elems[i] = try self.lowerExprKnownResTy(nodes.at(@intCast(i)), array_info.elem_type);
490540
}
491541

492542
if (array_info.sentinel) |sentinel| {
@@ -587,7 +637,7 @@ fn lowerTuple(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.
587637
);
588638
}
589639

590-
const val = try self.lowerExpr(elem_nodes.at(@intCast(i)), .fromInterned(field_types[i]));
640+
const val = try self.lowerExprKnownResTy(elem_nodes.at(@intCast(i)), .fromInterned(field_types[i]));
591641

592642
if (elems[i] != .none and val != elems[i]) {
593643
const elem_node = elem_nodes.at(@intCast(i));
@@ -650,7 +700,7 @@ fn lowerStruct(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool
650700
};
651701

652702
const field_type: Type = .fromInterned(struct_info.field_types.get(ip)[name_index]);
653-
field_values[name_index] = try self.lowerExpr(field_node, field_type);
703+
field_values[name_index] = try self.lowerExprKnownResTy(field_node, field_type);
654704

655705
if (struct_info.comptime_bits.getBit(ip, name_index)) {
656706
const val = ip.indexToKey(field_values[name_index]);
@@ -715,7 +765,7 @@ fn lowerSlice(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.
715765
const elems = try self.sema.arena.alloc(InternPool.Index, elem_nodes.len + @intFromBool(ptr_info.sentinel != .none));
716766

717767
for (elems, 0..) |*elem, i| {
718-
elem.* = try self.lowerExpr(elem_nodes.at(@intCast(i)), .fromInterned(ptr_info.child));
768+
elem.* = try self.lowerExprKnownResTy(elem_nodes.at(@intCast(i)), .fromInterned(ptr_info.child));
719769
}
720770

721771
if (ptr_info.sentinel != .none) {
@@ -810,7 +860,7 @@ fn lowerUnion(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.
810860
if (field_type.toIntern() == .void_type) {
811861
return self.fail(field_node, "expected type 'void'", .{});
812862
}
813-
break :b try self.lowerExpr(field_node, field_type);
863+
break :b try self.lowerExprKnownResTy(field_node, field_type);
814864
} else b: {
815865
if (field_type.toIntern() != .void_type) {
816866
return error.WrongType;
@@ -846,7 +896,7 @@ fn lowerVector(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool
846896
}
847897

848898
for (elems, 0..) |*elem, i| {
849-
elem.* = try self.lowerExpr(elem_nodes.at(@intCast(i)), .fromInterned(vector_info.child));
899+
elem.* = try self.lowerExprKnownResTy(elem_nodes.at(@intCast(i)), .fromInterned(vector_info.child));
850900
}
851901

852902
return self.sema.pt.intern(.{ .aggregate = .{

0 commit comments

Comments
 (0)