mirror of
https://codeberg.org/ziglings/exercises.git
synced 2024-12-26 01:20:30 +00:00
Merge pull request 'Add a new exercise for a labeled switch' (#161) from nm-remarkable/exercises:main into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/161
This commit is contained in:
commit
94b5b4bf4b
4 changed files with 105 additions and 3 deletions
|
@ -88,7 +88,8 @@ that if you update one, you may need to also update the other.
|
||||||
|
|
||||||
### Version Changes
|
### Version Changes
|
||||||
|
|
||||||
Version-0.14.0-dev.1224
|
Version-0.14.0-dev.1573
|
||||||
|
* *2024-09-16* zig 0.14.0-dev.1573 - introduction of labeled switch, see [#21257](https://github.com/ziglang/zig/pull/21257)
|
||||||
* *2024-09-02* zig 0.14.0-dev.1409 - several changes in std.builtin, see [#21225](https://github.com/ziglang/zig/pull/21225)
|
* *2024-09-02* zig 0.14.0-dev.1409 - several changes in std.builtin, see [#21225](https://github.com/ziglang/zig/pull/21225)
|
||||||
* *2024-08-04* zig 0.14.0-dev.1224 - several changes in build system, see [#21115](https://github.com/ziglang/zig/pull/21115)
|
* *2024-08-04* zig 0.14.0-dev.1224 - several changes in build system, see [#21115](https://github.com/ziglang/zig/pull/21115)
|
||||||
* *2024-08-04* zig 0.14.0-dev.839 - several changes in build system, see [#20580](https://github.com/ziglang/zig/pull/20580), [#20600](https://github.com/ziglang/zig/issues/20600)
|
* *2024-08-04* zig 0.14.0-dev.839 - several changes in build system, see [#20580](https://github.com/ziglang/zig/pull/20580), [#20600](https://github.com/ziglang/zig/issues/20600)
|
||||||
|
@ -229,7 +230,7 @@ Zig Core Language
|
||||||
* [X] Bit manipulation
|
* [X] Bit manipulation
|
||||||
* [X] Working with C
|
* [X] Working with C
|
||||||
* [X] Threading
|
* [X] Threading
|
||||||
* [ ] Labeled switch (#21257)
|
* [x] Labeled switch
|
||||||
|
|
||||||
Zig Standard Library
|
Zig Standard Library
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ const print = std.debug.print;
|
||||||
// 1) Getting Started
|
// 1) Getting Started
|
||||||
// 2) Version Changes
|
// 2) Version Changes
|
||||||
comptime {
|
comptime {
|
||||||
const required_zig = "0.14.0-dev.1409";
|
const required_zig = "0.14.0-dev.1573";
|
||||||
const current_zig = builtin.zig_version;
|
const current_zig = builtin.zig_version;
|
||||||
const min_zig = std.SemanticVersion.parse(required_zig) catch unreachable;
|
const min_zig = std.SemanticVersion.parse(required_zig) catch unreachable;
|
||||||
if (current_zig.order(min_zig) == .lt) {
|
if (current_zig.order(min_zig) == .lt) {
|
||||||
|
@ -1197,6 +1197,12 @@ const exercises = [_]Exercise{
|
||||||
\\Successfully Read 18 bytes: It's zigling time!
|
\\Successfully Read 18 bytes: It's zigling time!
|
||||||
,
|
,
|
||||||
},
|
},
|
||||||
|
.{
|
||||||
|
.main_file = "108_labeled_switch.zig",
|
||||||
|
.output =
|
||||||
|
\\The pull request has been merged
|
||||||
|
,
|
||||||
|
},
|
||||||
.{
|
.{
|
||||||
.main_file = "999_the_end.zig",
|
.main_file = "999_the_end.zig",
|
||||||
.output =
|
.output =
|
||||||
|
|
77
exercises/108_labeled_switch.zig
Normal file
77
exercises/108_labeled_switch.zig
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
//
|
||||||
|
// You've heard of while loops in exercises 011,012,013 and 014
|
||||||
|
// You've also heard of switch expressions in exercises 030 and 31.
|
||||||
|
// You've also seen how labels can be used in exercise 063.
|
||||||
|
//
|
||||||
|
// By combining while loops and switch statements with continue and break statements
|
||||||
|
// one can create very concise State Machines.
|
||||||
|
//
|
||||||
|
// One such example would be:
|
||||||
|
//
|
||||||
|
// pub fn main() void {
|
||||||
|
// var op: u8 = 1;
|
||||||
|
// while (true) {
|
||||||
|
// switch (op) {
|
||||||
|
// 1 => { op = 2; continue; },
|
||||||
|
// 2 => { op = 3; continue; },
|
||||||
|
// 3 => return,
|
||||||
|
// 4 => {},
|
||||||
|
// }
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// std.debug.print("This statement cannot be reached");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// By combining all we've learned so far, we can now proceed with a labeled switch
|
||||||
|
//
|
||||||
|
// A labeled switch is some extra syntatic sugar, which comes with all sorts of
|
||||||
|
// candy (performance benefits). Don't believe me? Directly to source https://github.com/ziglang/zig/pull/21367
|
||||||
|
//
|
||||||
|
// Here is the previous excerpt implemented as a labeled switch instead:
|
||||||
|
//
|
||||||
|
// pub fn main() void {
|
||||||
|
// foo: switch (@as(u8, 1)) {
|
||||||
|
// 1 => continue :foo 2,
|
||||||
|
// 2 => continue :foo 3,
|
||||||
|
// 3 => return,
|
||||||
|
// 4 => {},
|
||||||
|
// }
|
||||||
|
// std.debug.print("This statement cannot be reached");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// The flow of execution on this second case is:
|
||||||
|
// 1. The switch starts with value '1';
|
||||||
|
// 2. The switch evaluates to case '1' which in turn uses the continue statement
|
||||||
|
// to re-evaluate the labeled switch again, now providing the value '2';
|
||||||
|
// 3. In the case '2' we repeat the same pattern as case '1'
|
||||||
|
// but instead the value to be evaluated is now '3';
|
||||||
|
// 4. Finally we get to case '3', where we return from the function as a whole.
|
||||||
|
//
|
||||||
|
// Since step 4 or a break stament do not exist in this switch, the debug statement is
|
||||||
|
// never executed
|
||||||
|
//
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const PullRequestState = enum(u8) {
|
||||||
|
Draft,
|
||||||
|
InReview,
|
||||||
|
Approved,
|
||||||
|
Rejected,
|
||||||
|
Merged,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn main() void {
|
||||||
|
// Oh no, your pull request keeps being rejected,
|
||||||
|
// how would you fix it?
|
||||||
|
pr: switch (@as(PullRequestState, PullRequestState.Draft)) {
|
||||||
|
PullRequestState.Draft => continue :pr PullRequestState.InReview,
|
||||||
|
PullRequestState.InReview => continue :pr PullRequestState.Rejected,
|
||||||
|
PullRequestState.Approved => continue :pr PullRequestState.Merged,
|
||||||
|
PullRequestState.Rejected => {
|
||||||
|
std.debug.print("The pull request has been rejected", .{});
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
PullRequestState.Merged => break, // Would you know where to break to?
|
||||||
|
}
|
||||||
|
std.debug.print("The pull request has been merged", .{});
|
||||||
|
}
|
18
patches/patches/108_labeled_switch.patch
Normal file
18
patches/patches/108_labeled_switch.patch
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
--- a/exercises/108_labeled_switch.zig
|
||||||
|
+++ b/exercises/108_labeled_switch.zig
|
||||||
|
@@ -65,13 +65,13 @@ pub fn main() void {
|
||||||
|
// how would you fix it?
|
||||||
|
pr: switch (@as(PullRequestState, PullRequestState.Draft)) {
|
||||||
|
PullRequestState.Draft => continue :pr PullRequestState.InReview,
|
||||||
|
- PullRequestState.InReview => continue :pr PullRequestState.Rejected,
|
||||||
|
+ PullRequestState.InReview => continue :pr PullRequestState.Approved,
|
||||||
|
PullRequestState.Approved => continue :pr PullRequestState.Merged,
|
||||||
|
PullRequestState.Rejected => {
|
||||||
|
std.debug.print("The pull request has been rejected", .{});
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
- PullRequestState.Merged => break, // Would you know where to break to?
|
||||||
|
+ PullRequestState.Merged => break :pr, // Would you know where to break to?
|
||||||
|
}
|
||||||
|
std.debug.print("The pull request has been merged", .{});
|
||||||
|
}
|
Loading…
Reference in a new issue