diff options
-rw-r--r-- | README.md | 16 | ||||
-rw-r--r-- | build.zig | 145 | ||||
-rw-r--r-- | exercises/001_hello.zig (renamed from exercises/01_hello.zig) | 0 | ||||
-rw-r--r-- | exercises/002_std.zig (renamed from exercises/02_std.zig) | 0 | ||||
-rw-r--r-- | exercises/003_assignment.zig (renamed from exercises/03_assignment.zig) | 0 | ||||
-rw-r--r-- | exercises/004_arrays.zig (renamed from exercises/04_arrays.zig) | 0 | ||||
-rw-r--r-- | exercises/005_arrays2.zig (renamed from exercises/05_arrays2.zig) | 0 | ||||
-rw-r--r-- | exercises/006_strings.zig (renamed from exercises/06_strings.zig) | 0 | ||||
-rw-r--r-- | exercises/007_strings2.zig (renamed from exercises/07_strings2.zig) | 0 | ||||
-rw-r--r-- | exercises/008_quiz.zig (renamed from exercises/08_quiz.zig) | 0 | ||||
-rw-r--r-- | exercises/009_if.zig (renamed from exercises/09_if.zig) | 0 | ||||
-rw-r--r-- | exercises/010_if2.zig (renamed from exercises/10_if2.zig) | 0 | ||||
-rw-r--r-- | exercises/011_while.zig (renamed from exercises/11_while.zig) | 0 | ||||
-rw-r--r-- | exercises/012_while2.zig (renamed from exercises/12_while2.zig) | 0 | ||||
-rw-r--r-- | exercises/013_while3.zig (renamed from exercises/13_while3.zig) | 0 | ||||
-rw-r--r-- | exercises/014_while4.zig (renamed from exercises/14_while4.zig) | 0 | ||||
-rw-r--r-- | exercises/015_for.zig (renamed from exercises/15_for.zig) | 0 | ||||
-rw-r--r-- | exercises/016_for2.zig (renamed from exercises/16_for2.zig) | 0 | ||||
-rw-r--r-- | exercises/017_quiz2.zig (renamed from exercises/17_quiz2.zig) | 0 | ||||
-rw-r--r-- | exercises/018_functions.zig (renamed from exercises/18_functions.zig) | 0 | ||||
-rw-r--r-- | exercises/019_functions2.zig (renamed from exercises/19_functions2.zig) | 0 | ||||
-rw-r--r-- | exercises/020_quiz3.zig (renamed from exercises/20_quiz3.zig) | 0 | ||||
-rw-r--r-- | exercises/021_errors.zig (renamed from exercises/21_errors.zig) | 0 | ||||
-rw-r--r-- | exercises/022_errors2.zig (renamed from exercises/22_errors2.zig) | 6 | ||||
-rw-r--r-- | exercises/023_errors3.zig (renamed from exercises/23_errors3.zig) | 0 | ||||
-rw-r--r-- | exercises/024_errors4.zig (renamed from exercises/24_errors4.zig) | 0 | ||||
-rw-r--r-- | exercises/025_errors5.zig (renamed from exercises/25_errors5.zig) | 0 | ||||
-rw-r--r-- | exercises/026_hello2.zig (renamed from exercises/26_hello2.zig) | 0 | ||||
-rw-r--r-- | exercises/027_defer.zig (renamed from exercises/27_defer.zig) | 0 | ||||
-rw-r--r-- | exercises/028_defer2.zig (renamed from exercises/28_defer2.zig) | 0 | ||||
-rw-r--r-- | exercises/029_errdefer.zig (renamed from exercises/29_errdefer.zig) | 0 | ||||
-rw-r--r-- | exercises/030_switch.zig (renamed from exercises/30_switch.zig) | 0 | ||||
-rw-r--r-- | exercises/031_switch2.zig (renamed from exercises/31_switch2.zig) | 0 | ||||
-rw-r--r-- | exercises/032_unreachable.zig (renamed from exercises/32_unreachable.zig) | 0 | ||||
-rw-r--r-- | exercises/033_iferror.zig (renamed from exercises/33_iferror.zig) | 0 | ||||
-rw-r--r-- | exercises/034_quiz4.zig (renamed from exercises/34_quiz4.zig) | 0 | ||||
-rw-r--r-- | exercises/035_enums.zig (renamed from exercises/35_enums.zig) | 0 | ||||
-rw-r--r-- | exercises/036_enums2.zig (renamed from exercises/36_enums2.zig) | 0 | ||||
-rw-r--r-- | exercises/037_structs.zig (renamed from exercises/37_structs.zig) | 0 | ||||
-rw-r--r-- | exercises/038_structs2.zig (renamed from exercises/38_structs2.zig) | 0 | ||||
-rw-r--r-- | exercises/039_pointers.zig (renamed from exercises/39_pointers.zig) | 0 | ||||
-rw-r--r-- | exercises/040_pointers2.zig (renamed from exercises/40_pointers2.zig) | 0 | ||||
-rw-r--r-- | exercises/041_pointers3.zig (renamed from exercises/41_pointers3.zig) | 0 | ||||
-rw-r--r-- | exercises/042_pointers4.zig (renamed from exercises/42_pointers4.zig) | 0 | ||||
-rw-r--r-- | exercises/043_pointers5.zig (renamed from exercises/43_pointers5.zig) | 0 | ||||
-rw-r--r-- | exercises/044_quiz5.zig (renamed from exercises/44_quiz5.zig) | 0 | ||||
-rw-r--r-- | exercises/045_optionals.zig (renamed from exercises/45_optionals.zig) | 0 | ||||
-rw-r--r-- | exercises/046_optionals2.zig (renamed from exercises/46_optionals2.zig) | 0 | ||||
-rw-r--r-- | exercises/047_methods.zig (renamed from exercises/47_methods.zig) | 0 | ||||
-rw-r--r-- | exercises/048_methods2.zig (renamed from exercises/48_methods2.zig) | 4 | ||||
-rw-r--r-- | exercises/049_quiz6.zig (renamed from exercises/49_quiz6.zig) | 0 | ||||
-rw-r--r-- | exercises/050_no_value.zig (renamed from exercises/50_no_value.zig) | 0 | ||||
-rw-r--r-- | exercises/051_values.zig (renamed from exercises/51_values.zig) | 0 | ||||
-rw-r--r-- | exercises/052_slices.zig | 49 | ||||
-rw-r--r-- | exercises/053_slices2.zig | 35 | ||||
-rw-r--r-- | exercises/054_manypointers.zig | 55 | ||||
-rw-r--r-- | exercises/055_unions.zig | 76 | ||||
-rw-r--r-- | exercises/056_unions2.zig | 64 | ||||
-rw-r--r-- | exercises/057_unions3.zig | 54 | ||||
-rwxr-xr-x | patches/eowyn.sh | 27 | ||||
-rwxr-xr-x | patches/gollum.sh | 23 | ||||
-rw-r--r-- | patches/patches/001_hello.patch (renamed from patches/patches/01_hello.patch) | 0 | ||||
-rw-r--r-- | patches/patches/002_std.patch (renamed from patches/patches/02_std.patch) | 0 | ||||
-rw-r--r-- | patches/patches/003_assignment.patch (renamed from patches/patches/03_assignment.patch) | 0 | ||||
-rw-r--r-- | patches/patches/004_arrays.patch (renamed from patches/patches/04_arrays.patch) | 0 | ||||
-rw-r--r-- | patches/patches/005_arrays2.patch (renamed from patches/patches/05_arrays2.patch) | 0 | ||||
-rw-r--r-- | patches/patches/006_strings.patch (renamed from patches/patches/06_strings.patch) | 0 | ||||
-rw-r--r-- | patches/patches/007_strings2.patch (renamed from patches/patches/07_strings2.patch) | 0 | ||||
-rw-r--r-- | patches/patches/008_quiz.patch (renamed from patches/patches/08_quiz.patch) | 0 | ||||
-rw-r--r-- | patches/patches/009_if.patch (renamed from patches/patches/09_if.patch) | 0 | ||||
-rw-r--r-- | patches/patches/010_if2.patch (renamed from patches/patches/10_if2.patch) | 0 | ||||
-rw-r--r-- | patches/patches/011_while.patch (renamed from patches/patches/11_while.patch) | 0 | ||||
-rw-r--r-- | patches/patches/012_while2.patch (renamed from patches/patches/12_while2.patch) | 0 | ||||
-rw-r--r-- | patches/patches/013_while3.patch (renamed from patches/patches/13_while3.patch) | 0 | ||||
-rw-r--r-- | patches/patches/014_while4.patch (renamed from patches/patches/14_while4.patch) | 0 | ||||
-rw-r--r-- | patches/patches/015_for.patch (renamed from patches/patches/15_for.patch) | 0 | ||||
-rw-r--r-- | patches/patches/016_for2.patch (renamed from patches/patches/16_for2.patch) | 0 | ||||
-rw-r--r-- | patches/patches/017_quiz2.patch (renamed from patches/patches/17_quiz2.patch) | 0 | ||||
-rw-r--r-- | patches/patches/018_functions.patch (renamed from patches/patches/18_functions.patch) | 0 | ||||
-rw-r--r-- | patches/patches/019_functions2.patch (renamed from patches/patches/19_functions2.patch) | 0 | ||||
-rw-r--r-- | patches/patches/020_quiz3.patch (renamed from patches/patches/20_quiz3.patch) | 0 | ||||
-rw-r--r-- | patches/patches/021_errors.patch (renamed from patches/patches/21_errors.patch) | 0 | ||||
-rw-r--r-- | patches/patches/022_errors2.patch (renamed from patches/patches/22_errors2.patch) | 0 | ||||
-rw-r--r-- | patches/patches/023_errors3.patch (renamed from patches/patches/23_errors3.patch) | 0 | ||||
-rw-r--r-- | patches/patches/024_errors4.patch (renamed from patches/patches/24_errors4.patch) | 0 | ||||
-rw-r--r-- | patches/patches/025_errors5.patch (renamed from patches/patches/25_errors5.patch) | 0 | ||||
-rw-r--r-- | patches/patches/026_hello2.patch (renamed from patches/patches/26_hello2.patch) | 0 | ||||
-rw-r--r-- | patches/patches/027_defer.patch (renamed from patches/patches/27_defer.patch) | 0 | ||||
-rw-r--r-- | patches/patches/028_defer2.patch (renamed from patches/patches/28_defer2.patch) | 0 | ||||
-rw-r--r-- | patches/patches/029_errdefer.patch (renamed from patches/patches/29_errdefer.patch) | 0 | ||||
-rw-r--r-- | patches/patches/030_switch.patch (renamed from patches/patches/30_switch.patch) | 0 | ||||
-rw-r--r-- | patches/patches/031_switch2.patch (renamed from patches/patches/31_switch2.patch) | 0 | ||||
-rw-r--r-- | patches/patches/032_unreachable.patch (renamed from patches/patches/32_unreachable.patch) | 0 | ||||
-rw-r--r-- | patches/patches/033_iferror.patch (renamed from patches/patches/33_iferror.patch) | 0 | ||||
-rw-r--r-- | patches/patches/034_quiz4.patch (renamed from patches/patches/34_quiz4.patch) | 0 | ||||
-rw-r--r-- | patches/patches/035_enums.patch (renamed from patches/patches/35_enums.patch) | 0 | ||||
-rw-r--r-- | patches/patches/036_enums2.patch (renamed from patches/patches/36_enums2.patch) | 0 | ||||
-rw-r--r-- | patches/patches/037_structs.patch (renamed from patches/patches/37_structs.patch) | 0 | ||||
-rw-r--r-- | patches/patches/038_structs2.patch (renamed from patches/patches/38_structs2.patch) | 0 | ||||
-rw-r--r-- | patches/patches/039_pointers.patch (renamed from patches/patches/39_pointers.patch) | 0 | ||||
-rw-r--r-- | patches/patches/040_pointers2.patch (renamed from patches/patches/40_pointers2.patch) | 0 | ||||
-rw-r--r-- | patches/patches/041_pointers3.patch (renamed from patches/patches/41_pointers3.patch) | 0 | ||||
-rw-r--r-- | patches/patches/042_pointers4.patch (renamed from patches/patches/42_pointers4.patch) | 0 | ||||
-rw-r--r-- | patches/patches/043_pointers5.patch (renamed from patches/patches/43_pointers5.patch) | 0 | ||||
-rw-r--r-- | patches/patches/044_quiz5.patch (renamed from patches/patches/44_quiz5.patch) | 0 | ||||
-rw-r--r-- | patches/patches/045_optionals.patch (renamed from patches/patches/45_optionals.patch) | 0 | ||||
-rw-r--r-- | patches/patches/046_optionals2.patch (renamed from patches/patches/46_optionals2.patch) | 0 | ||||
-rw-r--r-- | patches/patches/047_methods.patch (renamed from patches/patches/47_methods.patch) | 0 | ||||
-rw-r--r-- | patches/patches/048_methods2.patch (renamed from patches/patches/48_methods2.patch) | 0 | ||||
-rw-r--r-- | patches/patches/049_quiz6.patch (renamed from patches/patches/49_quiz6.patch) | 0 | ||||
-rw-r--r-- | patches/patches/050_no_value.patch (renamed from patches/patches/50_no_value.patch) | 0 | ||||
-rw-r--r-- | patches/patches/051_values.patch (renamed from patches/patches/51_values.patch) | 0 | ||||
-rw-r--r-- | patches/patches/052_slices.patch | 10 | ||||
-rw-r--r-- | patches/patches/053_slices2.patch | 20 | ||||
-rw-r--r-- | patches/patches/054_manypointers.patch | 4 | ||||
-rw-r--r-- | patches/patches/055_unions.patch | 6 | ||||
-rw-r--r-- | patches/patches/056_unions2.patch | 10 | ||||
-rw-r--r-- | patches/patches/057_unions3.patch | 4 |
118 files changed, 518 insertions, 90 deletions
@@ -14,7 +14,7 @@ sweet of you.) This project was directly inspired by the brilliant and fun [rustlings](https://github.com/rust-lang/rustlings) project for the [Rust](https://www.rust-lang.org/) language. -Indirect inspiration comes from [Ruby Koans]( http://rubykoans.com/) +Indirect inspiration comes from [Ruby Koans](http://rubykoans.com/) and the Little LISPer/Little Schemer series of books. ## Intended Audience @@ -30,6 +30,8 @@ to also check out these Zig language resources for more detail: * https://ziglearn.org/ * https://ziglang.org/documentation/master/ +Also, the [Zig community](https://github.com/ziglang/zig/wiki/Community) is incredibly friendly and helpful! + ## Getting Started Install a [development build](https://ziglang.org/download/) of the Zig compiler. @@ -82,21 +84,21 @@ zig build 19_start You can also run without checking for correctness: ```bash -zig build 01_test +zig build 19_test ``` Or skip the build system entirely and interact directly with the compiler if you're into that sort of thing: ```bash -zig run exercises/01_hello.zig +zig run exercises/001_hello.zig ``` Calling all wizards: To prepare an executable for debugging, install it to zig-cache/bin with: ```bash -zig build 01_install +zig build 19_install ``` ## TODO @@ -128,9 +130,9 @@ Planned exercises: * [x] Pointers * [x] Optionals * [x] Struct methods -* [ ] Slices -* [ ] Multi pointers -* [ ] Unions +* [x] Slices +* [x] Many pointers +* [x] Unions * [ ] Numeric types (integers, floats) * [ ] Labelled blocks and loops * [ ] Loops as expressions @@ -27,248 +27,280 @@ const Exercise = struct { return self.main_file[0 .. self.main_file.len - 4]; } - /// Returns the key of the main file, which is the text before the _. - /// For example, "01_hello.zig" has the key "01". + /// Returns the key of the main file, the string before the '_' with + /// "zero padding" removed. + /// For example, "001_hello.zig" has the key "1". pub fn key(self: Exercise) []const u8 { const end_index = std.mem.indexOfScalar(u8, self.main_file, '_'); assert(end_index != null); // main file must be key_description.zig - return self.main_file[0..end_index.?]; + + // remove zero padding by advancing index past '0's + var start_index: usize = 0; + while (self.main_file[start_index] == '0') start_index += 1; + return self.main_file[start_index..end_index.?]; } }; const exercises = [_]Exercise{ .{ - .main_file = "01_hello.zig", + .main_file = "001_hello.zig", .output = "Hello world", .hint = "DON'T PANIC!\nRead the error above.\nSee how it has something to do with 'main'?\nOpen up the source file as noted and read the comments.\nYou can do this!", }, .{ - .main_file = "02_std.zig", + .main_file = "002_std.zig", .output = "Standard Library", }, .{ - .main_file = "03_assignment.zig", + .main_file = "003_assignment.zig", .output = "55 314159 -11", .hint = "There are three mistakes in this one!", }, .{ - .main_file = "04_arrays.zig", + .main_file = "004_arrays.zig", .output = "Fourth: 7, Length: 8", .hint = "There are two things to complete here.", }, .{ - .main_file = "05_arrays2.zig", + .main_file = "005_arrays2.zig", .output = "LEET: 1337, Bits: 100110011001", .hint = "Fill in the two arrays.", }, .{ - .main_file = "06_strings.zig", + .main_file = "006_strings.zig", .output = "d=d ha ha ha Major Tom", .hint = "Each '???' needs something filled in.", }, .{ - .main_file = "07_strings2.zig", + .main_file = "007_strings2.zig", .output = "Ziggy", .hint = "Please fix the lyrics!", }, .{ - .main_file = "08_quiz.zig", + .main_file = "008_quiz.zig", .output = "Program in Zig", .hint = "See if you can fix the program!", }, .{ - .main_file = "09_if.zig", + .main_file = "009_if.zig", .output = "Foo is 1!", }, .{ - .main_file = "10_if2.zig", + .main_file = "010_if2.zig", .output = "price is $17", }, .{ - .main_file = "11_while.zig", + .main_file = "011_while.zig", .output = "n=1024", .hint = "You probably want a 'less than' condition.", }, .{ - .main_file = "12_while2.zig", + .main_file = "012_while2.zig", .output = "n=1024", .hint = "It might help to look back at the previous exercise.", }, .{ - .main_file = "13_while3.zig", + .main_file = "013_while3.zig", .output = "1 2 4 7 8 11 13 14 16 17 19", }, .{ - .main_file = "14_while4.zig", + .main_file = "014_while4.zig", .output = "n=4", }, .{ - .main_file = "15_for.zig", + .main_file = "015_for.zig", .output = "A Dramatic Story: :-) :-) :-( :-| :-) The End.", }, .{ - .main_file = "16_for2.zig", + .main_file = "016_for2.zig", .output = "13", }, .{ - .main_file = "17_quiz2.zig", + .main_file = "017_quiz2.zig", .output = "8, Fizz, Buzz, 11, Fizz, 13, 14, FizzBuzz, 16", .hint = "This is a famous game!", }, .{ - .main_file = "18_functions.zig", + .main_file = "018_functions.zig", .output = "Question: 42", .hint = "Can you help write the function?", }, .{ - .main_file = "19_functions2.zig", + .main_file = "019_functions2.zig", .output = "2 4 8 16", }, .{ - .main_file = "20_quiz3.zig", + .main_file = "020_quiz3.zig", .output = "32 64 128 256", .hint = "Unexpected pop quiz! Help!", }, .{ - .main_file = "21_errors.zig", + .main_file = "021_errors.zig", .output = "2<4. 3<4. 4=4. 5>4. 6>4.", .hint = "What's the deal with fours?", }, .{ - .main_file = "22_errors2.zig", + .main_file = "022_errors2.zig", .output = "I compiled", .hint = "Get the error union type right to allow this to compile.", }, .{ - .main_file = "23_errors3.zig", + .main_file = "023_errors3.zig", .output = "a=64, b=22", }, .{ - .main_file = "24_errors4.zig", + .main_file = "024_errors4.zig", .output = "a=20, b=14, c=10", }, .{ - .main_file = "25_errors5.zig", + .main_file = "025_errors5.zig", .output = "a=0, b=19, c=0", }, .{ - .main_file = "26_hello2.zig", + .main_file = "026_hello2.zig", .output = "Hello world", .hint = "Try using a try!", .check_stdout = true, }, .{ - .main_file = "27_defer.zig", + .main_file = "027_defer.zig", .output = "One Two", }, .{ - .main_file = "28_defer2.zig", + .main_file = "028_defer2.zig", .output = "(Goat) (Cat) (Dog) (Dog) (Goat) (Unknown) done.", }, .{ - .main_file = "29_errdefer.zig", + .main_file = "029_errdefer.zig", .output = "Getting number...got 5. Getting number...failed!", }, .{ - .main_file = "30_switch.zig", + .main_file = "030_switch.zig", .output = "ZIG?", }, .{ - .main_file = "31_switch2.zig", + .main_file = "031_switch2.zig", .output = "ZIG!", }, .{ - .main_file = "32_unreachable.zig", + .main_file = "032_unreachable.zig", .output = "1 2 3 9 8 7", }, .{ - .main_file = "33_iferror.zig", + .main_file = "033_iferror.zig", .output = "2<4. 3<4. 4=4. 5>4. 6>4.", .hint = "Seriously, what's the deal with fours?", }, .{ - .main_file = "34_quiz4.zig", + .main_file = "034_quiz4.zig", .output = "my_num=42", .hint = "Can you make this work?", .check_stdout = true, }, .{ - .main_file = "35_enums.zig", + .main_file = "035_enums.zig", .output = "1 2 3 9 8 7", .hint = "This problem seems familiar...", }, .{ - .main_file = "36_enums2.zig", + .main_file = "036_enums2.zig", .output = "#0000ff", .hint = "I'm feeling blue about this.", }, .{ - .main_file = "37_structs.zig", + .main_file = "037_structs.zig", .output = "Your wizard has 90 health and 25 gold.", }, .{ - .main_file = "38_structs2.zig", + .main_file = "038_structs2.zig", .output = "Character 2 - G:10 H:100 XP:20", }, .{ - .main_file = "39_pointers.zig", + .main_file = "039_pointers.zig", .output = "num1: 5, num2: 5", .hint = "Pointers aren't so bad.", }, .{ - .main_file = "40_pointers2.zig", + .main_file = "040_pointers2.zig", .output = "a: 12, b: 12", }, .{ - .main_file = "41_pointers3.zig", + .main_file = "041_pointers3.zig", .output = "foo=6, bar=11", }, .{ - .main_file = "42_pointers4.zig", + .main_file = "042_pointers4.zig", .output = "num: 5, more_nums: 1 1 5 1", }, .{ - .main_file = "43_pointers5.zig", + .main_file = "043_pointers5.zig", .output = "Wizard (G:10 H:100 XP:20)", }, .{ - .main_file = "44_quiz5.zig", + .main_file = "044_quiz5.zig", .output = "Elephant A. Elephant B. Elephant C.", .hint = "Oh no! We forgot Elephant B!", }, .{ - .main_file = "45_optionals.zig", + .main_file = "045_optionals.zig", .output = "The Ultimate Answer: 42.", }, .{ - .main_file = "46_optionals2.zig", + .main_file = "046_optionals2.zig", .output = "Elephant A. Elephant B. Elephant C.", .hint = "Elephants again!", }, .{ - .main_file = "47_methods.zig", + .main_file = "047_methods.zig", .output = "5 aliens. 4 aliens. 1 aliens. 0 aliens. Earth is saved!", .hint = "Use the heat ray. And the method!", }, .{ - .main_file = "48_methods2.zig", + .main_file = "048_methods2.zig", .output = "A B C", .hint = "This just needs one little fix.", }, .{ - .main_file = "49_quiz6.zig", + .main_file = "049_quiz6.zig", .output = "A B C Cv Bv Av", .hint = "Now you're writting Zig!", }, .{ - .main_file = "50_no_value.zig", + .main_file = "050_no_value.zig", .output = "That is not dead which can eternal lie / And with strange aeons even death may die.", }, .{ - .main_file = "51_values.zig", + .main_file = "051_values.zig", .output = "1:false!. 2:true!. 3:true!. XP before:0, after:200.", }, - // 52 slices! + .{ + .main_file = "052_slices.zig", + .output = "Hand1: A 4 K 8 Hand2: 5 2 Q J", + }, + .{ + .main_file = "053_slices2.zig", + .output = "'all your base are belong to us.' 'for great justice.'", + }, + .{ + .main_file = "054_manypointers.zig", + .output = "Memory is a resource.", + }, + .{ + .main_file = "055_unions.zig", + .output = "Insect report! Ant alive is: true. Bee visited 15 flowers.", + }, + .{ + .main_file = "056_unions2.zig", + .output = "Insect report! Ant alive is: true. Bee visited 16 flowers.", + }, + .{ + .main_file = "057_unions3.zig", + .output = "Insect report! Ant alive is: true. Bee visited 17 flowers.", + }, + .{ + .main_file = "057_unions3.zig", + .output = "Insect report! Ant alive is: true. Bee visited 17 flowers.", + }, }; /// Check the zig version to make sure it can compile the examples properly. @@ -525,8 +557,7 @@ const ZiglingStep = struct { zig_args.append(@tagName(builder.color)) catch unreachable; } - const zig_file = std.fs.path.join(builder.allocator, &[_][]const u8{ - if (self.use_healed) "patches/healed" else "exercises", self.exercise.main_file }) catch unreachable; + const zig_file = std.fs.path.join(builder.allocator, &[_][]const u8{ if (self.use_healed) "patches/healed" else "exercises", self.exercise.main_file }) catch unreachable; zig_args.append(builder.pathFromRoot(zig_file)) catch unreachable; zig_args.append("--cache-dir") catch unreachable; diff --git a/exercises/01_hello.zig b/exercises/001_hello.zig index d2093c7..d2093c7 100644 --- a/exercises/01_hello.zig +++ b/exercises/001_hello.zig diff --git a/exercises/02_std.zig b/exercises/002_std.zig index 50059e1..50059e1 100644 --- a/exercises/02_std.zig +++ b/exercises/002_std.zig diff --git a/exercises/03_assignment.zig b/exercises/003_assignment.zig index 6a4364b..6a4364b 100644 --- a/exercises/03_assignment.zig +++ b/exercises/003_assignment.zig diff --git a/exercises/04_arrays.zig b/exercises/004_arrays.zig index 88fcc78..88fcc78 100644 --- a/exercises/04_arrays.zig +++ b/exercises/004_arrays.zig diff --git a/exercises/05_arrays2.zig b/exercises/005_arrays2.zig index 9282a31..9282a31 100644 --- a/exercises/05_arrays2.zig +++ b/exercises/005_arrays2.zig diff --git a/exercises/06_strings.zig b/exercises/006_strings.zig index 6258816..6258816 100644 --- a/exercises/06_strings.zig +++ b/exercises/006_strings.zig diff --git a/exercises/07_strings2.zig b/exercises/007_strings2.zig index 6350be1..6350be1 100644 --- a/exercises/07_strings2.zig +++ b/exercises/007_strings2.zig diff --git a/exercises/08_quiz.zig b/exercises/008_quiz.zig index eda66b8..eda66b8 100644 --- a/exercises/08_quiz.zig +++ b/exercises/008_quiz.zig diff --git a/exercises/09_if.zig b/exercises/009_if.zig index 284563d..284563d 100644 --- a/exercises/09_if.zig +++ b/exercises/009_if.zig diff --git a/exercises/10_if2.zig b/exercises/010_if2.zig index d0c8cac..d0c8cac 100644 --- a/exercises/10_if2.zig +++ b/exercises/010_if2.zig diff --git a/exercises/11_while.zig b/exercises/011_while.zig index 674d904..674d904 100644 --- a/exercises/11_while.zig +++ b/exercises/011_while.zig diff --git a/exercises/12_while2.zig b/exercises/012_while2.zig index ef53ea0..ef53ea0 100644 --- a/exercises/12_while2.zig +++ b/exercises/012_while2.zig diff --git a/exercises/13_while3.zig b/exercises/013_while3.zig index 4cccf62..4cccf62 100644 --- a/exercises/13_while3.zig +++ b/exercises/013_while3.zig diff --git a/exercises/14_while4.zig b/exercises/014_while4.zig index 7b2714e..7b2714e 100644 --- a/exercises/14_while4.zig +++ b/exercises/014_while4.zig diff --git a/exercises/15_for.zig b/exercises/015_for.zig index 2ce930e..2ce930e 100644 --- a/exercises/15_for.zig +++ b/exercises/015_for.zig diff --git a/exercises/16_for2.zig b/exercises/016_for2.zig index 0a62a1a..0a62a1a 100644 --- a/exercises/16_for2.zig +++ b/exercises/016_for2.zig diff --git a/exercises/17_quiz2.zig b/exercises/017_quiz2.zig index 7de7010..7de7010 100644 --- a/exercises/17_quiz2.zig +++ b/exercises/017_quiz2.zig diff --git a/exercises/18_functions.zig b/exercises/018_functions.zig index 51be2cd..51be2cd 100644 --- a/exercises/18_functions.zig +++ b/exercises/018_functions.zig diff --git a/exercises/19_functions2.zig b/exercises/019_functions2.zig index 00f33c5..00f33c5 100644 --- a/exercises/19_functions2.zig +++ b/exercises/019_functions2.zig diff --git a/exercises/20_quiz3.zig b/exercises/020_quiz3.zig index 651af8c..651af8c 100644 --- a/exercises/20_quiz3.zig +++ b/exercises/020_quiz3.zig diff --git a/exercises/21_errors.zig b/exercises/021_errors.zig index cbb5ac8..cbb5ac8 100644 --- a/exercises/21_errors.zig +++ b/exercises/021_errors.zig diff --git a/exercises/22_errors2.zig b/exercises/022_errors2.zig index fa0eafa..7bf00d4 100644 --- a/exercises/22_errors2.zig +++ b/exercises/022_errors2.zig @@ -2,15 +2,15 @@ // A common case for errors is a situation where we're expecting to // have a value OR something has gone wrong. Take this example: // -// var text: Text = getText('foo.txt'); +// var text: Text = getText("foo.txt"); // -// What happens if getText() can't find 'foo.txt'? How do we express +// What happens if getText() can't find "foo.txt"? How do we express // this in Zig? // // Zig lets us make what's called an "error union" which is a value // which could either be a regular value OR an error from a set: // -// var text: MyErrorSet!Text = getText('foo.txt'); +// var text: MyErrorSet!Text = getText("foo.txt"); // // For now, let's just see if we can try making an error union! // diff --git a/exercises/23_errors3.zig b/exercises/023_errors3.zig index a465737..a465737 100644 --- a/exercises/23_errors3.zig +++ b/exercises/023_errors3.zig diff --git a/exercises/24_errors4.zig b/exercises/024_errors4.zig index 560b129..560b129 100644 --- a/exercises/24_errors4.zig +++ b/exercises/024_errors4.zig diff --git a/exercises/25_errors5.zig b/exercises/025_errors5.zig index 5119dcf..5119dcf 100644 --- a/exercises/25_errors5.zig +++ b/exercises/025_errors5.zig diff --git a/exercises/26_hello2.zig b/exercises/026_hello2.zig index 237d27c..237d27c 100644 --- a/exercises/26_hello2.zig +++ b/exercises/026_hello2.zig diff --git a/exercises/27_defer.zig b/exercises/027_defer.zig index b41e2af..b41e2af 100644 --- a/exercises/27_defer.zig +++ b/exercises/027_defer.zig diff --git a/exercises/28_defer2.zig b/exercises/028_defer2.zig index 6943012..6943012 100644 --- a/exercises/28_defer2.zig +++ b/exercises/028_defer2.zig diff --git a/exercises/29_errdefer.zig b/exercises/029_errdefer.zig index f43c738..f43c738 100644 --- a/exercises/29_errdefer.zig +++ b/exercises/029_errdefer.zig diff --git a/exercises/30_switch.zig b/exercises/030_switch.zig index cb983f5..cb983f5 100644 --- a/exercises/30_switch.zig +++ b/exercises/030_switch.zig diff --git a/exercises/31_switch2.zig b/exercises/031_switch2.zig index b7680b4..b7680b4 100644 --- a/exercises/31_switch2.zig +++ b/exercises/031_switch2.zig diff --git a/exercises/32_unreachable.zig b/exercises/032_unreachable.zig index ffc35a4..ffc35a4 100644 --- a/exercises/32_unreachable.zig +++ b/exercises/032_unreachable.zig diff --git a/exercises/33_iferror.zig b/exercises/033_iferror.zig index 67777a9..67777a9 100644 --- a/exercises/33_iferror.zig +++ b/exercises/033_iferror.zig diff --git a/exercises/34_quiz4.zig b/exercises/034_quiz4.zig index 6b0e3fc..6b0e3fc 100644 --- a/exercises/34_quiz4.zig +++ b/exercises/034_quiz4.zig diff --git a/exercises/35_enums.zig b/exercises/035_enums.zig index 1825f52..1825f52 100644 --- a/exercises/35_enums.zig +++ b/exercises/035_enums.zig diff --git a/exercises/36_enums2.zig b/exercises/036_enums2.zig index 0ddc4a5..0ddc4a5 100644 --- a/exercises/36_enums2.zig +++ b/exercises/036_enums2.zig diff --git a/exercises/37_structs.zig b/exercises/037_structs.zig index 8082248..8082248 100644 --- a/exercises/37_structs.zig +++ b/exercises/037_structs.zig diff --git a/exercises/38_structs2.zig b/exercises/038_structs2.zig index b0db022..b0db022 100644 --- a/exercises/38_structs2.zig +++ b/exercises/038_structs2.zig diff --git a/exercises/39_pointers.zig b/exercises/039_pointers.zig index d545525..d545525 100644 --- a/exercises/39_pointers.zig +++ b/exercises/039_pointers.zig diff --git a/exercises/40_pointers2.zig b/exercises/040_pointers2.zig index 43dd2c3..43dd2c3 100644 --- a/exercises/40_pointers2.zig +++ b/exercises/040_pointers2.zig diff --git a/exercises/41_pointers3.zig b/exercises/041_pointers3.zig index 9e2bcc6..9e2bcc6 100644 --- a/exercises/41_pointers3.zig +++ b/exercises/041_pointers3.zig diff --git a/exercises/42_pointers4.zig b/exercises/042_pointers4.zig index 261dbc1..261dbc1 100644 --- a/exercises/42_pointers4.zig +++ b/exercises/042_pointers4.zig diff --git a/exercises/43_pointers5.zig b/exercises/043_pointers5.zig index cb94189..cb94189 100644 --- a/exercises/43_pointers5.zig +++ b/exercises/043_pointers5.zig diff --git a/exercises/44_quiz5.zig b/exercises/044_quiz5.zig index 8a0d88c..8a0d88c 100644 --- a/exercises/44_quiz5.zig +++ b/exercises/044_quiz5.zig diff --git a/exercises/45_optionals.zig b/exercises/045_optionals.zig index 1327e4c..1327e4c 100644 --- a/exercises/45_optionals.zig +++ b/exercises/045_optionals.zig diff --git a/exercises/46_optionals2.zig b/exercises/046_optionals2.zig index d3f65bb..d3f65bb 100644 --- a/exercises/46_optionals2.zig +++ b/exercises/046_optionals2.zig diff --git a/exercises/47_methods.zig b/exercises/047_methods.zig index c8e5c17..c8e5c17 100644 --- a/exercises/47_methods.zig +++ b/exercises/047_methods.zig diff --git a/exercises/48_methods2.zig b/exercises/048_methods2.zig index f97710d..d15a420 100644 --- a/exercises/48_methods2.zig +++ b/exercises/048_methods2.zig @@ -69,3 +69,7 @@ fn visitElephants(first_elephant: *Elephant) void { // // 1) drforester - I found one in the Zig source: // https://github.com/ziglang/zig/blob/041212a41cfaf029dc3eb9740467b721c76f406c/src/Compilation.zig#L2495 +// +// 2) bbuccianti - I found one! +// https://github.com/ziglang/zig/blob/master/lib/std/debug.zig#L477 +// diff --git a/exercises/49_quiz6.zig b/exercises/049_quiz6.zig index a1a1dec..a1a1dec 100644 --- a/exercises/49_quiz6.zig +++ b/exercises/049_quiz6.zig diff --git a/exercises/50_no_value.zig b/exercises/050_no_value.zig index 8708d2d..8708d2d 100644 --- a/exercises/50_no_value.zig +++ b/exercises/050_no_value.zig diff --git a/exercises/51_values.zig b/exercises/051_values.zig index dd68d3b..dd68d3b 100644 --- a/exercises/51_values.zig +++ b/exercises/051_values.zig diff --git a/exercises/052_slices.zig b/exercises/052_slices.zig new file mode 100644 index 0000000..98177cd --- /dev/null +++ b/exercises/052_slices.zig @@ -0,0 +1,49 @@ +// +// We've seen that passing arrays around can be awkward. Perhaps you +// remember a particularly horrendous function definition from quiz3? +// This function can only take arrays that are exactly 4 items long! +// +// fn printPowersOfTwo(numbers: [4]u16) void { ... } +// +// That's the trouble with arrays - their size is part of the data +// type and must be hard-coded into every usage of that type. This +// digits array is a [10]u8 forever and ever: +// +// var digits = [10]u8{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; +// +// Thankfully, Zig has slices, which let you dynamically point to a +// start item and provide a length. Here are slices of our digit +// array: +// +// const foo = digits[0..1]; // 0 +// const bar = digits[3..9]; // 3 4 5 6 7 8 +// const all = digits[0..]; // 0 1 2 3 4 5 6 7 8 9 +// +// As you can see, a slice [x..y] defines a first item by index x and +// a length y (where y-1 is the index of the last item). Leaving y off +// gives you the rest of the items. +// +// Notice that the type of a slice on an array of u8 items is []u8. +// +const std = @import("std"); + +pub fn main() void { + var cards = [8]u8{ 'A', '4', 'K', '8', '5', '2', 'Q', 'J' }; + + // Please put the first 4 cards in hand1 and the rest in hand2. + const hand1: []u8 = cards[???]; + const hand2: []u8 = cards[???]; + + std.debug.print("Hand1: ", .{}); + printHand(hand1); + + std.debug.print("Hand2: ", .{}); + printHand(hand2); +} + +// Please lend this function a hand. A u8 slice hand, that is. +fn printHand(hand: ???) void { + for (hand) |h| { + std.debug.print("{u} ", .{h}); + } +} diff --git a/exercises/053_slices2.zig b/exercises/053_slices2.zig new file mode 100644 index 0000000..2456d86 --- /dev/null +++ b/exercises/053_slices2.zig @@ -0,0 +1,35 @@ +// +// You are perhaps tempted to try slices on strings? They're arrays of +// u8 characters after all, right? Slices on strings work great. +// There's just one catch: don't forget that Zig string literals are +// immutable (const) values. So we need to change the type of slice +// from: +// +// var foo: []u8 = "foobar"[0..3]; +// +// to: +// +// var foo: []const u8 = "foobar"[0..3]; +// +// See if you can fix this Zero Wing-inspired phrase descrambler: +const std = @import("std"); + +pub fn main() void { + const scrambled = "great base for all your justice are belong to us"; + + const base1: []u8 = scrambled[15..23]; + const base2: []u8 = scrambled[6..10]; + const base3: []u8 = scrambled[32..]; + printPhrase(base1, base2, base3); + + const justice1: []u8 = scrambled[11..14]; + const justice2: []u8 = scrambled[0..5]; + const justice3: []u8 = scrambled[24..31]; + printPhrase(justice1, justice2, justice3); + + std.debug.print("\n", .{}); +} + +fn printPhrase(part1: []u8, part2: []u8, part3: []u8) void { + std.debug.print("'{s} {s} {s}.' ", .{part1, part2, part3}); +} diff --git a/exercises/054_manypointers.zig b/exercises/054_manypointers.zig new file mode 100644 index 0000000..23f2ae5 --- /dev/null +++ b/exercises/054_manypointers.zig @@ -0,0 +1,55 @@ +// +// You can also make pointers to multiple items without using a slice. +// +// var foo: [4]u8 = [4]u8{ 1, 2, 3, 4 }; +// var foo_slice: []u8 = foo[0..]; +// var foo_ptr: [*]u8 = &foo; +// +// The difference between foo_slice and foo_ptr is that the slice has +// a known length. The pointer doesn't. It is up to YOU to keep track +// of the number of u8s foo_ptr points to! +// +const std = @import("std"); + +pub fn main() void { + // Take a good look at the array type to which we're coercing + // the zen12 string (the REAL nature of strings will be + // revealed when we've learned some additional features): + const zen12: *const [21]u8 = "Memory is a resource."; + // + // It would also have been valid to coerce to a slice: + // const zen12: []const u8 = "..."; + // + // Now let's turn this into a "many pointer": + const zen_manyptr: [*]const u8 = zen12; + + // It's okay to access zen_manyptr just like an array or slice as + // long as you keep track of the length yourself! + // + // A "string" in Zig is a pointer to an array of const u8 values + // or a slice of const u8 values, into one, as we saw above). So, + // we could treat a "many pointer" of const u8 a string as long + // as we can CONVERT IT TO A SLICE. (Hint: we do know the length!) + // + // Please fix this line so the print below statement can print it: + const zen12_string: []const u8 = zen_manyptr; + + // Here's the moment of truth! + std.debug.print("{s}\n", .{zen12_string}); +} +// +// Are all of these pointer types starting to get confusing? +// +// FREE ZIG POINTER CHEATSHEET! (Using u8 as the example type.) +// +---------------+----------------------------------------------+ +// | u8 | one u8 | +// | *u8 | pointer to one u8 | +// | [2]u8 | two u8s | +// | [*]u8 | pointer to unknown number of u8s | +// | [2]const u8 | two immutable u8s | +// | [*]const u8 | pointer to unknown number of immutable u8s | +// | *[2]u8 | pointer to an array of 2 u8s | +// | *const [2]u8 | pointer to an immutable array of 2 u8s | +// | []u8 | slice of u8s | +// | []const u8 | slice of immutable u8s | +// +---------------+----------------------------------------------+ diff --git a/exercises/055_unions.zig b/exercises/055_unions.zig new file mode 100644 index 0000000..5e08aa1 --- /dev/null +++ b/exercises/055_unions.zig @@ -0,0 +1,76 @@ +// +// A union lets you store different types and sizes of data at +// the same memory address. How is this possible? The compiler +// sets aside enough memory for the largest thing you might want +// to store. +// +// In this example, an instance of Foo always takes up u64 of +// space memory even if you're currently storing a u8. +// +// const Foo = union { +// small: u8, +// medium: u32, +// large: u64, +// }; +// +// The syntax looks just like a struct, but a Foo can only hold a +// small OR a medium OR a large value. Once a field becomes +// active, the other inactive fields cannot be accessed. To +// change active fields, assign a whole new instance: +// +// var f = Foo{ .small = 5 }; +// f.small += 5; // OKAY +// f.medium = 5432; // ERROR! +// f = Foo{ .medium = 5432 }; // OKAY +// +// Unions can save space in memory because they let you "re-use" +// a space in memory. They also provide a sort of primitive +// polymorphism. Here fooBar() can take a Foo no matter what size +// of unsigned integer it holds: +// +// fn fooBar(f: Foo) void { ... } +// +// Oh, but how does fooBar() know which field is active? Zig has +// a neat way of keeping track, but for now, we'll just have to +// do it manually. +// +// Let's see if we can get this program working! +// +const std = @import("std"); + +// We've just started writing a simple ecosystem simulation. +// Insects will be represented by either bees or ants. Bees store +// the number of flowers they've visited that day and ants just +// store whether or not they're still alive. +const Insect = union { + flowers_visited: u16, + still_alive: bool, +}; + +// Since we need to specify the type of insect, we'll use an +// enum (remember those?). +const AntOrBee = enum { a, b }; + +pub fn main() void { + // We'll just make one bee and one ant to test them out: + var ant = Insect{ .still_alive = true }; + var bee = Insect{ .flowers_visited = 15 }; + + std.debug.print("Insect report! ", .{}); + + // Oops! We've made a mistake here. + printInsect(ant, AntOrBee.c); + printInsect(bee, AntOrBee.c); + + std.debug.print("\n", .{}); +} + +// Eccentric Doctor Zoraptera says that we can only use one +// function to print our insects. Doctor Z is small and sometimes +// inscrutable but we do not question her. +fn printInsect(insect: Insect, what_it_is: AntOrBee) void { + switch (what_it_is) { + .a => std.debug.print("Ant alive is: {}. ", .{insect.still_alive}), + .b => std.debug.print("Bee visited {} flowers. ", .{insect.flowers_visited}), + } +} diff --git a/exercises/056_unions2.zig b/exercises/056_unions2.zig new file mode 100644 index 0000000..e4294db --- /dev/null +++ b/exercises/056_unions2.zig @@ -0,0 +1,64 @@ +// +// It is really quite inconvenient having to manually keep track +// of the active field in our union, isn't it? +// +// Thankfully, Zig also has "tagged unions", which allow us to +// store an enum value within our union representing which field +// is active. +// +// const FooTag = enum{ small, medium, large }; +// +// const Foo = union(FooTag) { +// small: u8, +// medium: u32, +// large: u64, +// }; +// +// Now we can use a switch directly on the union to act on the +// active field: +// +// var f = Foo{ .small = 10 }; +// +// switch (f) { +// .small => |my_small| do_something(my_small), +// .medium => |my_medium| do_something(my_medium), +// .large => |my_large| do_something(my_large), +// } +// +// Let's make our Insects use a tagged union (Doctor Zoraptera +// approves). +// +const std = @import("std"); + +const InsectStat = enum { flowers_visited, still_alive }; + +const Insect = union(InsectStat) { + flowers_visited: u16, + still_alive: bool, +}; + +pub fn main() void { + var ant = Insect{ .still_alive = true }; + var bee = Insect{ .flowers_visited = 16 }; + + std.debug.print("Insect report! ", .{}); + + // Could it really be as simple as just passing the union? + printInsect(???); + printInsect(???); + + std.debug.print("\n", .{}); +} + +fn printInsect(insect: Insect) void { + switch (???) { + .still_alive => |a| std.debug.print("Ant alive is: {}. ", .{a}), + .flowers_visited => |f| std.debug.print("Bee visited {} flowers. ", .{f}), + } +} + +// By the way, did unions remind you of optional values and errors? +// Optional values are basically "null unions" and errors use "error +// union types". Now we can add our own unions to the mix to handle +// whatever situations we might encounter: +// union(Tag) { value: u32, toxic_ooze: void } diff --git a/exercises/057_unions3.zig b/exercises/057_unions3.zig new file mode 100644 index 0000000..142180f --- /dev/null +++ b/exercises/057_unions3.zig @@ -0,0 +1,54 @@ +// +// With tagged unions, it gets EVEN BETTER! If you don't have a +// need for a separate enum, you can define an inferred enum with +// your union all in one place. Just use the 'enum' keyword in +// place of the tag type: +// +// const Foo = union(enum) { +// small: u8, +// medium: u32, +// large: u64, +// }; +// +// Let's convert Insect. Doctor Zoraptera has already deleted the +// explicit InsectStat enum for you! +// +const std = @import("std"); + +const Insect = union(InsectStat) { + flowers_visited: u16, + still_alive: bool, +}; + +pub fn main() void { + var ant = Insect{ .still_alive = true }; + var bee = Insect{ .flowers_visited = 17 }; + + std.debug.print("Insect report! ", .{}); + + printInsect(ant); + printInsect(bee); + + std.debug.print("\n", .{}); +} + +fn printInsect(insect: Insect) void { + switch (insect) { + .still_alive => |a| std.debug.print("Ant alive is: {}. ", .{a}), + .flowers_visited => |f| std.debug.print("Bee visited {} flowers. ", .{f}), + } +} + +// Inferred enums are neat, representing the tip of the iceberg +// in the relationship between enums and unions. You can actually +// coerce a union TO an enum (which gives you the active field +// from the union as an enum). What's even wilder is that you can +// coerce an enum to a union! But don't get too excited, that +// only works when the union type is one of those weird zero-bit +// types like void! +// +// Tagged unions, as with most ideas in computer science, have a +// long history going back to the 1960s. However, they're only +// recently becoming mainstream, particularly in system-level +// programming languages. You might have also seen them called +// "variants", "sum types", or even "enums"! diff --git a/patches/eowyn.sh b/patches/eowyn.sh index 1bb8385..a30a67a 100755 --- a/patches/eowyn.sh +++ b/patches/eowyn.sh @@ -13,35 +13,34 @@ # to convalesce in the healed directory. # -# We run from the patches dir. Go there now if not already. -cd $(dirname $0) -pwd # Show it upon the screen so all shall be made apparent. +# We check ourselves before we wreck ourselves. +if [ ! -f 'patches/eowyn.sh' ] +then + echo "But I must be run from the project root directory." + exit 1 +fi -# Create healed/ directory here if it doesn't already exist. -mkdir -p healed +# Create directory of healing if it doesn't already exist. +mkdir -p patches/healed # Cycle through all the little broken Zig applications. -for broken in ../exercises/*.zig +for broken in exercises/*.zig do # Remove the dir and extension, rendering the True Name. true_name=$(basename $broken .zig) - patch_name="patches/$true_name.patch" + patch_name="patches/patches/$true_name.patch" - if [[ -f $patch_name ]] + if [ -f $patch_name ] then # Apply the bandages to the wounds, grow new limbs, let # new life spring into the broken bodies of the fallen. echo Healing $true_name... - patch --output=healed/$true_name.zig $broken $patch_name + patch --output=patches/healed/$true_name.zig $broken $patch_name else - echo Cannot heal $true_name. Making empty patch. - echo > $patch_name + echo Cannot heal $true_name. No patch found. fi done -# Return to the home of our ancestors. -cd .. - # Test the healed exercises. May the compiler have mercy upon us. zig build -Dhealed diff --git a/patches/gollum.sh b/patches/gollum.sh index 6531044..495aa44 100755 --- a/patches/gollum.sh +++ b/patches/gollum.sh @@ -6,18 +6,23 @@ # Gollum, The Hobbit, or There and Back Again # -cd $(dirname $(realpath $0)) -f=$(basename ../exercises/$1*.zig .zig 2> /dev/null) -b=../exercises/$f.zig -a=../answers/$f.zig -p=patches/$f.patch +if [ ! -f 'patches/gollum.sh' ] +then + echo "We must be run from the project root dir, precious!"; exit 1 +fi -printf "\tf: '$f'\n\tb: '$b'\n\ta: '$a'\n" +ex=$(printf "%03d" $1) +echo "Nassssty exercise $ex..." -if [[ ! -f $b ]]; then echo "We hates it!"; exit 1; fi -if [[ ! -a $a ]]; then echo "Where is it? Where is the answer, precious?"; exit; fi +f=$(basename exercises/${ex}_*.zig .zig 2> /dev/null) +b=exercises/$f.zig +a=answers/$f.zig +p=patches/patches/$f.patch -echo Hisssss! +if [ ! -f $b ]; then echo "No $f! We hates it!"; exit 1; fi +if [ ! -f $a ]; then echo "No $a! Where is it? Where is the answer, precious?"; exit; fi + +echo "Hissss!\tbefore: '$b'\n\t after: '$a'\n\t patch: '$p'\n" diff $b $a > $p diff --git a/patches/patches/01_hello.patch b/patches/patches/001_hello.patch index fb360a7..fb360a7 100644 --- a/patches/patches/01_hello.patch +++ b/patches/patches/001_hello.patch diff --git a/patches/patches/02_std.patch b/patches/patches/002_std.patch index 6c97adb..6c97adb 100644 --- a/patches/patches/02_std.patch +++ b/patches/patches/002_std.patch diff --git a/patches/patches/03_assignment.patch b/patches/patches/003_assignment.patch index bef4b24..bef4b24 100644 --- a/patches/patches/03_assignment.patch +++ b/patches/patches/003_assignment.patch diff --git a/patches/patches/04_arrays.patch b/patches/patches/004_arrays.patch index c6f9de3..c6f9de3 100644 --- a/patches/patches/04_arrays.patch +++ b/patches/patches/004_arrays.patch diff --git a/patches/patches/05_arrays2.patch b/patches/patches/005_arrays2.patch index 1e7b6b1..1e7b6b1 100644 --- a/patches/patches/05_arrays2.patch +++ b/patches/patches/005_arrays2.patch diff --git a/patches/patches/06_strings.patch b/patches/patches/006_strings.patch index 040a73c..040a73c 100644 --- a/patches/patches/06_strings.patch +++ b/patches/patches/006_strings.patch diff --git a/patches/patches/07_strings2.patch b/patches/patches/007_strings2.patch index 34cd053..34cd053 100644 --- a/patches/patches/07_strings2.patch +++ b/patches/patches/007_strings2.patch diff --git a/patches/patches/08_quiz.patch b/patches/patches/008_quiz.patch index 3d35a5a..3d35a5a 100644 --- a/patches/patches/08_quiz.patch +++ b/patches/patches/008_quiz.patch diff --git a/patches/patches/09_if.patch b/patches/patches/009_if.patch index 46579ad..46579ad 100644 --- a/patches/patches/09_if.patch +++ b/patches/patches/009_if.patch diff --git a/patches/patches/10_if2.patch b/patches/patches/010_if2.patch index e78f644..e78f644 100644 --- a/patches/patches/10_if2.patch +++ b/patches/patches/010_if2.patch diff --git a/patches/patches/11_while.patch b/patches/patches/011_while.patch index a892191..a892191 100644 --- a/patches/patches/11_while.patch +++ b/patches/patches/011_while.patch diff --git a/patches/patches/12_while2.patch b/patches/patches/012_while2.patch index 29ae763..29ae763 100644 --- a/patches/patches/12_while2.patch +++ b/patches/patches/012_while2.patch diff --git a/patches/patches/13_while3.patch b/patches/patches/013_while3.patch index b0172da..b0172da 100644 --- a/patches/patches/13_while3.patch +++ b/patches/patches/013_while3.patch diff --git a/patches/patches/14_while4.patch b/patches/patches/014_while4.patch index fb67587..fb67587 100644 --- a/patches/patches/14_while4.patch +++ b/patches/patches/014_while4.patch diff --git a/patches/patches/15_for.patch b/patches/patches/015_for.patch index e937221..e937221 100644 --- a/patches/patches/15_for.patch +++ b/patches/patches/015_for.patch diff --git a/patches/patches/16_for2.patch b/patches/patches/016_for2.patch index 5aba37f..5aba37f 100644 --- a/patches/patches/16_for2.patch +++ b/patches/patches/016_for2.patch diff --git a/patches/patches/17_quiz2.patch b/patches/patches/017_quiz2.patch index b46dab6..b46dab6 100644 --- a/patches/patches/17_quiz2.patch +++ b/patches/patches/017_quiz2.patch diff --git a/patches/patches/18_functions.patch b/patches/patches/018_functions.patch index dd3f2f6..dd3f2f6 100644 --- a/patches/patches/18_functions.patch +++ b/patches/patches/018_functions.patch diff --git a/patches/patches/19_functions2.patch b/patches/patches/019_functions2.patch index 254889a..254889a 100644 --- a/patches/patches/19_functions2.patch +++ b/patches/patches/019_functions2.patch diff --git a/patches/patches/20_quiz3.patch b/patches/patches/020_quiz3.patch index 6a00d31..6a00d31 100644 --- a/patches/patches/20_quiz3.patch +++ b/patches/patches/020_quiz3.patch diff --git a/patches/patches/21_errors.patch b/patches/patches/021_errors.patch index b37b3c8..b37b3c8 100644 --- a/patches/patches/21_errors.patch +++ b/patches/patches/021_errors.patch diff --git a/patches/patches/22_errors2.patch b/patches/patches/022_errors2.patch index 0501159..0501159 100644 --- a/patches/patches/22_errors2.patch +++ b/patches/patches/022_errors2.patch diff --git a/patches/patches/23_errors3.patch b/patches/patches/023_errors3.patch index a850116..a850116 100644 --- a/patches/patches/23_errors3.patch +++ b/patches/patches/023_errors3.patch diff --git a/patches/patches/24_errors4.patch b/patches/patches/024_errors4.patch index bb3fc8f..bb3fc8f 100644 --- a/patches/patches/24_errors4.patch +++ b/patches/patches/024_errors4.patch diff --git a/patches/patches/25_errors5.patch b/patches/patches/025_errors5.patch index 8aa59d4..8aa59d4 100644 --- a/patches/patches/25_errors5.patch +++ b/patches/patches/025_errors5.patch diff --git a/patches/patches/26_hello2.patch b/patches/patches/026_hello2.patch index 0065da5..0065da5 100644 --- a/patches/patches/26_hello2.patch +++ b/patches/patches/026_hello2.patch diff --git a/patches/patches/27_defer.patch b/patches/patches/027_defer.patch index 6ff7f98..6ff7f98 100644 --- a/patches/patches/27_defer.patch +++ b/patches/patches/027_defer.patch diff --git a/patches/patches/28_defer2.patch b/patches/patches/028_defer2.patch index c042c45..c042c45 100644 --- a/patches/patches/28_defer2.patch +++ b/patches/patches/028_defer2.patch diff --git a/patches/patches/29_errdefer.patch b/patches/patches/029_errdefer.patch index f93c56f..f93c56f 100644 --- a/patches/patches/29_errdefer.patch +++ b/patches/patches/029_errdefer.patch diff --git a/patches/patches/30_switch.patch b/patches/patches/030_switch.patch index 05cbe1a..05cbe1a 100644 --- a/patches/patches/30_switch.patch +++ b/patches/patches/030_switch.patch diff --git a/patches/patches/31_switch2.patch b/patches/patches/031_switch2.patch index f786762..f786762 100644 --- a/patches/patches/31_switch2.patch +++ b/patches/patches/031_switch2.patch diff --git a/patches/patches/32_unreachable.patch b/patches/patches/032_unreachable.patch index 0883932..0883932 100644 --- a/patches/patches/32_unreachable.patch +++ b/patches/patches/032_unreachable.patch diff --git a/patches/patches/33_iferror.patch b/patches/patches/033_iferror.patch index 62904db..62904db 100644 --- a/patches/patches/33_iferror.patch +++ b/patches/patches/033_iferror.patch diff --git a/patches/patches/34_quiz4.patch b/patches/patches/034_quiz4.patch index b259352..b259352 100644 --- a/patches/patches/34_quiz4.patch +++ b/patches/patches/034_quiz4.patch diff --git a/patches/patches/35_enums.patch b/patches/patches/035_enums.patch index ed2344b..ed2344b 100644 --- a/patches/patches/35_enums.patch +++ b/patches/patches/035_enums.patch diff --git a/patches/patches/36_enums2.patch b/patches/patches/036_enums2.patch index 54a7094..54a7094 100644 --- a/patches/patches/36_enums2.patch +++ b/patches/patches/036_enums2.patch diff --git a/patches/patches/37_structs.patch b/patches/patches/037_structs.patch index c26510d..c26510d 100644 --- a/patches/patches/37_structs.patch +++ b/patches/patches/037_structs.patch diff --git a/patches/patches/38_structs2.patch b/patches/patches/038_structs2.patch index 5d0d188..5d0d188 100644 --- a/patches/patches/38_structs2.patch +++ b/patches/patches/038_structs2.patch diff --git a/patches/patches/39_pointers.patch b/patches/patches/039_pointers.patch index 57d67e5..57d67e5 100644 --- a/patches/patches/39_pointers.patch +++ b/patches/patches/039_pointers.patch diff --git a/patches/patches/40_pointers2.patch b/patches/patches/040_pointers2.patch index a69cb20..a69cb20 100644 --- a/patches/patches/40_pointers2.patch +++ b/patches/patches/040_pointers2.patch diff --git a/patches/patches/41_pointers3.patch b/patches/patches/041_pointers3.patch index 02f7744..02f7744 100644 --- a/patches/patches/41_pointers3.patch +++ b/patches/patches/041_pointers3.patch diff --git a/patches/patches/42_pointers4.patch b/patches/patches/042_pointers4.patch index 29ca2d0..29ca2d0 100644 --- a/patches/patches/42_pointers4.patch +++ b/patches/patches/042_pointers4.patch diff --git a/patches/patches/43_pointers5.patch b/patches/patches/043_pointers5.patch index 8a73551..8a73551 100644 --- a/patches/patches/43_pointers5.patch +++ b/patches/patches/043_pointers5.patch diff --git a/patches/patches/44_quiz5.patch b/patches/patches/044_quiz5.patch index 44d4451..44d4451 100644 --- a/patches/patches/44_quiz5.patch +++ b/patches/patches/044_quiz5.patch diff --git a/patches/patches/45_optionals.patch b/patches/patches/045_optionals.patch index c945b5a..c945b5a 100644 --- a/patches/patches/45_optionals.patch +++ b/patches/patches/045_optionals.patch diff --git a/patches/patches/46_optionals2.patch b/patches/patches/046_optionals2.patch index 10705d9..10705d9 100644 --- a/patches/patches/46_optionals2.patch +++ b/patches/patches/046_optionals2.patch diff --git a/patches/patches/47_methods.patch b/patches/patches/047_methods.patch index cde93af..cde93af 100644 --- a/patches/patches/47_methods.patch +++ b/patches/patches/047_methods.patch diff --git a/patches/patches/48_methods2.patch b/patches/patches/048_methods2.patch index 781a99e..781a99e 100644 --- a/patches/patches/48_methods2.patch +++ b/patches/patches/048_methods2.patch diff --git a/patches/patches/49_quiz6.patch b/patches/patches/049_quiz6.patch index 83f9faf..83f9faf 100644 --- a/patches/patches/49_quiz6.patch +++ b/patches/patches/049_quiz6.patch diff --git a/patches/patches/50_no_value.patch b/patches/patches/050_no_value.patch index 79db0a3..79db0a3 100644 --- a/patches/patches/50_no_value.patch +++ b/patches/patches/050_no_value.patch diff --git a/patches/patches/51_values.patch b/patches/patches/051_values.patch index 43d1f65..43d1f65 100644 --- a/patches/patches/51_values.patch +++ b/patches/patches/051_values.patch diff --git a/patches/patches/052_slices.patch b/patches/patches/052_slices.patch new file mode 100644 index 0000000..80f8d72 --- /dev/null +++ b/patches/patches/052_slices.patch @@ -0,0 +1,10 @@ +34,35c34,35 +< const hand1: []u8 = cards[???]; +< const hand2: []u8 = cards[???]; +--- +> const hand1: []u8 = cards[0..4]; +> const hand2: []u8 = cards[4..]; +45c45 +< fn printHand(hand: ???) void { +--- +> fn printHand(hand: []u8) void { diff --git a/patches/patches/053_slices2.patch b/patches/patches/053_slices2.patch new file mode 100644 index 0000000..f5403a2 --- /dev/null +++ b/patches/patches/053_slices2.patch @@ -0,0 +1,20 @@ +20,22c20,22 +< const base1: []u8 = scrambled[15..23]; +< const base2: []u8 = scrambled[6..10]; +< const base3: []u8 = scrambled[32..]; +--- +> const base1: []const u8 = scrambled[15..23]; +> const base2: []const u8 = scrambled[6..10]; +> const base3: []const u8 = scrambled[32..]; +25,27c25,27 +< const justice1: []u8 = scrambled[11..14]; +< const justice2: []u8 = scrambled[0..5]; +< const justice3: []u8 = scrambled[24..31]; +--- +> const justice1: []const u8 = scrambled[11..14]; +> const justice2: []const u8 = scrambled[0..5]; +> const justice3: []const u8 = scrambled[24..31]; +33c33 +< fn printPhrase(part1: []u8, part2: []u8, part3: []u8) void { +--- +> fn printPhrase(part1: []const u8, part2: []const u8, part3: []const u8) void { diff --git a/patches/patches/054_manypointers.patch b/patches/patches/054_manypointers.patch new file mode 100644 index 0000000..82824e8 --- /dev/null +++ b/patches/patches/054_manypointers.patch @@ -0,0 +1,4 @@ +33c33 +< const zen12_string: []const u8 = zen_manyptr; +--- +> const zen12_string: []const u8 = zen_manyptr[0..21]; diff --git a/patches/patches/055_unions.patch b/patches/patches/055_unions.patch new file mode 100644 index 0000000..c362f20 --- /dev/null +++ b/patches/patches/055_unions.patch @@ -0,0 +1,6 @@ +62,63c62,63 +< printInsect(ant, AntOrBee.c); +< printInsect(bee, AntOrBee.c); +--- +> printInsect(ant, AntOrBee.a); +> printInsect(bee, AntOrBee.b); diff --git a/patches/patches/056_unions2.patch b/patches/patches/056_unions2.patch new file mode 100644 index 0000000..7341f7a --- /dev/null +++ b/patches/patches/056_unions2.patch @@ -0,0 +1,10 @@ +47,48c47,48 +< printInsect(???); +< printInsect(???); +--- +> printInsect(ant); +> printInsect(bee); +54c54 +< switch (???) { +--- +> switch (insect) { diff --git a/patches/patches/057_unions3.patch b/patches/patches/057_unions3.patch new file mode 100644 index 0000000..17e27a2 --- /dev/null +++ b/patches/patches/057_unions3.patch @@ -0,0 +1,4 @@ +18c18 +< const Insect = union(InsectStat) { +--- +> const Insect = union(enum) { |