| // written by Don Clugston: |
| // https://www.digitalmars.com/d/archives/digitalmars/D/announce/4374.html |
| // http://www.99-bottles-of-beer.net/language-d-1212.html |
| |
| // Generates the "99 bottles of beer" song at compile time, |
| // using the template metaprograming facilities of D. |
| // No executable is generated. No libraries are used. |
| // Illustrates template default values, template string value parameters, |
| // compile-time concatenation of constant strings, static if. |
| |
| module bottles99; |
| |
| template decimaldigit(int n) { |
| const string decimaldigit = "0123456789"[n..n+1]; |
| } |
| |
| template itoa(ulong n) |
| { |
| static if ( n < 10L ) |
| const string itoa = decimaldigit!(n); |
| else |
| const string itoa = itoa!( n / 10L ) ~ decimaldigit!( n % 10L ); |
| } |
| |
| template showHowMany(int n, string where, bool needcapital = false) |
| { |
| static if ( n > 1 ) |
| const string showHowMany = itoa!(n) ~ " bottles of beer" ~ where ~ "\n"; |
| else static if ( n == 1 ) |
| const string showHowMany = "1 bottle of beer" ~ where ~ "\n"; |
| else static if ( needcapital ) |
| const string showHowMany = "No more bottles of beer" ~ where ~ "\n"; |
| else |
| const string showHowMany = "no more bottles of beer" ~ where ~ "\n"; |
| } |
| |
| template beer(int maxbeers, int n = maxbeers) |
| { |
| static if ( n > 0 ) |
| const string beer = showHowMany!(n, " on the wall,", true) |
| ~ showHowMany!(n, ".") |
| ~ "Take one down and pass it around," ~ "\n" |
| ~ showHowMany!( n - 1 , " on the wall.") |
| ~ "\n" ~ beer!(maxbeers, n - 1); // recurse for subsequent verses. |
| else |
| const string beer = showHowMany!(n, " on the wall,", true) |
| ~ showHowMany!(n, ".") |
| ~ "Go to the store and buy some more," ~ "\n" |
| ~ showHowMany!( maxbeers, " on the wall."); |
| } |
| |
| enum expected = `99 bottles of beer on the wall, |
| 99 bottles of beer. |
| Take one down and pass it around, |
| 98 bottles of beer on the wall. |
| |
| 98 bottles of beer on the wall, |
| 98 bottles of beer. |
| Take one down and pass it around, |
| 97 bottles of beer on the wall. |
| |
| 97 bottles of beer on the wall, |
| 97 bottles of beer. |
| Take one down and pass it around, |
| 96 bottles of beer on the wall. |
| |
| 96 bottles of beer on the wall, |
| 96 bottles of beer. |
| Take one down and pass it around, |
| 95 bottles of beer on the wall. |
| |
| 95 bottles of beer on the wall, |
| 95 bottles of beer. |
| Take one down and pass it around, |
| 94 bottles of beer on the wall. |
| |
| 94 bottles of beer on the wall, |
| 94 bottles of beer. |
| Take one down and pass it around, |
| 93 bottles of beer on the wall. |
| |
| 93 bottles of beer on the wall, |
| 93 bottles of beer. |
| Take one down and pass it around, |
| 92 bottles of beer on the wall. |
| |
| 92 bottles of beer on the wall, |
| 92 bottles of beer. |
| Take one down and pass it around, |
| 91 bottles of beer on the wall. |
| |
| 91 bottles of beer on the wall, |
| 91 bottles of beer. |
| Take one down and pass it around, |
| 90 bottles of beer on the wall. |
| |
| 90 bottles of beer on the wall, |
| 90 bottles of beer. |
| Take one down and pass it around, |
| 89 bottles of beer on the wall. |
| |
| 89 bottles of beer on the wall, |
| 89 bottles of beer. |
| Take one down and pass it around, |
| 88 bottles of beer on the wall. |
| |
| 88 bottles of beer on the wall, |
| 88 bottles of beer. |
| Take one down and pass it around, |
| 87 bottles of beer on the wall. |
| |
| 87 bottles of beer on the wall, |
| 87 bottles of beer. |
| Take one down and pass it around, |
| 86 bottles of beer on the wall. |
| |
| 86 bottles of beer on the wall, |
| 86 bottles of beer. |
| Take one down and pass it around, |
| 85 bottles of beer on the wall. |
| |
| 85 bottles of beer on the wall, |
| 85 bottles of beer. |
| Take one down and pass it around, |
| 84 bottles of beer on the wall. |
| |
| 84 bottles of beer on the wall, |
| 84 bottles of beer. |
| Take one down and pass it around, |
| 83 bottles of beer on the wall. |
| |
| 83 bottles of beer on the wall, |
| 83 bottles of beer. |
| Take one down and pass it around, |
| 82 bottles of beer on the wall. |
| |
| 82 bottles of beer on the wall, |
| 82 bottles of beer. |
| Take one down and pass it around, |
| 81 bottles of beer on the wall. |
| |
| 81 bottles of beer on the wall, |
| 81 bottles of beer. |
| Take one down and pass it around, |
| 80 bottles of beer on the wall. |
| |
| 80 bottles of beer on the wall, |
| 80 bottles of beer. |
| Take one down and pass it around, |
| 79 bottles of beer on the wall. |
| |
| 79 bottles of beer on the wall, |
| 79 bottles of beer. |
| Take one down and pass it around, |
| 78 bottles of beer on the wall. |
| |
| 78 bottles of beer on the wall, |
| 78 bottles of beer. |
| Take one down and pass it around, |
| 77 bottles of beer on the wall. |
| |
| 77 bottles of beer on the wall, |
| 77 bottles of beer. |
| Take one down and pass it around, |
| 76 bottles of beer on the wall. |
| |
| 76 bottles of beer on the wall, |
| 76 bottles of beer. |
| Take one down and pass it around, |
| 75 bottles of beer on the wall. |
| |
| 75 bottles of beer on the wall, |
| 75 bottles of beer. |
| Take one down and pass it around, |
| 74 bottles of beer on the wall. |
| |
| 74 bottles of beer on the wall, |
| 74 bottles of beer. |
| Take one down and pass it around, |
| 73 bottles of beer on the wall. |
| |
| 73 bottles of beer on the wall, |
| 73 bottles of beer. |
| Take one down and pass it around, |
| 72 bottles of beer on the wall. |
| |
| 72 bottles of beer on the wall, |
| 72 bottles of beer. |
| Take one down and pass it around, |
| 71 bottles of beer on the wall. |
| |
| 71 bottles of beer on the wall, |
| 71 bottles of beer. |
| Take one down and pass it around, |
| 70 bottles of beer on the wall. |
| |
| 70 bottles of beer on the wall, |
| 70 bottles of beer. |
| Take one down and pass it around, |
| 69 bottles of beer on the wall. |
| |
| 69 bottles of beer on the wall, |
| 69 bottles of beer. |
| Take one down and pass it around, |
| 68 bottles of beer on the wall. |
| |
| 68 bottles of beer on the wall, |
| 68 bottles of beer. |
| Take one down and pass it around, |
| 67 bottles of beer on the wall. |
| |
| 67 bottles of beer on the wall, |
| 67 bottles of beer. |
| Take one down and pass it around, |
| 66 bottles of beer on the wall. |
| |
| 66 bottles of beer on the wall, |
| 66 bottles of beer. |
| Take one down and pass it around, |
| 65 bottles of beer on the wall. |
| |
| 65 bottles of beer on the wall, |
| 65 bottles of beer. |
| Take one down and pass it around, |
| 64 bottles of beer on the wall. |
| |
| 64 bottles of beer on the wall, |
| 64 bottles of beer. |
| Take one down and pass it around, |
| 63 bottles of beer on the wall. |
| |
| 63 bottles of beer on the wall, |
| 63 bottles of beer. |
| Take one down and pass it around, |
| 62 bottles of beer on the wall. |
| |
| 62 bottles of beer on the wall, |
| 62 bottles of beer. |
| Take one down and pass it around, |
| 61 bottles of beer on the wall. |
| |
| 61 bottles of beer on the wall, |
| 61 bottles of beer. |
| Take one down and pass it around, |
| 60 bottles of beer on the wall. |
| |
| 60 bottles of beer on the wall, |
| 60 bottles of beer. |
| Take one down and pass it around, |
| 59 bottles of beer on the wall. |
| |
| 59 bottles of beer on the wall, |
| 59 bottles of beer. |
| Take one down and pass it around, |
| 58 bottles of beer on the wall. |
| |
| 58 bottles of beer on the wall, |
| 58 bottles of beer. |
| Take one down and pass it around, |
| 57 bottles of beer on the wall. |
| |
| 57 bottles of beer on the wall, |
| 57 bottles of beer. |
| Take one down and pass it around, |
| 56 bottles of beer on the wall. |
| |
| 56 bottles of beer on the wall, |
| 56 bottles of beer. |
| Take one down and pass it around, |
| 55 bottles of beer on the wall. |
| |
| 55 bottles of beer on the wall, |
| 55 bottles of beer. |
| Take one down and pass it around, |
| 54 bottles of beer on the wall. |
| |
| 54 bottles of beer on the wall, |
| 54 bottles of beer. |
| Take one down and pass it around, |
| 53 bottles of beer on the wall. |
| |
| 53 bottles of beer on the wall, |
| 53 bottles of beer. |
| Take one down and pass it around, |
| 52 bottles of beer on the wall. |
| |
| 52 bottles of beer on the wall, |
| 52 bottles of beer. |
| Take one down and pass it around, |
| 51 bottles of beer on the wall. |
| |
| 51 bottles of beer on the wall, |
| 51 bottles of beer. |
| Take one down and pass it around, |
| 50 bottles of beer on the wall. |
| |
| 50 bottles of beer on the wall, |
| 50 bottles of beer. |
| Take one down and pass it around, |
| 49 bottles of beer on the wall. |
| |
| 49 bottles of beer on the wall, |
| 49 bottles of beer. |
| Take one down and pass it around, |
| 48 bottles of beer on the wall. |
| |
| 48 bottles of beer on the wall, |
| 48 bottles of beer. |
| Take one down and pass it around, |
| 47 bottles of beer on the wall. |
| |
| 47 bottles of beer on the wall, |
| 47 bottles of beer. |
| Take one down and pass it around, |
| 46 bottles of beer on the wall. |
| |
| 46 bottles of beer on the wall, |
| 46 bottles of beer. |
| Take one down and pass it around, |
| 45 bottles of beer on the wall. |
| |
| 45 bottles of beer on the wall, |
| 45 bottles of beer. |
| Take one down and pass it around, |
| 44 bottles of beer on the wall. |
| |
| 44 bottles of beer on the wall, |
| 44 bottles of beer. |
| Take one down and pass it around, |
| 43 bottles of beer on the wall. |
| |
| 43 bottles of beer on the wall, |
| 43 bottles of beer. |
| Take one down and pass it around, |
| 42 bottles of beer on the wall. |
| |
| 42 bottles of beer on the wall, |
| 42 bottles of beer. |
| Take one down and pass it around, |
| 41 bottles of beer on the wall. |
| |
| 41 bottles of beer on the wall, |
| 41 bottles of beer. |
| Take one down and pass it around, |
| 40 bottles of beer on the wall. |
| |
| 40 bottles of beer on the wall, |
| 40 bottles of beer. |
| Take one down and pass it around, |
| 39 bottles of beer on the wall. |
| |
| 39 bottles of beer on the wall, |
| 39 bottles of beer. |
| Take one down and pass it around, |
| 38 bottles of beer on the wall. |
| |
| 38 bottles of beer on the wall, |
| 38 bottles of beer. |
| Take one down and pass it around, |
| 37 bottles of beer on the wall. |
| |
| 37 bottles of beer on the wall, |
| 37 bottles of beer. |
| Take one down and pass it around, |
| 36 bottles of beer on the wall. |
| |
| 36 bottles of beer on the wall, |
| 36 bottles of beer. |
| Take one down and pass it around, |
| 35 bottles of beer on the wall. |
| |
| 35 bottles of beer on the wall, |
| 35 bottles of beer. |
| Take one down and pass it around, |
| 34 bottles of beer on the wall. |
| |
| 34 bottles of beer on the wall, |
| 34 bottles of beer. |
| Take one down and pass it around, |
| 33 bottles of beer on the wall. |
| |
| 33 bottles of beer on the wall, |
| 33 bottles of beer. |
| Take one down and pass it around, |
| 32 bottles of beer on the wall. |
| |
| 32 bottles of beer on the wall, |
| 32 bottles of beer. |
| Take one down and pass it around, |
| 31 bottles of beer on the wall. |
| |
| 31 bottles of beer on the wall, |
| 31 bottles of beer. |
| Take one down and pass it around, |
| 30 bottles of beer on the wall. |
| |
| 30 bottles of beer on the wall, |
| 30 bottles of beer. |
| Take one down and pass it around, |
| 29 bottles of beer on the wall. |
| |
| 29 bottles of beer on the wall, |
| 29 bottles of beer. |
| Take one down and pass it around, |
| 28 bottles of beer on the wall. |
| |
| 28 bottles of beer on the wall, |
| 28 bottles of beer. |
| Take one down and pass it around, |
| 27 bottles of beer on the wall. |
| |
| 27 bottles of beer on the wall, |
| 27 bottles of beer. |
| Take one down and pass it around, |
| 26 bottles of beer on the wall. |
| |
| 26 bottles of beer on the wall, |
| 26 bottles of beer. |
| Take one down and pass it around, |
| 25 bottles of beer on the wall. |
| |
| 25 bottles of beer on the wall, |
| 25 bottles of beer. |
| Take one down and pass it around, |
| 24 bottles of beer on the wall. |
| |
| 24 bottles of beer on the wall, |
| 24 bottles of beer. |
| Take one down and pass it around, |
| 23 bottles of beer on the wall. |
| |
| 23 bottles of beer on the wall, |
| 23 bottles of beer. |
| Take one down and pass it around, |
| 22 bottles of beer on the wall. |
| |
| 22 bottles of beer on the wall, |
| 22 bottles of beer. |
| Take one down and pass it around, |
| 21 bottles of beer on the wall. |
| |
| 21 bottles of beer on the wall, |
| 21 bottles of beer. |
| Take one down and pass it around, |
| 20 bottles of beer on the wall. |
| |
| 20 bottles of beer on the wall, |
| 20 bottles of beer. |
| Take one down and pass it around, |
| 19 bottles of beer on the wall. |
| |
| 19 bottles of beer on the wall, |
| 19 bottles of beer. |
| Take one down and pass it around, |
| 18 bottles of beer on the wall. |
| |
| 18 bottles of beer on the wall, |
| 18 bottles of beer. |
| Take one down and pass it around, |
| 17 bottles of beer on the wall. |
| |
| 17 bottles of beer on the wall, |
| 17 bottles of beer. |
| Take one down and pass it around, |
| 16 bottles of beer on the wall. |
| |
| 16 bottles of beer on the wall, |
| 16 bottles of beer. |
| Take one down and pass it around, |
| 15 bottles of beer on the wall. |
| |
| 15 bottles of beer on the wall, |
| 15 bottles of beer. |
| Take one down and pass it around, |
| 14 bottles of beer on the wall. |
| |
| 14 bottles of beer on the wall, |
| 14 bottles of beer. |
| Take one down and pass it around, |
| 13 bottles of beer on the wall. |
| |
| 13 bottles of beer on the wall, |
| 13 bottles of beer. |
| Take one down and pass it around, |
| 12 bottles of beer on the wall. |
| |
| 12 bottles of beer on the wall, |
| 12 bottles of beer. |
| Take one down and pass it around, |
| 11 bottles of beer on the wall. |
| |
| 11 bottles of beer on the wall, |
| 11 bottles of beer. |
| Take one down and pass it around, |
| 10 bottles of beer on the wall. |
| |
| 10 bottles of beer on the wall, |
| 10 bottles of beer. |
| Take one down and pass it around, |
| 9 bottles of beer on the wall. |
| |
| 9 bottles of beer on the wall, |
| 9 bottles of beer. |
| Take one down and pass it around, |
| 8 bottles of beer on the wall. |
| |
| 8 bottles of beer on the wall, |
| 8 bottles of beer. |
| Take one down and pass it around, |
| 7 bottles of beer on the wall. |
| |
| 7 bottles of beer on the wall, |
| 7 bottles of beer. |
| Take one down and pass it around, |
| 6 bottles of beer on the wall. |
| |
| 6 bottles of beer on the wall, |
| 6 bottles of beer. |
| Take one down and pass it around, |
| 5 bottles of beer on the wall. |
| |
| 5 bottles of beer on the wall, |
| 5 bottles of beer. |
| Take one down and pass it around, |
| 4 bottles of beer on the wall. |
| |
| 4 bottles of beer on the wall, |
| 4 bottles of beer. |
| Take one down and pass it around, |
| 3 bottles of beer on the wall. |
| |
| 3 bottles of beer on the wall, |
| 3 bottles of beer. |
| Take one down and pass it around, |
| 2 bottles of beer on the wall. |
| |
| 2 bottles of beer on the wall, |
| 2 bottles of beer. |
| Take one down and pass it around, |
| 1 bottle of beer on the wall. |
| |
| 1 bottle of beer on the wall, |
| 1 bottle of beer. |
| Take one down and pass it around, |
| no more bottles of beer on the wall. |
| |
| No more bottles of beer on the wall, |
| no more bottles of beer. |
| Go to the store and buy some more, |
| 99 bottles of beer on the wall. |
| `; |
| |
| static assert(beer!(99) == expected); |