072_comptime7.zig 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. //
  2. // There is also an 'inline while'. Just like 'inline for', it
  3. // loops at compile time, allowing you to do all sorts of
  4. // interesting things not possible at runtime. See if you can
  5. // figure out what this rather bonkers example prints:
  6. //
  7. // const foo = [3]*const [5]u8{ "~{s}~", "<{s}>", "d{s}b" };
  8. // comptime var i = 0;
  9. //
  10. // inline while ( i < foo.len ) : (i += 1) {
  11. // print(foo[i] ++ "\n", .{foo[i]});
  12. // }
  13. //
  14. // You haven't taken off that wizard hat yet, have you?
  15. //
  16. const print = @import("std").debug.print;
  17. pub fn main() void {
  18. // Here is a string containing a series of arithmetic
  19. // operations and single-digit decimal values. Let's call
  20. // each operation and digit pair an "instruction".
  21. const instructions = "+3 *5 -2 *2";
  22. // Here is a u32 variable that will keep track of our current
  23. // value in the program at runtime. It starts at 0, and we
  24. // will get the final value by performing the sequence of
  25. // instructions above.
  26. var value: u32 = 0;
  27. // This "index" variable will only be used at compile time in
  28. // our loop.
  29. comptime var i = 0;
  30. // Here we wish to loop over each "instruction" in the string
  31. // at compile time.
  32. //
  33. // Please fix this to loop once per "instruction":
  34. ??? (i < instructions.len) : (???) {
  35. // This gets the digit from the "instruction". Can you
  36. // figure out why we subtract '0' from it?
  37. comptime var digit = instructions[i + 1] - '0';
  38. // This 'switch' statement contains the actual work done
  39. // at runtime. At first, this doesn't seem exciting...
  40. switch (instructions[i]) {
  41. '+' => value += digit,
  42. '-' => value -= digit,
  43. '*' => value *= digit,
  44. else => unreachable,
  45. }
  46. // ...But it's quite a bit more exciting than it first appears.
  47. // The 'inline while' no longer exists at runtime and neither
  48. // does anything else not touched directly by runtime
  49. // code. The 'instructions' string, for example, does not
  50. // appear anywhere in the compiled program because it's
  51. // not used by it!
  52. //
  53. // So in a very real sense, this loop actually converts
  54. // the instructions contained in a string into runtime
  55. // code at compile time. Guess we're compiler writers
  56. // now. See? The wizard hat was justified after all.
  57. }
  58. print("{}\n", .{value});
  59. }