From e780328b253dfd948ca84535767c98dd2adf383e Mon Sep 17 00:00:00 2001 From: Dave Gauer Date: Tue, 13 Apr 2021 20:47:05 -0400 Subject: [PATCH] Add ex066, the first comptime explanation --- build.zig | 5 ++ exercises/066_comptime.zig | 74 ++++++++++++++++++++++++++++++ patches/patches/066_comptime.patch | 6 +++ 3 files changed, 85 insertions(+) create mode 100644 exercises/066_comptime.zig create mode 100644 patches/patches/066_comptime.patch diff --git a/build.zig b/build.zig index 50fde90..0eaec0b 100644 --- a/build.zig +++ b/build.zig @@ -331,6 +331,11 @@ const exercises = [_]Exercise{ .main_file = "065_builtins2.zig", .output = "A Narcissus loves all Narcissuses. He has room in his heart for: me myself.", }, + .{ + .main_file = "066_comptime.zig", + .output = "const_int=12345, const_float=987.654, var_int=54321, var_float=456.789", + .hint = "It may help to read this one out loud to your favorite stuffed animal until it sinks in completely." + }, }; /// Check the zig version to make sure it can compile the examples properly. diff --git a/exercises/066_comptime.zig b/exercises/066_comptime.zig new file mode 100644 index 0000000..20a96a7 --- /dev/null +++ b/exercises/066_comptime.zig @@ -0,0 +1,74 @@ +// +// "Compile time" is a program's environment while it is being +// compiled. In contrast, "run time" is the environment while the +// compiled program is executing (traditionally as machine code +// on a hardware CPU). +// +// Errors make an easy example: +// +// 1. Compile-time error: caught by the compiler, usually +// resulting in a message to the programmer. +// +// 2. Runtime error: either caught by the running program itself +// or by the host hardware or operating system. Could be +// gracefully caught and handled or could cause the computer +// to crash (or halt and catch fire)! +// +// All compiled languages must perform a certain amount of logic +// at compile time in order to analyze the code, maintain a table +// of symbols (such as variable and function names), etc. +// +// Optimizing compilers can also figure out how much of a program +// can be pre-computed or "inlined" at compile time to make the +// resulting program more efficient. Smart compilers can even +// "unroll" loops, turning their logic into a fast linear +// sequence of statements (at the usually very slight expense of +// the increased size of the repeated code). +// +// Zig takes these concepts further by making these optimizations +// an integral part of the language itself! +// +const print = @import("std").debug.print; + +pub fn main() void { + // ALL numeric literals in Zig are of type comptime_int or + // comptime_float. They are of arbitary size (as big or + // little as you need). + // + // Notice how we don't have to specify a size like "u8", + // "i32", or "f64" when we assign identifiers immutably with + // "const". + // + // When we use these identifiers in our program, the VALUES + // are inserted at compile time into the executable code. The + // identifiers "my_int" and "my_float" don't really exist in + // our compiled application and do not refer to any + // particular areas of memory! + const const_int = 12345; + const const_float = 987.654; + + print("const_int={}, const_float={d:.3}, ", .{const_int, const_float}); + + // But something changes when we assign the exact same values + // to identifiers mutably with "var". + // + // The literals are STILL comptime_int and comptime_float, + // but we wish to assign them to identifiers which are + // mutable at runtime. + // + // To be mutable at runtime, these identifiers must refer to + // areas of memory. In order to refer to areas of memory, Zig + // must know exactly how much memory to reserve for these + // values. Therefore, it follows that we just specify numeric + // types with specific sizes. The comptime numbers will be + // coerced (if they'll fit!) into your chosen runtime types. + var var_int = 12345; + var var_float = 987.654; + + // We can change what is stored at the areas set aside for + // "var_int" and "var_float" in the running compiled program. + var_int = 54321; + var_float = 456.789; + + print("var_int={}, var_float={d:.3}\n", .{var_int, var_float}); +} diff --git a/patches/patches/066_comptime.patch b/patches/patches/066_comptime.patch new file mode 100644 index 0000000..e7130c2 --- /dev/null +++ b/patches/patches/066_comptime.patch @@ -0,0 +1,6 @@ +65,66c65,66 +< var var_int = 12345; +< var var_float = 987.654; +--- +> var var_int: u32 = 12345; +> var var_float: f32 = 987.654;