diff options
Diffstat (limited to 'exercises/065_builtins2.zig')
-rw-r--r-- | exercises/065_builtins2.zig | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/exercises/065_builtins2.zig b/exercises/065_builtins2.zig new file mode 100644 index 0000000..9667b76 --- /dev/null +++ b/exercises/065_builtins2.zig @@ -0,0 +1,127 @@ +// +// Zig has builtins for mathematical operations such as... +// +// @sqrt @sin @cos +// @exp @log @floor +// +// ...and lots of type casting operations such as... +// +// @as @intToError @intToFloat +// @intToPtr @ptrToInt @enumToInt +// +// Spending part of a rainy day skimming through the complete +// list of builtins in the official Zig documentation wouldn't be +// a bad use of your time. There are some seriously cool features +// in there. Check out @call, @compileLog, @embedFile, and @src! +// +// ... +// +// For now, we're going to complete our examination of builtins +// by exploring just THREE of Zig's MANY introspection abilities: +// +// 1. @This() type +// +// Returns the innermost struct, enum, or union that a function +// call is inside. +// +// 2. @typeInfo(comptime T: type) @import("std").builtin.TypeInfo +// +// Returns information about any type in a TypeInfo union which +// will contain different information depending on which type +// you're examining. +// +// 3. @TypeOf(...) type +// +// Returns the type common to all input parameters (each of which +// may be any expression). The type is resolved using the same +// "peer type resolution" process the compiler itself uses when +// inferring types. +// +// (Notice how the two functions which return types start with +// uppercase letters? This is a standard naming practice in Zig.) +// +const print = import(std).debug.print; // Oops! + +const Narcissus = struct { + me: *Narcissus = undefined, + myself: *Narcissus = undefined, + echo: void = undefined, + + fn fetchTheMostBeautifulType() type { + return @This(); + } +}; + +pub fn main() void { + var narcissus: Narcissus = Narcissus {}; + + // Oops! We cannot leave the 'me' and 'myself' fields + // undefined. Please set them here: + ??? = &narcissus; + ??? = &narcissus; + + // This determines a "peer type" from three separate + // references (they just happen to all be the same object). + const T1 = @TypeOf(narcissus, narcissus.me.*, narcissus.myself.*); + + // Oh dear, we seem to have done something wrong when calling + // this function. It is namespaced to the struct, but doesn't + // use the method syntax (there's no self parameter). Please + // fix this call: + const T2 = narcissus.fetchTheMostBeautifulType(); + + print("A {} loves all {}es. ", .{T1, T2}); + + // His final words as he was looking in + // those waters he habitually watched + // were these: + // "Alas, my beloved boy, in vain!" + // The place gave every word back in reply. + // He cried: + // "Farewell." + // And Echo called: + // "Farewell!" + // + // --Ovid, The Metamorphoses + // translated by Ian Johnston + + print("He has room in his heart for:", .{}); + + // A StructFields array + const fields = @typeInfo(Narcissus).Struct.fields; + + // 'fields' is an array of StructFields. Here's the declaration: + // + // pub const StructField = struct { + // name: []const u8, + // field_type: type, + // default_value: anytype, + // is_comptime: bool, + // alignment: comptime_int, + // }; + // + // Please complete these 'if' statements so that the field + // 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!): + if (fields[0].??? != void) { + print(" {s}", .{@typeInfo(Narcissus).Struct.fields[0].name}); + } + + if (fields[1].??? != void) { + print(" {s}", .{@typeInfo(Narcissus).Struct.fields[1].name}); + } + + if (fields[2].??? != void) { + print(" {s}", .{@typeInfo(Narcissus).Struct.fields[2].name}); + } + + // Yuck, look at all that repeated code above! I don't know + // about you, but it makes me itchy. + // + // Alas, we can't use a regular 'for' loop here because + // 'fields' can only be evaluated at compile time. It seems + // like we're overdue to learn about this "comptime" stuff, + // isn't it? :-) + + print(".\n", .{}); +} |