aboutsummaryrefslogtreecommitdiff
path: root/src/Module.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-03-29 21:59:08 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-03-29 21:59:08 -0700
commit195ddab2be938c1201767909d39106cdf99fd07e (patch)
treea24f32c4829370474b2319c9bbdd3478974d1bad /src/Module.zig
parent623d5f442c832ec0ea2a07aba73b8e2eae57191c (diff)
downloadzig-195ddab2be938c1201767909d39106cdf99fd07e.tar.gz
zig-195ddab2be938c1201767909d39106cdf99fd07e.zip
Sema: implement switch expressions
The logic for putting ranges into the else prong is moved from AstGen to Sema. However, logic to emit multi-items the same as single-items cannot be done until TZIR supports mapping multiple items to the same block of code. This will be simple to represent when we do the upcoming TZIR memory layout changes. Not yet implemented in this commit is the validation of duplicate values. The trick is going to be emitting error messages with accurate source locations, without adding extra source nodes to the ZIR switch instruction. This will be done by computing the respective AST node based on the switch node (which we do have available), only when a compile error occurs and we need to know the source location to attach the message to.
Diffstat (limited to 'src/Module.zig')
-rw-r--r--src/Module.zig23
1 files changed, 21 insertions, 2 deletions
diff --git a/src/Module.zig b/src/Module.zig
index 3309a10b30..91790aa1b6 100644
--- a/src/Module.zig
+++ b/src/Module.zig
@@ -888,7 +888,7 @@ pub const Scope = struct {
pub fn addSwitchBr(
block: *Scope.Block,
src: LazySrcLoc,
- target: *ir.Inst,
+ operand: *ir.Inst,
cases: []ir.Inst.SwitchBr.Case,
else_body: ir.Body,
) !*ir.Inst {
@@ -899,7 +899,7 @@ pub const Scope = struct {
.ty = Type.initTag(.noreturn),
.src = src,
},
- .target = target,
+ .target = operand,
.cases = cases,
.else_body = else_body,
};
@@ -1533,6 +1533,8 @@ pub const SrcLoc = struct {
.node_offset_bin_lhs,
.node_offset_bin_rhs,
.node_offset_switch_operand,
+ .node_offset_switch_special_prong,
+ .node_offset_switch_range,
=> src_loc.container.decl.container.file_scope,
};
}
@@ -1665,6 +1667,8 @@ pub const SrcLoc = struct {
return token_starts[tok_index];
},
.node_offset_switch_operand => @panic("TODO"),
+ .node_offset_switch_special_prong => @panic("TODO"),
+ .node_offset_switch_range => @panic("TODO"),
}
}
};
@@ -1802,6 +1806,17 @@ pub const LazySrcLoc = union(enum) {
/// which points to a switch expression AST node. Next, nagivate to the operand.
/// The Decl is determined contextually.
node_offset_switch_operand: i32,
+ /// The source location points to the else/`_` prong of a switch expression, found
+ /// by taking this AST node index offset from the containing Decl AST node,
+ /// which points to a switch expression AST node. Next, nagivate to the else/`_` prong.
+ /// The Decl is determined contextually.
+ node_offset_switch_special_prong: i32,
+ /// The source location points to all the ranges of a switch expression, found
+ /// by taking this AST node index offset from the containing Decl AST node,
+ /// which points to a switch expression AST node. Next, nagivate to any of the
+ /// range nodes. The error applies to all of them.
+ /// The Decl is determined contextually.
+ node_offset_switch_range: i32,
/// Upgrade to a `SrcLoc` based on the `Decl` or file in the provided scope.
pub fn toSrcLoc(lazy: LazySrcLoc, scope: *Scope) SrcLoc {
@@ -1836,6 +1851,8 @@ pub const LazySrcLoc = union(enum) {
.node_offset_bin_lhs,
.node_offset_bin_rhs,
.node_offset_switch_operand,
+ .node_offset_switch_special_prong,
+ .node_offset_switch_range,
=> .{
.container = .{ .decl = scope.srcDecl().? },
.lazy = lazy,
@@ -1876,6 +1893,8 @@ pub const LazySrcLoc = union(enum) {
.node_offset_bin_lhs,
.node_offset_bin_rhs,
.node_offset_switch_operand,
+ .node_offset_switch_special_prong,
+ .node_offset_switch_range,
=> .{
.container = .{ .decl = decl },
.lazy = lazy,