From b68855fc2de2898dc90af1e5e56235324ecbd5eb Mon Sep 17 00:00:00 2001 From: Laurens Miers Date: Wed, 25 Sep 2024 12:20:34 +0200 Subject: [PATCH] WIP: comptime experiments --- exercises/066_comptime.zig | 4 ++-- exercises/067_comptime2.zig | 2 +- exercises/068_comptime3.zig | 5 +++-- exercises/069_comptime4.zig | 4 ++-- exercises/070_comptime5.zig | 4 ++-- exercises/071_comptime6.zig | 2 +- exercises/072_comptime7.zig | 2 +- exercises/073_comptime8.zig | 4 ++-- exercises/074_comptime9.zig | 2 +- exercises/075_quiz8.zig | 43 ++++++++++++++++++++++++++++++++++++- 10 files changed, 57 insertions(+), 15 deletions(-) diff --git a/exercises/066_comptime.zig b/exercises/066_comptime.zig index 9b07a2d..124b472 100644 --- a/exercises/066_comptime.zig +++ b/exercises/066_comptime.zig @@ -62,8 +62,8 @@ pub fn main() void { // types with specific sizes. The comptime numbers will be // coerced (if they'll fit!) into your chosen runtime types. // For this it is necessary to specify a size, e.g. 32 bit. - var var_int = 12345; - var var_float = 987.654; + var var_int: u32 = 12345; + var var_float: f32 = 987.654; // We can change what is stored at the areas set aside for // "var_int" and "var_float" in the running compiled program. diff --git a/exercises/067_comptime2.zig b/exercises/067_comptime2.zig index 7d4bdb0..136bca1 100644 --- a/exercises/067_comptime2.zig +++ b/exercises/067_comptime2.zig @@ -35,7 +35,7 @@ pub fn main() void { // In this contrived example, we've decided to allocate some // arrays using a variable count! But something's missing... // - var count = 0; + comptime var count = 0; count += 1; var a1: [count]u8 = .{'A'} ** count; diff --git a/exercises/068_comptime3.zig b/exercises/068_comptime3.zig index 15b8997..4d8419a 100644 --- a/exercises/068_comptime3.zig +++ b/exercises/068_comptime3.zig @@ -43,7 +43,8 @@ const Schooner = struct { // // Please change this so that it sets a 0 scale to 1 // instead. - if (my_scale == 0) @compileError("Scale 1:0 is not valid!"); + // if (my_scale == 0) @compileError("Scale 1:0 is not valid!"); + if (my_scale == 0) my_scale = 1; self.scale = my_scale; self.hull_length /= my_scale; @@ -69,7 +70,7 @@ pub fn main() void { // Hey, we can't just pass this runtime variable as an // argument to the scaleMe() method. What would let us do // that? - var scale: u32 = undefined; + comptime var scale: u32 = undefined; scale = 32; // 1:32 scale diff --git a/exercises/069_comptime4.zig b/exercises/069_comptime4.zig index e090bb3..0263de0 100644 --- a/exercises/069_comptime4.zig +++ b/exercises/069_comptime4.zig @@ -42,8 +42,8 @@ pub fn main() void { // 2) Sets the size of the array of type T (which is the // sequence we're creating and returning). // -fn makeSequence(comptime T: type, ??? size: usize) [???]T { - var sequence: [???]T = undefined; +fn makeSequence(comptime T: type, comptime size: usize) [size]T { + var sequence: [size]T = undefined; var i: usize = 0; while (i < size) : (i += 1) { diff --git a/exercises/070_comptime5.zig b/exercises/070_comptime5.zig index 3b85aae..69a529b 100644 --- a/exercises/070_comptime5.zig +++ b/exercises/070_comptime5.zig @@ -123,8 +123,8 @@ fn isADuck(possible_duck: anytype) bool { // Please make sure MyType has both waddle() and quack() // methods: const MyType = @TypeOf(possible_duck); - const walks_like_duck = ???; - const quacks_like_duck = ???; + const walks_like_duck = @hasDecl(MyType, "waddle"); + const quacks_like_duck = @hasDecl(MyType, "quack"); const is_duck = walks_like_duck and quacks_like_duck; diff --git a/exercises/071_comptime6.zig b/exercises/071_comptime6.zig index 7723291..d467184 100644 --- a/exercises/071_comptime6.zig +++ b/exercises/071_comptime6.zig @@ -40,7 +40,7 @@ pub fn main() void { const fields = @typeInfo(Narcissus).Struct.fields; - ??? { + inline for (fields) |field| { if (field.type != void) { print(" {s}", .{field.name}); } diff --git a/exercises/072_comptime7.zig b/exercises/072_comptime7.zig index 9bc30fb..48bb39e 100644 --- a/exercises/072_comptime7.zig +++ b/exercises/072_comptime7.zig @@ -35,7 +35,7 @@ pub fn main() void { // at compile time. // // 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 // figure out why we subtract '0' from it? diff --git a/exercises/073_comptime8.zig b/exercises/073_comptime8.zig index fe1f8ea..2e69566 100644 --- a/exercises/073_comptime8.zig +++ b/exercises/073_comptime8.zig @@ -32,12 +32,12 @@ const llamas = [llama_count]u32{ 5, 10, 15, 20, 25 }; pub fn main() void { // We meant to fetch the last llama. Please fix this simple // mistake so the assertion no longer fails. - const my_llama = getLlama(5); + const my_llama = getLlama(4); print("My llama value is {}.\n", .{my_llama}); } -fn getLlama(i: usize) u32 { +fn getLlama(comptime i: usize) u32 { // We've put a guard assert() at the top of this function to // prevent mistakes. The 'comptime' keyword here means that // the mistake will be caught when we compile! diff --git a/exercises/074_comptime9.zig b/exercises/074_comptime9.zig index 6db8ad2..d5e6e67 100644 --- a/exercises/074_comptime9.zig +++ b/exercises/074_comptime9.zig @@ -39,7 +39,7 @@ const llamas = makeLlamas(llama_count); // And here's the function. Note that the return value type // depends on one of the input arguments! -fn makeLlamas(count: usize) [count]u8 { +fn makeLlamas(comptime count: usize) [count]u8 { var temp: [count]u8 = undefined; var i = 0; diff --git a/exercises/075_quiz8.zig b/exercises/075_quiz8.zig index 12b460c..8eee967 100644 --- a/exercises/075_quiz8.zig +++ b/exercises/075_quiz8.zig @@ -8,6 +8,8 @@ // of it. // const print = @import("std").debug.print; +const mem = @import("std").mem; +const fmt = @import("std").fmt; const TripError = error{ Unreachable, EatenByAGrue }; @@ -49,12 +51,47 @@ const Path = struct { // // Please fill in the body of this function! fn makePath(from: *Place, to: *Place, dist: u8) Path { + return Path{ + .from = from, + .to = to, + .dist = dist, + }; +} +fn makePath2(comptime path: []const u8) Path { + var it = mem.split(u8, path, "->"); + var from: []const u8 = it.first(); + it = mem.split(u8, it.next().?, ":"); + var to: []const u8 = it.first(); + var dist: []const u8 = it.next().?; + return Path{ + .from = &@field(@This(), from), + .to = &@field(@This(), to), + .dist = try fmt.parseInt(u8, dist, 10), + }; +} + +fn makePath3(comptime path: []const u8) Path { + var it = mem.split(u8, path, "->"); + var from: []const u8 = it.first(); + var list = it.next().?; + var connections_it = mem.split(u8, list[1..(path.len - from.len - 3)], " "); + + while (connections_it.next()) |connect| { + var connection_it = mem.split(u8, connect, ":"); + return Path{ + .from = &@field(@This(), from), + .to = &@field(@This(), connection_it.first()), + .dist = try fmt.parseInt(u8, connection_it.next().?, 10), + }; + } } // Using our new function, these path definitions take up considerably less // space in our program now! -const a_paths = [_]Path{makePath(&a, &b, 2)}; +// const a_paths = [_]Path{makePath(&a, &b, 2)}; +const a_paths = [_]Path{makePath2("a->b:2")}; +// const a_paths = makePath3("a->(b:2)"); const b_paths = [_]Path{ makePath(&b, &a, 2), makePath(&b, &d, 1) }; const c_paths = [_]Path{ makePath(&c, &d, 3), makePath(&c, &e, 2) }; const d_paths = [_]Path{ makePath(&d, &b, 1), makePath(&d, &c, 3), makePath(&d, &f, 7) }; @@ -154,6 +191,10 @@ pub fn main() void { const start = &a; // Archer's Point const destination = &f; // Fox Pond + // makePath3("a->(b:2 d:3)"); + var temp: Path = makePath3("a->(b:2)"); + _ = temp; + // We could either have this: // // a.paths = a_paths[0..];