Compare commits
3 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 723822e800 | |||
| 28dc209134 | |||
|
|
68bb75644b |
29 changed files with 87 additions and 74 deletions
|
|
@ -1,5 +1,7 @@
|
||||||
# Ziglings
|
# Ziglings
|
||||||
|
|
||||||
|
-> Fix originally by [nerdman](https://codeberg.org/nerdman) from [this issue](https://codeberg.org/ziglings/exercises/issues/127).
|
||||||
|
|
||||||
Welcome to Ziglings! This project contains a series of tiny
|
Welcome to Ziglings! This project contains a series of tiny
|
||||||
broken programs (and one nasty surprise). By fixing them, you'll
|
broken programs (and one nasty surprise). By fixing them, you'll
|
||||||
learn how to read and write [Zig](https://ziglang.org/) code.
|
learn how to read and write [Zig](https://ziglang.org/) code.
|
||||||
|
|
|
||||||
12
build.zig
12
build.zig
|
|
@ -274,7 +274,7 @@ const ZiglingStep = struct {
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make(step: *Step, prog_node: std.Progress.Node) !void {
|
fn make(step: *Step, options: Step.MakeOptions) !void {
|
||||||
// NOTE: Using exit code 2 will prevent the Zig compiler to print the message:
|
// NOTE: Using exit code 2 will prevent the Zig compiler to print the message:
|
||||||
// "error: the following build command failed with exit code 1:..."
|
// "error: the following build command failed with exit code 1:..."
|
||||||
const self: *ZiglingStep = @alignCast(@fieldParentPtr("step", step));
|
const self: *ZiglingStep = @alignCast(@fieldParentPtr("step", step));
|
||||||
|
|
@ -285,7 +285,7 @@ const ZiglingStep = struct {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const exe_path = self.compile(prog_node) catch {
|
const exe_path = self.compile(options) catch {
|
||||||
self.printErrors();
|
self.printErrors();
|
||||||
|
|
||||||
if (self.exercise.hint) |hint|
|
if (self.exercise.hint) |hint|
|
||||||
|
|
@ -295,7 +295,7 @@ const ZiglingStep = struct {
|
||||||
std.process.exit(2);
|
std.process.exit(2);
|
||||||
};
|
};
|
||||||
|
|
||||||
self.run(exe_path.?, prog_node) catch {
|
self.run(exe_path.?, options.progress_node) catch {
|
||||||
self.printErrors();
|
self.printErrors();
|
||||||
|
|
||||||
if (self.exercise.hint) |hint|
|
if (self.exercise.hint) |hint|
|
||||||
|
|
@ -405,7 +405,7 @@ const ZiglingStep = struct {
|
||||||
print("{s}PASSED{s}\n\n", .{ green_text, reset_text });
|
print("{s}PASSED{s}\n\n", .{ green_text, reset_text });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compile(self: *ZiglingStep, prog_node: std.Progress.Node) !?[]const u8 {
|
fn compile(self: *ZiglingStep, options: Step.MakeOptions) !?[]const u8 {
|
||||||
print("Compiling: {s}\n", .{self.exercise.main_file});
|
print("Compiling: {s}\n", .{self.exercise.main_file});
|
||||||
|
|
||||||
const b = self.step.owner;
|
const b = self.step.owner;
|
||||||
|
|
@ -436,7 +436,7 @@ const ZiglingStep = struct {
|
||||||
|
|
||||||
zig_args.append("--listen=-") catch @panic("OOM");
|
zig_args.append("--listen=-") catch @panic("OOM");
|
||||||
|
|
||||||
return try self.step.evalZigProcess(zig_args.items, prog_node);
|
return try self.step.evalZigProcess(zig_args.items, options.progress_node, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn help(self: *ZiglingStep) void {
|
fn help(self: *ZiglingStep) void {
|
||||||
|
|
@ -525,7 +525,7 @@ const PrintStep = struct {
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make(step: *Step, _: std.Progress.Node) !void {
|
fn make(step: *Step, _: Step.MakeOptions) !void {
|
||||||
const self: *PrintStep = @alignCast(@fieldParentPtr("step", step));
|
const self: *PrintStep = @alignCast(@fieldParentPtr("step", step));
|
||||||
print("{s}", .{self.message});
|
print("{s}", .{self.message});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ pub fn main() void {
|
||||||
for (&aliens) |*alien| {
|
for (&aliens) |*alien| {
|
||||||
|
|
||||||
// *** Zap the alien with the heat ray here! ***
|
// *** Zap the alien with the heat ray here! ***
|
||||||
???.zap(???);
|
heat_ray.zap(alien);
|
||||||
|
|
||||||
// If the alien's health is still above 0, it's still alive.
|
// If the alien's health is still above 0, it's still alive.
|
||||||
if (alien.health > 0) aliens_alive += 1;
|
if (alien.health > 0) aliens_alive += 1;
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ fn visitElephants(first_elephant: *Elephant) void {
|
||||||
|
|
||||||
// This gets the next elephant or stops:
|
// This gets the next elephant or stops:
|
||||||
// which method do we want here?
|
// which method do we want here?
|
||||||
e = if (e.hasTail()) e.??? else break;
|
e = if (e.hasTail()) e.getTail() else break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,13 @@ const Elephant = struct {
|
||||||
// Your Elephant trunk methods go here!
|
// Your Elephant trunk methods go here!
|
||||||
// ---------------------------------------------------
|
// ---------------------------------------------------
|
||||||
|
|
||||||
???
|
pub fn getTrunk(self: *Elephant) *Elephant {
|
||||||
|
return self.trunk.?;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn hasTrunk(self: *Elephant) bool {
|
||||||
|
return (self.trunk != null);
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------
|
// ---------------------------------------------------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -65,10 +65,10 @@ const std = @import("std");
|
||||||
const Err = error{Cthulhu};
|
const Err = error{Cthulhu};
|
||||||
|
|
||||||
pub fn main() void {
|
pub fn main() void {
|
||||||
var first_line1: *const [16]u8 = ???;
|
var first_line1: *const [16]u8 = undefined;
|
||||||
first_line1 = "That is not dead";
|
first_line1 = "That is not dead";
|
||||||
|
|
||||||
var first_line2: Err!*const [21]u8 = ???;
|
var first_line2: Err!*const [21]u8 = Err.Cthulhu;
|
||||||
first_line2 = "which can eternal lie";
|
first_line2 = "which can eternal lie";
|
||||||
|
|
||||||
// Note we need the "{!s}" format for the error union string.
|
// Note we need the "{!s}" format for the error union string.
|
||||||
|
|
@ -77,8 +77,8 @@ pub fn main() void {
|
||||||
printSecondLine();
|
printSecondLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn printSecondLine() ??? {
|
fn printSecondLine() void {
|
||||||
var second_line2: ?*const [18]u8 = ???;
|
var second_line2: ?*const [18]u8 = null;
|
||||||
second_line2 = "even death may die";
|
second_line2 = "even death may die";
|
||||||
|
|
||||||
std.debug.print("And with strange aeons {s}.\n", .{second_line2.?});
|
std.debug.print("And with strange aeons {s}.\n", .{second_line2.?});
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ pub fn main() void {
|
||||||
// Let's assign the std.debug.print function to a const named
|
// Let's assign the std.debug.print function to a const named
|
||||||
// "print" so that we can use this new name later!
|
// "print" so that we can use this new name later!
|
||||||
|
|
||||||
const print = ???;
|
const print = std.debug.print;
|
||||||
|
|
||||||
// Now let's look at assigning and pointing to values in Zig.
|
// Now let's look at assigning and pointing to values in Zig.
|
||||||
//
|
//
|
||||||
|
|
@ -163,13 +163,13 @@ pub fn main() void {
|
||||||
print("XP before:{}, ", .{glorp.experience});
|
print("XP before:{}, ", .{glorp.experience});
|
||||||
|
|
||||||
// Fix 1 of 2 goes here:
|
// Fix 1 of 2 goes here:
|
||||||
levelUp(glorp, reward_xp);
|
levelUp(&glorp, reward_xp);
|
||||||
|
|
||||||
print("after:{}.\n", .{glorp.experience});
|
print("after:{}.\n", .{glorp.experience});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fix 2 of 2 goes here:
|
// Fix 2 of 2 goes here:
|
||||||
fn levelUp(character_access: Character, xp: u32) void {
|
fn levelUp(character_access: *Character, xp: u32) void {
|
||||||
character_access.experience += xp;
|
character_access.experience += xp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,8 @@ pub fn main() void {
|
||||||
var cards = [8]u8{ 'A', '4', 'K', '8', '5', '2', 'Q', 'J' };
|
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.
|
// Please put the first 4 cards in hand1 and the rest in hand2.
|
||||||
const hand1: []u8 = cards[???];
|
const hand1: []u8 = cards[0..4];
|
||||||
const hand2: []u8 = cards[???];
|
const hand2: []u8 = cards[4..8];
|
||||||
|
|
||||||
std.debug.print("Hand1: ", .{});
|
std.debug.print("Hand1: ", .{});
|
||||||
printHand(hand1);
|
printHand(hand1);
|
||||||
|
|
@ -43,7 +43,7 @@ pub fn main() void {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Please lend this function a hand. A u8 slice hand, that is.
|
// Please lend this function a hand. A u8 slice hand, that is.
|
||||||
fn printHand(hand: ???) void {
|
fn printHand(hand: []u8) void {
|
||||||
for (hand) |h| {
|
for (hand) |h| {
|
||||||
std.debug.print("{u} ", .{h});
|
std.debug.print("{u} ", .{h});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,19 +17,19 @@ const std = @import("std");
|
||||||
pub fn main() void {
|
pub fn main() void {
|
||||||
const scrambled = "great base for all your justice are belong to us";
|
const scrambled = "great base for all your justice are belong to us";
|
||||||
|
|
||||||
const base1: []u8 = scrambled[15..23];
|
const base1: []const u8 = scrambled[15..23];
|
||||||
const base2: []u8 = scrambled[6..10];
|
const base2: []const u8 = scrambled[6..10];
|
||||||
const base3: []u8 = scrambled[32..];
|
const base3: []const u8 = scrambled[32..];
|
||||||
printPhrase(base1, base2, base3);
|
printPhrase(base1, base2, base3);
|
||||||
|
|
||||||
const justice1: []u8 = scrambled[11..14];
|
const justice1: []const u8 = scrambled[11..14];
|
||||||
const justice2: []u8 = scrambled[0..5];
|
const justice2: []const u8 = scrambled[0..5];
|
||||||
const justice3: []u8 = scrambled[24..31];
|
const justice3: []const u8 = scrambled[24..31];
|
||||||
printPhrase(justice1, justice2, justice3);
|
printPhrase(justice1, justice2, justice3);
|
||||||
|
|
||||||
std.debug.print("\n", .{});
|
std.debug.print("\n", .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn printPhrase(part1: []u8, part2: []u8, part3: []u8) void {
|
fn printPhrase(part1: []const u8, part2: []const u8, part3: []const u8) void {
|
||||||
std.debug.print("'{s} {s} {s}.' ", .{ part1, part2, part3 });
|
std.debug.print("'{s} {s} {s}.' ", .{ part1, part2, part3 });
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ pub fn main() void {
|
||||||
// we can CONVERT IT TO A SLICE. (Hint: we do know the length!)
|
// we can CONVERT IT TO A SLICE. (Hint: we do know the length!)
|
||||||
//
|
//
|
||||||
// Please fix this line so the print statement below can print it:
|
// Please fix this line so the print statement below can print it:
|
||||||
const zen12_string: []const u8 = zen_manyptr;
|
const zen12_string: []const u8 = zen_manyptr[0..21];
|
||||||
|
|
||||||
// Here's the moment of truth!
|
// Here's the moment of truth!
|
||||||
std.debug.print("{s}\n", .{zen12_string});
|
std.debug.print("{s}\n", .{zen12_string});
|
||||||
|
|
|
||||||
|
|
@ -59,8 +59,8 @@ pub fn main() void {
|
||||||
std.debug.print("Insect report! ", .{});
|
std.debug.print("Insect report! ", .{});
|
||||||
|
|
||||||
// Oops! We've made a mistake here.
|
// Oops! We've made a mistake here.
|
||||||
printInsect(ant, AntOrBee.c);
|
printInsect(ant, AntOrBee.a);
|
||||||
printInsect(bee, AntOrBee.c);
|
printInsect(bee, AntOrBee.b);
|
||||||
|
|
||||||
std.debug.print("\n", .{});
|
std.debug.print("\n", .{});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,14 +44,14 @@ pub fn main() void {
|
||||||
std.debug.print("Insect report! ", .{});
|
std.debug.print("Insect report! ", .{});
|
||||||
|
|
||||||
// Could it really be as simple as just passing the union?
|
// Could it really be as simple as just passing the union?
|
||||||
printInsect(???);
|
printInsect(ant);
|
||||||
printInsect(???);
|
printInsect(bee);
|
||||||
|
|
||||||
std.debug.print("\n", .{});
|
std.debug.print("\n", .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn printInsect(insect: Insect) void {
|
fn printInsect(insect: Insect) void {
|
||||||
switch (???) {
|
switch (insect) {
|
||||||
.still_alive => |a| std.debug.print("Ant alive is: {}. ", .{a}),
|
.still_alive => |a| std.debug.print("Ant alive is: {}. ", .{a}),
|
||||||
.flowers_visited => |f| std.debug.print("Bee visited {} flowers. ", .{f}),
|
.flowers_visited => |f| std.debug.print("Bee visited {} flowers. ", .{f}),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
//
|
//
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
const Insect = union(InsectStat) {
|
const Insect = union(enum) {
|
||||||
flowers_visited: u16,
|
flowers_visited: u16,
|
||||||
still_alive: bool,
|
still_alive: bool,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -192,8 +192,8 @@ const TripItem = union(enum) {
|
||||||
// Oops! The hermit forgot how to capture the union values
|
// Oops! The hermit forgot how to capture the union values
|
||||||
// in a switch statement. Please capture both values as
|
// in a switch statement. Please capture both values as
|
||||||
// 'p' so the print statements work!
|
// 'p' so the print statements work!
|
||||||
.place => print("{s}", .{p.name}),
|
.place => |p| print("{s}", .{p.name}),
|
||||||
.path => print("--{}->", .{p.dist}),
|
.path => |p| print("--{}->", .{p.dist}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -255,7 +255,7 @@ const HermitsNotebook = struct {
|
||||||
// dereference and optional value "unwrapping" look
|
// dereference and optional value "unwrapping" look
|
||||||
// together. Remember that you return the address with the
|
// together. Remember that you return the address with the
|
||||||
// "&" operator.
|
// "&" operator.
|
||||||
if (place == entry.*.?.place) return entry;
|
if (place == entry.*.?.place) return &entry.*.?;
|
||||||
// Try to make your answer this long:__________;
|
// Try to make your answer this long:__________;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -309,7 +309,7 @@ const HermitsNotebook = struct {
|
||||||
//
|
//
|
||||||
// Looks like the hermit forgot something in the return value of
|
// Looks like the hermit forgot something in the return value of
|
||||||
// this function. What could that be?
|
// this function. What could that be?
|
||||||
fn getTripTo(self: *HermitsNotebook, trip: []?TripItem, dest: *Place) void {
|
fn getTripTo(self: *HermitsNotebook, trip: []?TripItem, dest: *Place) TripError!void {
|
||||||
// We start at the destination entry.
|
// We start at the destination entry.
|
||||||
const destination_entry = self.getEntry(dest);
|
const destination_entry = self.getEntry(dest);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,9 @@ const print = @import("std").debug.print;
|
||||||
|
|
||||||
pub fn main() void {
|
pub fn main() void {
|
||||||
const zig = [_]u8{
|
const zig = [_]u8{
|
||||||
0o131, // octal
|
'Z', // octal
|
||||||
0b1101000, // binary
|
'i', // binary
|
||||||
0x66, // hex
|
'g', // hex
|
||||||
};
|
};
|
||||||
|
|
||||||
print("{s} is cool.\n", .{zig});
|
print("{s} is cool.\n", .{zig});
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ pub fn main() void {
|
||||||
//
|
//
|
||||||
// We'll convert this weight from pound to kilograms at a
|
// We'll convert this weight from pound to kilograms at a
|
||||||
// conversion of 0.453592kg to the pound.
|
// conversion of 0.453592kg to the pound.
|
||||||
const shuttle_weight: f16 = 0.453592 * 4480e6;
|
const shuttle_weight: f32 = 0.453592 * 4480e3;
|
||||||
|
|
||||||
// By default, float values are formatted in scientific
|
// By default, float values are formatted in scientific
|
||||||
// notation. Try experimenting with '{d}' and '{d:.3}' to see
|
// notation. Try experimenting with '{d}' and '{d:.3}' to see
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ const print = @import("std").debug.print;
|
||||||
pub fn main() void {
|
pub fn main() void {
|
||||||
var letter: u8 = 'A';
|
var letter: u8 = 'A';
|
||||||
|
|
||||||
const my_letter: ??? = &letter;
|
const my_letter: ?*[1]u8 = &letter;
|
||||||
// ^^^^^^^
|
// ^^^^^^^
|
||||||
// Your type here.
|
// Your type here.
|
||||||
// Must coerce from &letter (which is a *u8).
|
// Must coerce from &letter (which is a *u8).
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ pub fn main() void {
|
||||||
// return it from the for loop.
|
// return it from the for loop.
|
||||||
const current_lang: ?[]const u8 = for (langs) |lang| {
|
const current_lang: ?[]const u8 = for (langs) |lang| {
|
||||||
if (lang.len == 3) break lang;
|
if (lang.len == 3) break lang;
|
||||||
};
|
} else null;
|
||||||
|
|
||||||
if (current_lang) |cl| {
|
if (current_lang) |cl| {
|
||||||
print("Current language: {s}\n", .{cl});
|
print("Current language: {s}\n", .{cl});
|
||||||
|
|
|
||||||
|
|
@ -128,8 +128,8 @@ pub fn main() void {
|
||||||
// wanted for this Food.
|
// wanted for this Food.
|
||||||
//
|
//
|
||||||
// Please return this Food from the loop.
|
// Please return this Food from the loop.
|
||||||
break;
|
break food;
|
||||||
};
|
} else menu[0];
|
||||||
// ^ Oops! We forgot to return Mac & Cheese as the default
|
// ^ Oops! We forgot to return Mac & Cheese as the default
|
||||||
// Food when the requested ingredients aren't found.
|
// Food when the requested ingredients aren't found.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ pub fn main() void {
|
||||||
//
|
//
|
||||||
// If there was no overflow at all while adding 5 to a, what value would
|
// If there was no overflow at all while adding 5 to a, what value would
|
||||||
// 'my_result' hold? Write the answer in into 'expected_result'.
|
// 'my_result' hold? Write the answer in into 'expected_result'.
|
||||||
const expected_result: u8 = ???;
|
const expected_result: u8 = 18;
|
||||||
print(". Without overflow: {b:0>8}. ", .{expected_result});
|
print(". Without overflow: {b:0>8}. ", .{expected_result});
|
||||||
|
|
||||||
print("Furthermore, ", .{});
|
print("Furthermore, ", .{});
|
||||||
|
|
@ -78,6 +78,6 @@ pub fn main() void {
|
||||||
// Now it's your turn. See if you can fix this attempt to use
|
// Now it's your turn. See if you can fix this attempt to use
|
||||||
// this builtin to reverse the bits of a u8 integer.
|
// this builtin to reverse the bits of a u8 integer.
|
||||||
const input: u8 = 0b11110000;
|
const input: u8 = 0b11110000;
|
||||||
const tupni: u8 = @bitReverse(input, tupni);
|
const tupni: u8 = @bitReverse(input);
|
||||||
print("{b:0>8} backwards is {b:0>8}.\n", .{ input, tupni });
|
print("{b:0>8} backwards is {b:0>8}.\n", .{ input, tupni });
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ pub fn main() void {
|
||||||
// Oops! We cannot leave the 'me' and 'myself' fields
|
// Oops! We cannot leave the 'me' and 'myself' fields
|
||||||
// undefined. Please set them here:
|
// undefined. Please set them here:
|
||||||
narcissus.me = &narcissus;
|
narcissus.me = &narcissus;
|
||||||
narcissus.??? = ???;
|
narcissus.myself = &narcissus;
|
||||||
|
|
||||||
// This determines a "peer type" from three separate
|
// This determines a "peer type" from three separate
|
||||||
// references (they just happen to all be the same object).
|
// references (they just happen to all be the same object).
|
||||||
|
|
@ -70,7 +70,7 @@ pub fn main() void {
|
||||||
//
|
//
|
||||||
// The fix for this is very subtle, but it makes a big
|
// The fix for this is very subtle, but it makes a big
|
||||||
// difference!
|
// difference!
|
||||||
const Type2 = narcissus.fetchTheMostBeautifulType();
|
const Type2 = Narcissus.fetchTheMostBeautifulType();
|
||||||
|
|
||||||
// Now we print a pithy statement about Narcissus.
|
// Now we print a pithy statement about Narcissus.
|
||||||
print("A {s} loves all {s}es. ", .{
|
print("A {s} loves all {s}es. ", .{
|
||||||
|
|
@ -109,15 +109,15 @@ pub fn main() void {
|
||||||
// Please complete these 'if' statements so that the field
|
// Please complete these 'if' statements so that the field
|
||||||
// name will not be printed if the field is of type 'void'
|
// name will not be printed if the field is of type 'void'
|
||||||
// (which is a zero-bit type that takes up no space at all!):
|
// (which is a zero-bit type that takes up no space at all!):
|
||||||
if (fields[0].??? != void) {
|
if (fields[0].type != void) {
|
||||||
print(" {s}", .{@typeInfo(Narcissus).Struct.fields[0].name});
|
print(" {s}", .{@typeInfo(Narcissus).Struct.fields[0].name});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fields[1].??? != void) {
|
if (fields[1].type != void) {
|
||||||
print(" {s}", .{@typeInfo(Narcissus).Struct.fields[1].name});
|
print(" {s}", .{@typeInfo(Narcissus).Struct.fields[1].name});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fields[2].??? != void) {
|
if (fields[2].type != void) {
|
||||||
print(" {s}", .{@typeInfo(Narcissus).Struct.fields[2].name});
|
print(" {s}", .{@typeInfo(Narcissus).Struct.fields[2].name});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -62,8 +62,8 @@ pub fn main() void {
|
||||||
// types with specific sizes. The comptime numbers will be
|
// types with specific sizes. The comptime numbers will be
|
||||||
// coerced (if they'll fit!) into your chosen runtime types.
|
// coerced (if they'll fit!) into your chosen runtime types.
|
||||||
// For this it is necessary to specify a size, e.g. 32 bit.
|
// For this it is necessary to specify a size, e.g. 32 bit.
|
||||||
var var_int = 12345;
|
var var_int: u32 = 12345;
|
||||||
var var_float = 987.654;
|
var var_float: f32 = 987.654;
|
||||||
|
|
||||||
// We can change what is stored at the areas set aside for
|
// We can change what is stored at the areas set aside for
|
||||||
// "var_int" and "var_float" in the running compiled program.
|
// "var_int" and "var_float" in the running compiled program.
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ pub fn main() void {
|
||||||
// In this contrived example, we've decided to allocate some
|
// In this contrived example, we've decided to allocate some
|
||||||
// arrays using a variable count! But something's missing...
|
// arrays using a variable count! But something's missing...
|
||||||
//
|
//
|
||||||
var count = 0;
|
comptime var count = 0;
|
||||||
|
|
||||||
count += 1;
|
count += 1;
|
||||||
const a1: [count]u8 = .{'A'} ** count;
|
const a1: [count]u8 = .{'A'} ** count;
|
||||||
|
|
@ -60,5 +60,5 @@ pub fn main() void {
|
||||||
//
|
//
|
||||||
// Try uncommenting this line and playing around with it
|
// Try uncommenting this line and playing around with it
|
||||||
// (copy it, move it) to see what it does:
|
// (copy it, move it) to see what it does:
|
||||||
//@compileLog("Count at compile time: ", count);
|
// @compileLog("Count at compile time: ", count);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ const Schooner = struct {
|
||||||
//
|
//
|
||||||
// Please change this so that it sets a 0 scale to 1
|
// Please change this so that it sets a 0 scale to 1
|
||||||
// instead.
|
// instead.
|
||||||
if (my_scale == 0) @compileError("Scale 1:0 is not valid!");
|
if (my_scale == 0) my_scale = 1;
|
||||||
|
|
||||||
self.scale = my_scale;
|
self.scale = my_scale;
|
||||||
self.hull_length /= my_scale;
|
self.hull_length /= my_scale;
|
||||||
|
|
@ -69,7 +69,7 @@ pub fn main() void {
|
||||||
// Hey, we can't just pass this runtime variable as an
|
// Hey, we can't just pass this runtime variable as an
|
||||||
// argument to the scaleMe() method. What would let us do
|
// argument to the scaleMe() method. What would let us do
|
||||||
// that?
|
// that?
|
||||||
var scale: u32 = undefined;
|
comptime var scale: u32 = undefined;
|
||||||
|
|
||||||
scale = 32; // 1:32 scale
|
scale = 32; // 1:32 scale
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,8 @@ pub fn main() void {
|
||||||
// 2) Sets the size of the array of type T (which is the
|
// 2) Sets the size of the array of type T (which is the
|
||||||
// sequence we're creating and returning).
|
// sequence we're creating and returning).
|
||||||
//
|
//
|
||||||
fn makeSequence(comptime T: type, ??? size: usize) [???]T {
|
fn makeSequence(comptime T: type, comptime size: usize) [size]T {
|
||||||
var sequence: [???]T = undefined;
|
var sequence: [size]T = undefined;
|
||||||
var i: usize = 0;
|
var i: usize = 0;
|
||||||
|
|
||||||
while (i < size) : (i += 1) {
|
while (i < size) : (i += 1) {
|
||||||
|
|
|
||||||
|
|
@ -123,8 +123,8 @@ fn isADuck(possible_duck: anytype) bool {
|
||||||
// Please make sure MyType has both waddle() and quack()
|
// Please make sure MyType has both waddle() and quack()
|
||||||
// methods:
|
// methods:
|
||||||
const MyType = @TypeOf(possible_duck);
|
const MyType = @TypeOf(possible_duck);
|
||||||
const walks_like_duck = ???;
|
const walks_like_duck = @hasDecl(MyType, "waddle");
|
||||||
const quacks_like_duck = ???;
|
const quacks_like_duck = @hasDecl(MyType, "quack");
|
||||||
|
|
||||||
const is_duck = walks_like_duck and quacks_like_duck;
|
const is_duck = walks_like_duck and quacks_like_duck;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ pub fn main() void {
|
||||||
|
|
||||||
const fields = @typeInfo(Narcissus).Struct.fields;
|
const fields = @typeInfo(Narcissus).Struct.fields;
|
||||||
|
|
||||||
??? {
|
inline for (fields) |field| {
|
||||||
if (field.type != void) {
|
if (field.type != void) {
|
||||||
print(" {s}", .{field.name});
|
print(" {s}", .{field.name});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ pub fn main() void {
|
||||||
// at compile time.
|
// at compile time.
|
||||||
//
|
//
|
||||||
// Please fix this to loop once per "instruction":
|
// Please fix this to loop once per "instruction":
|
||||||
??? (i < instructions.len) : (???) {
|
inline while (i < instructions.len) : (i += 3) {
|
||||||
|
|
||||||
// This gets the digit from the "instruction". Can you
|
// This gets the digit from the "instruction". Can you
|
||||||
// figure out why we subtract '0' from it?
|
// figure out why we subtract '0' from it?
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ pub fn addCliTests(b: *std.Build, exercises: []const Exercise) *Step {
|
||||||
b.graph.zig_exe,
|
b.graph.zig_exe,
|
||||||
"build",
|
"build",
|
||||||
"-Dhealed",
|
"-Dhealed",
|
||||||
b.fmt("-Dhealed-path={s}", .{tmp_path}),
|
b.fmt("-Dhealed-path={s}", .{tmp_path.src_path.sub_path}),
|
||||||
b.fmt("-Dn={}", .{n}),
|
b.fmt("-Dn={}", .{n}),
|
||||||
});
|
});
|
||||||
cmd.setName(b.fmt("zig build -Dhealed -Dn={}", .{n}));
|
cmd.setName(b.fmt("zig build -Dhealed -Dn={}", .{n}));
|
||||||
|
|
@ -72,7 +72,7 @@ pub fn addCliTests(b: *std.Build, exercises: []const Exercise) *Step {
|
||||||
b.graph.zig_exe,
|
b.graph.zig_exe,
|
||||||
"build",
|
"build",
|
||||||
"-Dhealed",
|
"-Dhealed",
|
||||||
b.fmt("-Dhealed-path={s}", .{tmp_path}),
|
b.fmt("-Dhealed-path={s}", .{tmp_path.src_path.sub_path}),
|
||||||
});
|
});
|
||||||
cmd.setName("zig build -Dhealed");
|
cmd.setName("zig build -Dhealed");
|
||||||
cmd.expectExitCode(0);
|
cmd.expectExitCode(0);
|
||||||
|
|
@ -150,7 +150,7 @@ const CheckNamedStep = struct {
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make(step: *Step, _: std.Progress.Node) !void {
|
fn make(step: *Step, _: Step.MakeOptions) !void {
|
||||||
const b = step.owner;
|
const b = step.owner;
|
||||||
const self: *CheckNamedStep = @alignCast(@fieldParentPtr("step", step));
|
const self: *CheckNamedStep = @alignCast(@fieldParentPtr("step", step));
|
||||||
const ex = self.exercise;
|
const ex = self.exercise;
|
||||||
|
|
@ -202,7 +202,7 @@ const CheckStep = struct {
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make(step: *Step, _: std.Progress.Node) !void {
|
fn make(step: *Step, _: Step.MakeOptions) !void {
|
||||||
const b = step.owner;
|
const b = step.owner;
|
||||||
const self: *CheckStep = @alignCast(@fieldParentPtr("step", step));
|
const self: *CheckStep = @alignCast(@fieldParentPtr("step", step));
|
||||||
const exercises = self.exercises;
|
const exercises = self.exercises;
|
||||||
|
|
@ -325,7 +325,7 @@ const FailStep = struct {
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make(step: *Step, _: std.Progress.Node) !void {
|
fn make(step: *Step, _: Step.MakeOptions) !void {
|
||||||
const b = step.owner;
|
const b = step.owner;
|
||||||
const self: *FailStep = @alignCast(@fieldParentPtr("step", step));
|
const self: *FailStep = @alignCast(@fieldParentPtr("step", step));
|
||||||
|
|
||||||
|
|
@ -352,7 +352,7 @@ const HealStep = struct {
|
||||||
exercises: []const Exercise,
|
exercises: []const Exercise,
|
||||||
work_path: []const u8,
|
work_path: []const u8,
|
||||||
|
|
||||||
pub fn create(owner: *Build, exercises: []const Exercise, work_path: []const u8) *HealStep {
|
pub fn create(owner: *Build, exercises: []const Exercise, work_path: LazyPath) *HealStep {
|
||||||
const self = owner.allocator.create(HealStep) catch @panic("OOM");
|
const self = owner.allocator.create(HealStep) catch @panic("OOM");
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.step = Step.init(.{
|
.step = Step.init(.{
|
||||||
|
|
@ -362,13 +362,13 @@ const HealStep = struct {
|
||||||
.makeFn = make,
|
.makeFn = make,
|
||||||
}),
|
}),
|
||||||
.exercises = exercises,
|
.exercises = exercises,
|
||||||
.work_path = work_path,
|
.work_path = work_path.src_path.sub_path,
|
||||||
};
|
};
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make(step: *Step, _: std.Progress.Node) !void {
|
fn make(step: *Step, _: Step.MakeOptions) !void {
|
||||||
const b = step.owner;
|
const b = step.owner;
|
||||||
const self: *HealStep = @alignCast(@fieldParentPtr("step", step));
|
const self: *HealStep = @alignCast(@fieldParentPtr("step", step));
|
||||||
|
|
||||||
|
|
@ -403,12 +403,17 @@ fn heal(allocator: Allocator, exercises: []const Exercise, work_path: []const u8
|
||||||
|
|
||||||
/// This function is the same as the one in std.Build.makeTempPath, with the
|
/// This function is the same as the one in std.Build.makeTempPath, with the
|
||||||
/// difference that returns an error when the temp path cannot be created.
|
/// difference that returns an error when the temp path cannot be created.
|
||||||
pub fn makeTempPath(b: *Build) ![]const u8 {
|
pub fn makeTempPath(b: *Build) !LazyPath {
|
||||||
const rand_int = std.crypto.random.int(u64);
|
const rand_int = std.crypto.random.int(u64);
|
||||||
const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ Build.hex64(rand_int);
|
const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ Build.hex64(rand_int);
|
||||||
const path = b.cache_root.join(b.allocator, &.{tmp_dir_sub_path}) catch
|
const path = b.cache_root.join(b.allocator, &.{tmp_dir_sub_path}) catch
|
||||||
@panic("OOM");
|
@panic("OOM");
|
||||||
try b.cache_root.handle.makePath(tmp_dir_sub_path);
|
try b.cache_root.handle.makePath(tmp_dir_sub_path);
|
||||||
|
|
||||||
return path;
|
return LazyPath{
|
||||||
|
.src_path = .{
|
||||||
|
.owner = b,
|
||||||
|
.sub_path = path,
|
||||||
|
},
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue