"99 bottles of beer" InstantView® Code Sample

 /* Song in English

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.

...

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.

*/

 /* Song in german

99 Flaschen Bier stehen im Regal, 99 Flaschen Bier.
Hol eine her und reich sie herum, 98 Flaschen Bier stehen im Regal.

98 Flaschen Bier stehen im Regal, 98 Flaschen Bier.
Hol eine her und reich sie herum, 97 Flaschen Bier stehen im Regal.

97 Flaschen Bier stehen im Regal, 97 Flaschen Bier.
Hol eine her und reich sie herum, 96 Flaschen Bier stehen im Regal.

...

3 Flaschen Bier stehen im Regal, 3 Flaschen Bier.
Hol eine her und reich sie herum, 2 Flaschen Bier stehen im Regal.

2 Flaschen Bier stehen im Regal, 2 Flaschen Bier.
Hol eine her und reich sie herum, 1 Flasche Bier steht im Regal.

1 Flasche Bier steht im Regal, 1 Flasche Bier.
Hol eine her und reich sie herum, keine Flasche Bier steht mehr im Regal.

Keine Flasche Bier steht mehr im Regal, keine Flasche Bier mehr.
Geh in den Laden und kauf welche ein, 99 Flaschen Bier stehen dann im Regal.

*/

Simple Version

Simple text output without caring about plural/singular (bottles(s)).

 
// Define macro
    Define(SingBottlesOfBeerSimple)
       Var(i)
       99 -> i
       ""
       do
         i "%s bottle(s) of beer on the wall, " String(STACK) + i "%s bottle(s) of beer.\n" String(STACK) +
         "Take one down and pass it around, " +
         Decr(i)
         i if {
           i "%s bottle(s)" String(STACK) +
         }
         else {
           "no more bottles" +
         }
         " of beer on the wall.\n\n" +
 
         i ifnot break
       loop

       "No more bottles of beer on the wall, no more bottles of beer.\n" +
       "Go to the store and buy some more, 99 bottles of beer on the wall." +
    ;

// Call macro
   SingBottlesOfBeerSimple


Monolingual version

More compact version with plural/singular form of "bottles". Macro is called with the number of bottles at the start.

 
// Define macro
   Define(SingBottlesOfBeerInEnglish)
     Var(i)
     1 + -> i
     ""
     do
       Decr(i)
       i Dup if { String Dup } else { Drop "o more" "n" Over + Swap "N" Swap + }
       "%s bottle" String(STACK) i 1 = ifnot { "s" + } Swap " of beer on the wall, %s bottle" String(STACK) i 1 = ifnot { "s" + } + " of beer.\n" + +
       i if {
          "Take one down and pass it around, " + i 1 - Dup if {
             "%s bottle" String(STACK) + i 2 > if { "s" + } }
          else {  Drop "no more bottles" + } " of beer on   the wall.\n\n" +
       }
       else { "Go to the store and buy some more, 99 bottles of beer on the wall." + break }
     loop
   ;

// Call macro with number of bottles
   100 SingBottlesOfBeerInEnglisch


Multilingual version

Two-lingual version in German and English. Before calling macro, the language is set with SetLanguage commando.
 
// Define macros
   Define(SetMLEnding)
     case
       0: T("t mehr im Regal", "")
       1: T("t im Regal", "")
       default: T("en im Regal", "")
     endCase  *
   ;

   Define(SingBottlesOfBeerML)
     Var(i) 1 + -> i
     T("", "")
     do
       Decr(i)
       i Dup if { String T("", "") Swap * Dup } else { Drop T("eine", "o more") T("k", "n") Over * Swap T("K", "N") Swap * }
       T(" Flasche", " bottle") * i 1 > if { T("n", "s") * } T(" Bier steh", " of beer on the wall, ") *
       i SetMLEnding T(", ", "") * Swap * T(" Flasche", " bottle") * i 1 > if { T("n", "s") * } * T(" Bier.\n", " of beer.\n") *
       i if {
         T("Hol eine her und reich sie herum, ", "Take one down and pass it around, ") *
          i 1 - Dup if { * T(" Flasche", " bottle") * i 2 > if { T("n", "s") * } } else { Drop T("keine Flasche", "no more bottles") * }
         T(" Bier steh", " of beer on the wall.\n\n") * i 1 - SetMLEnding T(".\n\n", "") *
       }
       else {
         T("Geh in den Laden und kauf welche ein, 99 Flaschen Bier stehen im Regal.", "Go to the store and buy some more, 99 bottles of beer on the wall.")         * break
       }
       loop
;

// Call macro with number of bottles
   100 SingBottlesOfBeerML

Version with units

Definition of the unit "bottle", plural form "bottles". This is used in a CX_VALUE object to have an arithmetically correct counting of bottles.
 
// Define macros
   Define(CheckForBottlesUnit)
     Var(unitParameter)
     NULL -> unitParameter
     0x00100000 SystemObject Call(UnitParameters)
     iterate {
       Dup Copy(Name(0)) T("Flaschen", "bottles") String = if { -> unitParameter break } else Drop
     }
     unitParameter ifnot {
       CreateTransObject(CX_UNIT_PARAMETER) -> unitParameter
       unitParameter Call(Fix)
       T("Flaschen", "bottles") unitParameter Put(Name(0))
       T("Flasche", "bottle") unitParameter Put(SingularForm(3))
       0x00100000 unitParameter Put(flags) // declare as packaging unit
       0 unitParameter Put(precision)
       unitParameter Call(MakePersistent)
    }
;

   Define(SingBottlesOfBeerWithUnits)
     CheckForBottlesUnit
     Var(bottles)
     T("0Flaschen", "0bottles") String CreateTransObject(CX_VALUE) Dup -> bottles Put
     0 bottles Call(SetPrecision)
     1 + bottles Put
     T("", "")
     do
       bottles Dup 1 -= Integer
      case
        0: T("Keine Flasche Bier steht mehr im Regal, keine Flasche Bier mehr.\n", "No more bottles of beer on the wall, no more bottles of beer.\n") *
            T("Geh in den Laden und kauf welche ein, 99 Flaschen Bier stehen dann im Regal.", "Go to the store and buy some more, 99 bottles of beer on the wall.") *
            break
         1: bottles * T(" Bier steht im Regal, ", " of beer on the wall, ") * bottles String * T(" Bier.\n", " of beer.\n") *
             T("Hol eine her und reich sie herum, keine Flasche Bier steht mehr im Regal.\n\n", "Take one down and pass it around, no more bottles of beer on   the wall.\n\n") *
         default: bottles * T(" Bier stehen im Regal, ", " of beer on the wall, ") * bottles String * T(" Bier.\n", " of beer.\n") *
          T("Hol eine her und reich sie herum, ", "Take one down and pass it around, ") *
         bottles 1 - Dup Integer
         case
            1: String * T(" Bier steht im Regal.\n\n", " of beer on the wall.\n\n") *
            default: String * T(" Bier stehen im Regal.\n\n", " of beer on the wall.\n\n") *
            endCase
        endCase
     loop
    ;

// Call macro with number of bottles
   100 SingBottlesOfBeerWithUnits

Version as service

Definition of macros in a separate module to be called from anywhere through message bus, e.g.

100 SendMsg(SING_BOTTLES_OF_BEER_IN_ENGLISH)

 
// Define module
Module(eva_bottlesOfBeer, HELP("eva_bottlesOfBeer"))
[
   Declare(SingBottlesOfBeerInEnglish, SingBottlesOfBeerML, SingBottlesOfBeerWithUnits)

   // Define service interface
   SING_BOTTLES_OF_BEER_IN_ENGLISH: SingBottlesOfBeerInEnglish Attention
   SING_BOTTLES_OF_BEER_ML : SingBottlesOfBeerML Attention
   SING_BOTTLES_OF_BEER_WITH_UNITS: SingBottlesOfBeerWithUnits Attention

//.... copy macro definitions from examples above into this part

] // close macro