DAL

    Apple's Data Access Language
    /*
    DAL version of 99 Bottles of beer programmer:
    by Georg Hentsch: ghentsch@blsoft.com
    */
    
    declare integer beers = 99;
    declare varchar s;
    
    while (beers > 0)
    {
    	if (beers != 1)
    		s = "s";
    	else
    		s = "";
    	printf("%d bottle%s of beer on the wall,\n", beers, s);
    	printf("%d bottle%s of beeeeer . . . ,\n", beers, s);
    	printf("Take one down, pass it around,\n");
    
    	beers--;
    	if (beers > 0)
    		printf("%d", beers);
    	else
    		printf("No more");
    	if (beers != 1)
    		s = "s";
    	else
    		s = "";
    	printf(" bottle%s of beer on the wall.\n", s);
    }
    

    DOS Batch

    @echo off
    REM 99 Bottles of Beer in DOS Batch
    REM Gert-jan Los (los@lsdb.bwl.uni-mannheim.de)
    
    if "%1"=="" goto outer
    if "%1"=="body" goto body
    :inner
    for %%a in ( 9 8 7 6 5 4 3 2 1 0 ) do call beer body %2 %%a
    goto exit
    
    :outer
    for %%a in ( 9 8 7 6 5 4 3 2 1 0 ) do call beer inner %%a
    goto exit
    
    :body
    set num=%2%3
    set bottle=bottles
    if "%num%"=="99" goto skipfirst
    if "%2"=="0" set num=%3
    if "%num%"=="1" set bottle=bottle
    echo %num% %bottle% of beer on the wall
    echo.
    if "%num%"=="0" exit
    :skipfirst
    echo %num% %bottle% of beer on the wall
    echo %num% %bottle% of beer
    echo take one down and pass it around
    :exit
    
    

    Fortran

    C     patrick m. ryan pryan@access.digex.net
          program ninetynine
          implicit none
          integer i
    
          do i=99,1,-1
            print*, i,' bottles of beer on the wall, ',i,' bottles of beer'
            print*, 'take one down, pass it around, ',i-1,
         .       ' bottles of beer on the wall'
          enddo
          end
    

    Forth

    \ Forth version of the 99 Bottles program.
    \ Dan Reish, dreish@izzy.net
    
    : .bottles ( n -- n-1 )
       dup 1 = IF  ." One bottle of beer on the wall," CR
    	       ." One bottle of beer," CR
    	       ." Take it down," 
       ELSE  dup . ." bottles of beer on the wall," CR
    	 dup . ." bottles of beer," CR
    	 ." Take one down," 
       THEN
       CR
       ." Pass it around," CR
       1-
       ?dup IF  dup 1 = IF  ." One bottle of beer on the wall;" 
    	    ELSE  dup . ." bottles of beer on the wall;" 
    	    THEN
    	ELSE  ." No more bottles of beer on the wall." 
       THEN
       CR
    ;
    
    : nbottles ( n -- )
      BEGIN  .bottles  ?dup NOT UNTIL
    ;
    
    99 nbottles
    
    

    Fortran IV

    C Allen Mcintosh
    C mcintosh@bellcore.com 
          integer bottls
          do 50 i = 1, 99
             bottls = 100 - i
             print 10, bottls
    10       format(1x, i2, 31h bottle(s) of beer on the wall.)
             print 20, bottls
    20       format(1x, i2, 19h bottle(s) of beer.)
             print 30
    30       format(34h Take one down and pass it around,)
             bottls = bottls - 1
             print 10, bottls
             print 40
    40       format(1x)
    50    continue
          stop
          end
    
    

    Emacs Lisp

    ;;Geza Gyuk - gyuk@oddjob.uchicago.edu"
    
    (defun beersong (n)
      "Does the n-beers song."
    
    (progn (insert (int-to-string n) " bottle" (cond ((= n 1) "")
                                                     (t "s")) 
                                             " of beer on the wall,\n")
           (insert (int-to-string n) " bottle" (cond ((= n 1) "")
                                                     (t "s"))
                                             " of beer,\n")
           (insert "take one down and pass it around,\n")
           (insert (cond ((= n 1) "no more")
                         (t (int-to-string (- n 1)))) 
                   " bottle" (cond ((= n 2) "")
                                   (t "s")) 
                   " of beer on the wall.\n\n")
           (cond ((> n 1) (beersong (- n 1))))))
    
    

    hackMongo

    hackMongo is an extension of the Mongo plotting package.
    ! Does the beer song... sends output to a postscript file
    ! Geza Gyuk - gyuk@oddjob.uchicago.edu
    
    printer 1
    erase
    
    data beer.dat
    setv rounds c1(1)                       ! get number of rounds
                                            ! from first line, first
    setv container bottles                  ! column of file beer.dat
    expand {5/rounds}
    loop i {rounds} 2 -1
       relocate 0.1 {i*5/(5*rounds)}
       putlabel 6 {i} bottles of beer on the wall,
       relocate 0.1 {(i*5-1)/(5*rounds)}
       putlabel 6 {i} bottles of beer,
       relocate 0.1 {(i*5-2)/(5*rounds)}
       putlabel 6 take one down and pass it around,
       if ({i}=2) setv container bottle
       relocate 0.1 {(i*5-3)/(5*rounds)}
       putlabel 6 {i-1} {container} of beer on the wall.
       relocate 0.1 {(i*5-4)/(5*rounds)}
       putlabel 6
    endloop
    
    relocate 0.1 {5/(5*rounds)}
    putlabel 6 1 bottle of beer on the wall,
    relocate 0.1 {4/(5*rounds)}
    putlabel 6 1 bottle of beer,
    relocate 0.1 {3/(5*rounds)}
    putlabel 6 take it down and pass it around,
    relocate 0.1 {2/(5*rounds)}
    putlabel 6 no more bottles of beer on the wall.
    
    hardcopy
    end
    
    

    Delphi

    Note: Borland's Delphi only runs under Windows, so the simple task of dumping the text to standard output isn't so simple any more. The large body of code is to account for the Windows interface.
    {----------------------------------------------------------------------}
    {Contents of BEER99.DPR}
    program Beer99;
    
    {99 bottles of beer - Borland Delphi 1.0}
    {by Rodney M. Savard <rodney.savard%phun@phunnet.org>}
    
    uses
      Forms,
      Beer in 'BEER.PAS' {Form1};
    
    {$R *.RES}
    
    begin
      Application.CreateForm(TForm1, Form1);
      Application.Run;
    end.
    
    {----------------------------------------------------------------------}
    {Contents of BEER.PAS}
    unit Beer;
    
    interface
    
    uses
      Classes, Controls, Forms, StdCtrls, SysUtils;
    
    type
      TForm1 = class(TForm)
        Memo1: TMemo;
        Button1: TButton;
        procedure FormCreate(Sender: TObject);
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    
    var
      Form1: TForm1;
      Bottles: Integer;
      s: String;
    
    implementation
    
    {$R *.DFM}
    
    procedure TakeOneDown;
    begin
       with Form1 do begin
          Memo1.Lines.Clear;
          Memo1.Lines.Add(IntToStr(bottles)+' bottle'+s+' of beer on the wall,');
          Memo1.Lines.Add(IntToStr(bottles)+' bottle'+s+' of beer.');
          Memo1.Lines.Add('');
          Memo1.Lines.Add('Take one down, pass it around,');
    
          Dec(Bottles);
          if Bottles<>1 then s:='s' else s:='';
    
          if Bottles=0 then begin
             Memo1.Lines.Add('no more bottles of beer on the wall!');
             Button1.Caption:='No More!';
             Button1.Enabled:=False;
          end
          else begin
             Memo1.Lines.Add(IntToStr(bottles)+' bottle'+s+' of beer on the wall.');
          end;
       end;
    end;
    
    procedure TForm1.FormCreate(Sender: TObject);
    begin
       Bottles:=99;
       s:='s';
       Button1Click(Form1);
    end;
    
    procedure TForm1.Button1Click(Sender: TObject);
    begin
       TakeOneDown;
    end;
    
    end.
    {----------------------------------------------------------------------}
    
    

    Dylan

    // Dylan version of 99 Bottles of Beer
    // programmer: Jim Studt jim@federated.com
    
    define method enumerate( count == 1 ) "1 bottle" end method enumerate;
    define method enumerate( count == 0 ) "no more bottles" end method enumerate;
    define method enumerate( count :: <integer> )
      format-to-string("%d bottles", count);
    end method enumerate;
    
    define method reference( count == 1) "it" end method reference;
    define method reference( count :: <integer>) "one" end method reference;
    
    define method main (argv0, #rest noise)
      for ( i from 99 to 1 by -1) 
        format( *standard-output*, "%s of beer on the wall, %s of beer.\n", 
    	   enumerate(i), enumerate(i));
        format( *standard-output*, 
    	   "  Take %s down, pass it around, %s of beer on the wall.\n",
    	   reference(i), enumerate( i - 1));
      end for;
    end method main;
    

    Eiffel

    Click for information.
    class BEERS
    
    creation
    
        make
    
    feature     -- Creation
    
        make is
            local
                i : INTEGER
                b : STRING;
            do
                from i := 99 variant i until i <= 0 loop
                    if i = 1 then
                        b := " bottle";
                    else
                        b := " bottles"
                    end -- if
                    io.put_integer(i);
                    io.put_string(b);
                    io.put_string(" of beer on the wall, ");
                    io.put_integer(i);
                    io.put_string(b);
                    io.put_string(" of beer,");
                    io.new_line;
                    io.put_string("Take one down and pass it around, ");
                    i := i - 1;
                    io.put_integer(i);
                    io.put_string(b);
                    io.put_string(" bottles of beer on the wall.");
                    io.new_line;
                end -- loop
                io.put_string("Go to the store and buy some more,");
                io.new_line;
                io.put_string("99 bottles of beer on the wall.");
                io.new_line;
            end;
    
    end -- class BEERS
    
    Here is the OOP version of this in Eiffel... that is to say, the "proper" way to do Eiffel:
    class SHELF
    
          -- A shelf of bottles
    
    creation
    
       make
    
    feature
    
       make (l_bottles: INTEGER) is
          require
             positive_bottles: l_bottles >= 0
          do
             bottles := l_bottles
          end
    
       remove is
          require
             bottles_exist: bottles > 0
          do
             bottles := bottles - 1
          ensure
             removed: bottles = old bottles - 1
          end
    
       bottles: INTEGER
    
       short_description: STRING is
          do
             if bottles = 0 then
                Result := "No"
             else
                Result := bottles.out
             end
             Result.append (" bottle")
             if bottles /= 1 then
                Result.append ("s")
             end
             Result.append (" of beer")
          ensure
             result_exists: Result /= Void
          end
    
       description: STRING is
          do
             Result := short_description
             Result.append (" on the wall, ")
             Result.append (short_description)
             Result.append ("%N")
          ensure
             result_exists: Result /= Void
          end
    
       empty: BOOLEAN is
          do
             Result := bottles = 0
          end
    
    invariant
    
       positive_bottles: bottles >= 0
             
    end -- class SHELF
    
    class BEER
    
       -- Produuce the ditty
       -- Nick Leaton
    
    creation
    
       make
    
    feature
    
       shelf: SHELF
    
       make is
          do
             from
                !!shelf.make (99)
             until
                shelf.empty
             loop
                io.put_string (shelf.description)
                shelf.remove
                io.put_string ("Take one down, pass it all around%N%N")
             end
             io.put_string (shelf.description)
             io.put_string ("Go to the store and buy some more%N%N")
             shelf.make (99)
             io.put_string (shelf.description)
          end   
                
    end -- class BEER
    
    

    Erlang

    Erlang is a language used for real-time control systems.
    % ---------------------------------------------------------------
    % Erlang version of the beer song
    % Kent Engström, kenen@ida.liu.se
    % ---------------------------------------------------------------
    % See http://www.ericsson.se/cslab/erlang/ for Erlang information
    % ---------------------------------------------------------------
    
    -module(beer).
    -export([song/0]).
    
    song() ->
        song(100).
    
    song(0) ->
        done;
    song(N) ->
        Bottles=bottles(N),
        Bottles1=bottles(N-1),
        io:format("~s of beer on the wall, ~s of beer.~n",
    	      [Bottles,Bottles]),
        io:format("Take one down and pass it around, ~s of beer on the wall.~n",
    	      [Bottles1]),
        song(N-1).
    
    bottles(0)->
        "no more bottles";
    bottles(1)->
        "1 bottle";
    bottles(N)->
        lists:append(integer_to_list(N)," bottles").
    

    Focal

    01.10 c Focal-8 version of 99 Bottles of beer
    01.20 c Hacked by Akira KIDA, <SDI00379@niftyserve.or.jp>
    
    10.10 set bottles = 99
    10.20 do 20
    10.30 quit
    
    20.10 for i = bottles, 1, -1; do 30
    20.20 return
    
    30.10 set b = i
    30.20 do 40 ; type " on the wall, "
    30.30 do 40 ; type ".", ! , "Take one down, pass it around.", !
    30.40 set b = i - 1
    30.50 do 40 ; type " on the wall.", !, !
    30.60 return
    
    40.10 do 50
    40.20 type " of beer"
    40.30 return
    
    50.10 if (b - 1) 50.20, 50.40, 50.60
    50.20 type "No more bottles"
    50.30 return
    50.40 type %1.0, b, " bottle"
    50.50 return
    50.60 type %1.0, b, " bottles"
    50.70 return
    

    DECTPU

    DEC's Pascal-like "Text Processing Utility."
    PROCEDURE BEER
              LOCAL BOTTLES, LINE_1, LINE_2, LINE_3;
    
              BOTTLES := 99;
              LINE_1 := "!SL bottle!%S of beer on the wall";
              LINE_2 := "!SL bottle!%S of beer,";
              LINE_3 := "If !0!1%Cthat single bottle"
                      + "!%Eone of those bottles!%F should happen to fall,";
              LOOP;
                   COPY_TEXT( FAO( LINE_1, BOTTLES) + ","); SPLIT_LINE;
                   COPY_TEXT( FAO( LINE_2, BOTTLES));       SPLIT_LINE;
                   COPY_TEXT( FAO( LINE_3, BOTTLES));       SPLIT_LINE;
                   BOTTLES := BOTTLES - 1;
                   COPY_TEXT( FAO( LINE_1, BOTTLES) + "."); SPLIT_LINE;
    SPLIT_LINE;
                   EXITIF BOTTLES = 0;
              ENDLOOP;
    ENDPROCEDURE
    

    False

    The False language was created by Wouter van Oortmerssen (Wouter@alf.let.uva.nl).
    { False version of 99 Bottles by Marcus Comstedt (marcus@lysator.liu.se) }
    [$0=["no more bottles"]?$1=["One bottle"]?$1>[$." bottles"]?%" of beer"]b:
    100[$0>][$b;!" on the wall, "$b;!".
    "1-"Take one down, pass it around, "$b;!" on the wall.
    "]#%
    

    Hope

    Click for more information.
    ! Hope Version of 99 Bottles of Beer : RAM-Biter!!!
    ! Tested on a SPARC classic, SunSolaris 2 
    ! Programmer: Wolfgang Lohmann   wlohmann@informatik.uni-rostock.de
     
    dec app  :( list ( char ) X list ( char )) -> list ( char ) ;
    dec i2c  : num -> char;
    dec i2s  : num -> list(char);
    dec beer : num -> list(char);
    
    --- app ( nil , w )
           <= w  ;
    --- app (( a  ::  v ), w )
           <=( a  ::  app ( v , w )) ;
    
    --- i2c(0) <= '0';
    --- i2c(1) <= '1';
    --- i2c(2) <= '2';
    --- i2c(3) <= '3';
    --- i2c(4) <= '4';
    --- i2c(5) <= '5';
    --- i2c(6) <= '6';
    --- i2c(7) <= '7';
    --- i2c(8) <= '8';
    --- i2c(9) <= '9';
    
    --- i2s(x) <= if x < 10 then [i2c(x)] else
    				app(i2s(x div 10), i2s( x mod 10)); 
    
    --- beer(x) <= if x = 1 then app( i2s(x), 
    				" bottle of beer. No more beer on the wall.")
                    	else app( app( app( app( app( 
    				i2s(x), 
    				" bottles of beer on the wall, "),
    				i2s(x)), 
    				" bottles of beer. "),
    				"Take one down, pass it around. "), 
    				beer(y))
                            where y== x-1;
    

    Haskell

    Click for more information.
    -- Haskell program for the Beer Song.
    --
    -- Bert Thompson 5.11.95 (aet@cs.mu.oz.au)
    
    module Main where
    
    main = song 99
    
    song n =
            bob n ++ " on the wall,\n" ++
            bob n ++ ".\n" ++
            "Take one down, pass it around.\n"  ++
            if n == 1
            then
                    "No more bottles of beer on the wall.\n"
            else
                    bob (n-1) ++ " on the wall.\n"
                    ++ song (n-1)
    
    bob n =
            show n ++ bottle ++ " of beer"
            where
            bottle = " bottle" ++ if n == 1 then "" else "s"
    

    Fortran 90

    !  F90 (Fortran 90) version of 99 bottles of beer.
    !    written by Akira KIDA,  SDI00379@niftyserver.or.jp
    !    Note that this source is in FIXED format.
    
    	program ninetynine
    	implicit none
    	integer, parameter :: BOTTLES = 99
    	integer :: i
    	integer :: k
    	character*7 :: btl = 'bottles'
    
    	do i = BOTTLES, 1, -1
    		k = len(btl)
    		if (i == 1) k = k - 1
    		print *, i, btl(1:k), ' of beer on the wall, ',
         c			 i, btl(1:k), ' of beer.'
    		print *, 'Take one down, pass it around.'
    		if (i == 0) exit
    		print *, i, btl(1:k), ' of beer on the wall.'
    	end do
    	print *, 'No more bottles of beer on the wall.'
    	end
    

    Forms/3

    Programming in Forms/3 follows the spreadsheet paradigm; the programmer uses direct manipulation to place cells on forms, and then defines a formula for each cell. Click here for more information.


    DIBOL

    .TITLE - "Program to display 99 bottles of beer on the wall"
    ;
    ;=======================================================================================================
    ;	Author: Bob Welton (welton@pui.com)
    ;		Projects Unlimited Inc.
    ;		Dayton, OH  45414
    ;
    ;	Language: DIBOL or DBL
    ;=======================================================================================================
    
    RECORD MISC
        NUMBOTTLES	,D2,99			;Default # of bottles to 99
        ANUMBOTTLES	,A2			;Used to mask the output of bottles
    
    
    .PROC
        XCALL FLAGS (0007000000,1)		;Suppress STOP message
        OPEN (8,O:C,"TT:")        		;Open the terminal/display
        REPEAT
    	BEGIN
    	ANUMBOTTLES = NUMBOTTLES,'ZX'
    	WRITES (8,ANUMBOTTLES+" Bottles of Beer on the wall,")
    	ANUMBOTTLES = NUMBOTTLES,'ZX'
    	WRITES (8,ANUMBOTTLES+" Bottles of Beer,")
    	WRITES (8,"   Take one down, pass it around,")
    	DECR NUMBOTTLES	      		;Reduce # of bottles by 1
    	IF (NUMBOTTLES .LE. 1) EXITLOOP	;If just 1 bottle left, get out
    	ANUMBOTTLES = NUMBOTTLES,'ZX'
    	WRITES(8,ANUMBOTTLES+" Bottles of Beer on the wall.") 
    	WRITES (8," ")
    	END
        ANUMBOTTLES = NUMBOTTLES,'ZX'
        WRITES(8,ANUMBOTTLES+" Bottle of Beer on the wall.") 
        WRITES (8," ")
        WRITES (8,ANUMBOTTLES+" Bottle of Beer on the wall,")
        WRITES (8,ANUMBOTTLES+" Bottle of Beer,")
        WRITES (8,"   Take one down, pass it around,")
        WRITES (8," ")
        WRITES (8," ")
        WRITES (8, "Hey the Beer's gone, I am out of here...")
        SLEEP 2
        CLOSE 8
        STOP
    .END
    

    dBase III

    && BEER.PRG  - 99 Bottles of Beer  - Brian Hobbs  Jan 1996
    && (BHOBBS@cayman.vf.mmc.com)
    SET TALK OFF
    I=99
    DO WHILE I>=1
       b = STR(i,2)
       ? b +" Bottle"
       IF i > 1
          ?? "s"
       ENDIF
       ?? " of beer on the wall "+b+" bottle"
       IF i> 1 
         ?? "s"
         ENDIF
       ?? " of beer"
       ? "   Take one down and pass it around"
       i=i-1
       b = STR(i,2)
       if i = 0
         b = "No more"
         ENDIF
       ? b + " Bottle"
       IF I > 1 .OR. I=0
          ?? "s"
       ENDIF
       ?? " of beer on the wall"
       ?
    ENDDO
       ? "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"
    SET TALK ON
    

    Gofer

    Gofer is a variation of Haskell. More Information
    -- 99 bottles of beer (gofer version)
    -- Written by Bow-Yaw Wang (bywang@saul.cis.upenn.edu)
    
    radix 0 _ = []
    radix x n = (x `mod` n):(radix (x/n) n)
    
    itoa x = map (\x -> chr(x + ord('0'))) (reverse (radix x 10))
    
    bottles :: Int -> Dialogue
    
    bottles 1 resps = [AppendChan stdout "1 bottle of beer on the wall, ",
                       AppendChan stdout "1 bottle of beer.\n",
                       AppendChan stdout "Take one down, pass it around, ",
                       AppendChan stdout "no more bottles of beer on the wall.\n"]
    bottles n resps = [AppendChan stdout (itoa n),
                       AppendChan stdout " bottles of beer on the wall, ",
                       AppendChan stdout (itoa n),
                       AppendChan stdout " bottles of beer.\n",
                       AppendChan stdout "Take one down, pass it around, ",
                       AppendChan stdout (itoa (n-1)),
                       AppendChan stdout " bottles of beer on the wall.\n"] ++
                       bottles (n-1) resps
    

    Dialog System

    'Dialog System', a system for developing graphical applications.
    # Programmer: Mark Gray - mvg@mfltd.co.uk
    # http://www.mfltd.co.uk/
    #
    # Note: requires version 2.5 of Dialog System.
    
    Form BEER
       Screenset Details
           First-Window WIN1
       End Details
    
       Form Data
           Group BOTTLE-TEXT-GROUP-1 Vertical Occurs 1
               NUMBER-OF-BOTTLES-1 Integer(2)
               BOTTLE-TEXT-1 Character(28)
               BOTTLE-PUNCTUATION-1 Character(1)
           End Group # BOTTLE-TEXT-GROUP-1
    
           Group BOTTLE-TEXT-GROUP-2 Vertical Occurs 1
               NUMBER-OF-BOTTLES-2 Integer(2)
               BOTTLE-TEXT-2 Character(17)
           End Group # BOTTLE-TEXT-GROUP-2
    
               BOTTLE-TEXT-1A Character(31)
               BOTTLE-TEXT-2A Character(19)
               BOTTLE-TEXT-3 Character(30)
               BOTTLE-TEXT-4 Character(34)
       End Data
    
       Object WIN1
           Type DIALOG-BOX
           Parent DESKTOP
           Start (492,720)
           Size  (1208,1150)
           Display "99 Bottles of Beer"
           Style MODELESS TITLEBAR SYSTEM-MENU
       End Object  #WIN1
    
       Object BEER-LIST
           Type LIST-BOX
           Parent WIN1
           Start (64,100)
           Size  (1088,800)
           Style DISABLE-HORIZONTAL
       End Object  #BEER-LIST
    
       Object PB1
           Type PUSH-BUTTON
           Parent WIN1
           Start (416,1040)
           Size  (372,96)
           Display "Close"
       End Object  #PB1
    
       Global Dialog CASE(OFF)
           Event ESC
               SET-EXIT-FLAG ;
               TERMINATE ;
           End Event # ESC
           Event CLOSED-WINDOW
               SET-EXIT-FLAG ;
               TERMINATE ;
           End Event # CLOSED-WINDOW
           Event BUTTON-SELECTED
               SET-EXIT-FLAG ;
               TERMINATE ;
           End Event # BUTTON-SELECTED
           Event SCREENSET-INITIALIZED
               MOVE " bottles of beer on the wall" BOTTLE-TEXT-1(1) ;
               MOVE " bottles of beer," BOTTLE-TEXT-2(1) ;
               MOVE "Take one down, pass it around," BOTTLE-TEXT-3 ;
               MOVE "Go to the store and buy some more," BOTTLE-TEXT-4 ;
               MOVE 99 NUMBER-OF-BOTTLES-1(1) ;
               BRANCH-TO-PROCEDURE COUNT-BOTTLES ;
           End Event # SCREENSET-INITIALIZED
           Procedure COUNT-BOTTLES
               MOVE NUMBER-OF-BOTTLES-1(1) NUMBER-OF-BOTTLES-2(1) ;
               MOVE "," BOTTLE-PUNCTUATION-1(1) ;
               MOVE BOTTLE-TEXT-GROUP-1 BOTTLE-TEXT-1A ;
               MOVE BOTTLE-TEXT-GROUP-2 BOTTLE-TEXT-2A ;
               INSERT-LIST-ITEM BEER-LIST BOTTLE-TEXT-1A 0 ;
               INSERT-LIST-ITEM BEER-LIST BOTTLE-TEXT-2A 0 ;
               MOVE "." BOTTLE-PUNCTUATION-1(1) ;
               IF= NUMBER-OF-BOTTLES-1(1) 0 END-BOTTLES ;
               INSERT-LIST-ITEM BEER-LIST BOTTLE-TEXT-3 0 ;
               DECREMENT NUMBER-OF-BOTTLES-1(1) ;
               MOVE BOTTLE-TEXT-GROUP-1 BOTTLE-TEXT-1A ;
               INSERT-LIST-ITEM BEER-LIST BOTTLE-TEXT-1A 0 ;
               BRANCH-TO-PROCEDURE COUNT-BOTTLES ;
           End Procedure # COUNT-BOTTLES
           Procedure END-BOTTLES
               MOVE 99 NUMBER-OF-BOTTLES-1(1) ;
               MOVE BOTTLE-TEXT-GROUP-1 BOTTLE-TEXT-1A ;
               INSERT-LIST-ITEM BEER-LIST BOTTLE-TEXT-4 0 ;
               INSERT-LIST-ITEM BEER-LIST BOTTLE-TEXT-1A 0 ;
           End Procedure # END-BOTTLES
       End Dialog
    End Form
    

    HyperTalk

    The scripting language for Apple's HyperCard.
    --
    -- a version of the "99 bottles of beer" song in HyperTalk
    -- by eric carlson: eric@bungdabba.com
    --
    on BeerSong99
      BottlesOfBeer 99
    end BeerSong99
    
    
    --
    -- do something with a lyric from the beer song.  this handler adds 
    it to
    --  a field on the current card
    on OutputBeerLyric beerString
      if ( beerString is "<reset>" ) then
        put empty into cd fld "beer song"
      else
        put beerString & return after cd fld "beer song"
      end if
    end OutputBeerLyric
    
    
    --
    -- sing the beer song with the specified number of bottles
    on BottlesOfBeer bottleCount
      put bottleCount into initialCount
      OutputBeerLyric "<reset>"
      
      repeat until ( bottleCount < 1 )
        set cursor to busy     -- let 'em know this might take a while
        put BottleString(bottleCount) into currentString
        OutputBeerLyric currentString && "of beer on the wall,"
        OutputBeerLyric currentString && "of beer."
        OutputBeerLyric "Take one down, and pass it around,"
        
        subtract one from bottleCount
        OutputBeerLyric BottleString(bottleCount) && "of beer on the 
    wall." & return
      end repeat
      
      OutputBeerLyric "Go to the store and buy some more..."
      OutputBeerLyric initialCount & " bottles of beer on the wall."
    end BottlesOfBeer
    
    
    --
    -- return the bottle string appropriate for the current count
    function BottleString bottleCount
      if ( bottleCount is 1 ) then
        return "1 bottle"
      else if ( bottleCount is 0 ) then
        return "no more bottles"
      else
        return bottleCount && "bottles"
      end if
    end BottleString
    

    Foxpro/Xbase

    The scripting language controlling the Foxpro database.
    ** Randy Jean
    FOR x = 100 TO 1 STEP -1
    	?x,"Bottle(s) of beer on the wall,",x,"bottle(s) of beer"
    	?"         Take one down and pass it around,"
    	?x-1,"bottle(s) of beer on the wall"
    ENDFOR
    

    Froth

    \ 99 bottles of beer in Froth, by Leo Wong, a teetotaler   6FEB96  +
    \ Pass it around.
    
    : LYRICS   [CHAR] ! PARSE  TUCK  HERE CHAR+  SWAP CHARS MOVE   DUP C,  CHARS ALLOT ;
    : VOCALIZE  ( a)  COUNT TYPE ;
    : SING   CREATE LYRICS  DOES> VOCALIZE ;
    
    SING NO_MORE No more !
    SING BOTTLE bottle! 
    SING BOTTLES bottles! 
    SING OF_BEER  of beer!  
    SING ON_THE_WALL  on the wall!
    SING TAKE Take !
    SING IT it! 
    SING ONE one!
    SING DOWN_AND_PASS_IT_AROUND  down and pass it around!
    SING GO_TO_THE_STORE_&_BUY_SOME_MORE Go to the store and buy some more! 
    SING COMMA ,!
    SING PERIOD .!
    
    : ?: CREATE  ( n)  ,   ' ,  ' ,
       DOES>  ( n)  TUCK @ <>  1-  CELLS -  @ EXECUTE ;
    
    : NONE  ( n)  DROP NO_MORE ;
    : SOME  ( n)  . ;
    
    0 ?: HOW_MANY  NONE  SOME 
    
    1 ?: BOTTLE(S)  BOTTLE  BOTTLES
    
    1 ?: IT|ONE  IT  ONE
    
    : COMMERCIAL  ( 0 - 99)  GO_TO_THE_STORE_&_BUY_SOME_MORE  99 + ;  
    : SHAREWARE  ( n - n-1)  DUP  TAKE IT|ONE DOWN_AND_PASS_IT_AROUND  1- 
    ;
    
    0 ?: main(){0?99:--}  COMMERCIAL  SHAREWARE
    
    : BURP  ( n - n n)  DUP ;
    : HOW_MANY_BOTTLES_OF_BEER  ( n n n)  HOW_MANY BOTTLE(S) OF_BEER ;
    
    : Froth  ( n - n')
       CR  BURP BURP BURP  HOW_MANY_BOTTLES_OF_BEER ON_THE_WALL  COMMA
       CR  BURP BURP BURP  HOW_MANY_BOTTLES_OF_BEER              COMMA 
       CR  BURP            main(){0?99:--}                       COMMA
       CR  BURP BURP BURP  HOW_MANY_BOTTLES_OF_BEER ON_THE_WALL  PERIOD 
    CR ;
    
    : LeoWong  ( n)  DROP ;
    
    : SONG   99
    

    Draco

    An Amiga language combining features of C and Pascal
    /* 99 Bottles of Beer */
    /* James Hicks (hicksjl@cs.rose-hulman.edu) */
    /* 5 August 1996 */
    
    int BEERS = 99;
    
    proc main()void:
    
      uint i;
    
      for i from BEERS downto 1 do
        if i > 1 then
          writeln(i, " bottles of beer on the wall, ", i, " bottles of beer.");
        else
          writeln(i, " bottle of beer on the wall, ", i, " bottle of beer.");
        fi;
        writeln("Take one down, pass it around,");
        if i > 2 then
          writeln(i - 1, " bottles of beer on the wall.");
        elsif i > 1 then
          writeln(i - 1, " bottle of beer on the wall.");
        else
          writeln("No bottles of beer on the wall.");
        fi;
      od;
    
    corp;
    

    Expect

    Update: Through some kind comments from others, I can now say something about this language. It is designed to talk to other interactive programs apparently for testing purposes. I am told the contributor was the author of the language but apparently was being humble.
    #!/usr/local/bin/expect
    
    # 99 bottles of beer on the wall, Expect-style
    # Author: Don Libes 
    
    # Unlike programs (http://www.ionet.net/~timtroyr/funhouse/beer.html)
    # which merely print out the 99 verses, this one SIMULATES a human
    # typing the beer song.  Like a real human, typing mistakes and timing
    # becomes more erratic with each beer - the final verse is barely
    # recognizable and it is really like watching a typist hunt and peck
    # while drunk.
    
    # Finally, no humans actually sing all 99 verses - particularly when
    # drunk.  In reality, they occasionally lose their place (or just get
    # bored) and skip verses, so this program does likewise.
    
    # Because the output is timed, just looking at the output isn't enough
    # - you really have to see the program running to appreciate it.
    # Nonetheless, for convenience, output from one run (it's different
    # every time of course) can be found in the file beer.exp.out
    # But it won't show the erratic timing;  you have to run it for that.
    
    proc bottles {i} {
    	return "$i bottle[expr $i!=1?"s":""] of beer"
    }
    
    proc line123 {i} {
    	out $i "[bottles $i] on the wall,\n"
    	out $i "[bottles $i],\n"
    	out $i "take one down, pass it around,\n"
    }
    
    proc line4 {i} {
    	out $i "[bottles $i] on the wall.\n\n"
    }
    
    proc out {i s} {
    	foreach c [split $s ""] {
    		# don't touch punctuation; just looks too strange if you do
    		if [regexp "\[,. \n\]" $c] {
    			append d $c
    			continue
    		}
    
    		# keep first couple of verses straight
    		if {$i > 97} {append d $c; continue}
    
    		# +3 prevents it from degenerating too far
    		# /2 makes it degenerate faster though
    
    		set r [rand [expr $i/2+3]]
    		if {$r} {append d $c; continue}
    
    		# do something strange
    		switch [rand 3] {
    		    0 {
    			# substitute another letter
    
    			if [regexp \[aeiou\] $c] {
    				# if vowel, substitute another
    				append d [string index aeiou [rand 5]]
    			} elseif [regexp \[0-9\] $c] {
    				# if number, substitute another
    				append d [string index 123456789 [rand 9]]
    			} else {
    				# if consonant, substitute another
    				append d [string index bcdfghjklmnpqrstvwxyz [rand 21]]
    			}
    		    } 1 {
    			# duplicate a letter
    			append d $c$c
    		    } 2 {
    			# drop a letter
    		    }
    		}
    	}
    
    	set arr1 [expr .4 - ($i/333.)]
    	set arr2 [expr .6 - ($i/333.)]
    	set shape [expr log(($i+2)/2.)+.1]
    	set min 0
    	set max [expr 6-$i/20.]
    
    	set send_human "$arr1 $arr2 $shape $min $max"
    
    	send -h $d
    }
    
    set _ran [pid]
    
    proc rand {m} {
    	global _ran
    
    	set period 259200
    	set _ran [expr ($_ran*7141 + 54773) % $period]
    	expr int($m*($_ran/double($period)))
    }
    
    for {set i 99} {$i>0} {} {
    	line123 $i
    	incr i -1
    	line4 $i
    
    	# get bored and skip ahead
    	if {$i == 92} {
    		set i [expr 52+[rand 5]]
    	}
    	if {$i == 51} {
    		set i [expr 12+[rand 5]]
    	}
    	if {$i == 10} {
    		set i [expr 6+[rand 3]]
    	}
    }
    
    Sample output:
    99 bottles of beer on the wall,
    99 bottles of beer,
    take one down, pass it around,
    98 bottles of beer on the wall.
    
    11 botqle off baer oc tbe wakl,
    1 botplo of beer,
    take onne da, pass itt arounm,
    0 yotglees oof beeeer on tte walll.
    

    FileMaker Pro 3.0

    This program will allegedly sing to you. Program courtesy Jon Rosen (techwiz@netaxis.com).
    Enter Browse Mode
    Set Field No. Bottles/Calculation (99)
    Set Field Bottle Text/Calculation (³²)
    Loop
      Set Field Bottle Text/Calculation
        If(No. Bottles ‚ 1,
          No. Bottles & ³bottles of beer on the wall. ³ & No. Bottles & ³bottles of beer.² & Paragraph & ³Take one down and pass it around and ³,
          No. Bottles & ³bottle of beer on the wall. ³ & No. Bottles & ³bottle of beer.² & Paragraph & ³Take one down and pass it around and ³) & Paragraph &
        If(No. Bottles - 1 ‚ 1,
          (No. Bottles - 1) & ³ bottles of beer on the wall²,
          (No. Bottles - 1) & ³ bottle of beer on the wall²)
    Refresh Window
    Comment (Viewing text is optional)
    Speak (Speech Data: Field: Bottle Text/Wait for completion)
    Comment  (Speech is optional)
    Set Field No. Bottles/Calculation (No. Bottles - 1)
    Exit Loop If (Calculation (No. Bottles = 0))
    End Loop
    Set Field Bottle Text/Calculation (³0 bottles of beer on the wall. 0 bottles of beer. Go to the store and buy some more.² & Paragraph & ³99 bottles of beer on the wall.²
    Refresh Window
    Speak (Speech Data: Field: Bottle Text/Wait for completion)
    

    GrASP

    GrASP is used for controlling the GrASP animation program.
    video 1
    local var1 99
    local var2 24
    mark 98
    text 1 @var2 @var1
    text " bottle(s) of beer on the wall,"
    text 1 @var2-1 @var1
    text " bottle(s) of beer!"
    text 1 @var2-2 "Take one down, pass it around,"
    text 1 @var2-3 @var1-1
    text " bottle(s) of beer on the wall!"
    waitkey 500
    set var1 @var1-1
    loop
    

    GNU-cpp

    /************************************************************************/
    /*	bottle.cpp							*/
    /*	1996 Walter Zimmer (walter.zimmer@rz.uni-ulm.de)		*/
    /*									*/
    /*	Save as "bottle.cpp" or change all the #includes !		*/
    /*	#include is necessary since cpp expands each line into		*/
    /*	no more than one new line					*/
    /*									*/
    /*	Invocation: cpp -P bottle.cpp					*/
    /*									*/
    /*	Remove comments to have less empty lines in the output		*/
    /*	but we still have to many...					*/
    /************************************************************************/
    
    #if defined TEXT
    /* This is the part which outputs one verse. 'Passed' parameters are */
    	/* ONES:	inner digit */
    	/* TENS:	outer digit */
    	/* SECONDTEN:	outer digit decremented by one */
    
    	/* if ONES == 0 then we have to use the decremented outer digit */
    	#if ONES == 0
    		/* omit output of 00 verse */
    		#if SECONDTEN < 10
    		/* Use SECONDTEN */
    			print(TENS,ONES)
    			print(TENS,ONES)
    			  Take one down, pass it around
    			print(SECONDTEN,SECONDONE)
    		#endif /* SECONDTEN */
    	#else /* ONES */
    		/* Here everthing is normal, we use the normal TENS */
    			print(TENS,ONES)
    			print(TENS,ONES)
    			  Take one down, pass it around
    			print(TENS,SECONDONE)
    	#endif /* ONES */
    #elif defined LOOP
    /*	This is the inner loop which iterates about the last digit */
    	/* #undef LOOP, #define TEXT so we output text in the next #include */
    	#undef LOOP
    	#define TEXT
    
    	/* #undef and #define the inner digits, invoke text output */
    	#undef ONES
    	#undef SECONDONE
    	#define ONES 9
    	#define SECONDONE 8
    	#include "bottle.cpp"
    
    	/* ...and so on for digits 8-0 */
    	#undef ONES
    	#undef SECONDONE
    	#define ONES 8
    	#define SECONDONE 7
    	#include "bottle.cpp"
    	#undef ONES
    	#undef SECONDONE
    	#define ONES 7
    	#define SECONDONE 6
    	#include "bottle.cpp"
    	#undef ONES
    	#undef SECONDONE
    	#define ONES 6
    	#define SECONDONE 5
    	#include "bottle.cpp"
    	#undef ONES
    	#undef SECONDONE
    	#define ONES 5
    	#define SECONDONE 4
    	#include "bottle.cpp"
    	#undef ONES
    	#undef SECONDONE
    	#define ONES 4
    	#define SECONDONE 3
    	#include "bottle.cpp"
    	#undef ONES
    	#undef SECONDONE
    	#define ONES 3
    	#define SECONDONE 2
    	#include "bottle.cpp"
    	#undef ONES
    	#undef SECONDONE
    	#define ONES 2
    	#define SECONDONE 1
    	#include "bottle.cpp"
    	#undef ONES
    	#undef SECONDONE
    	#define ONES 1
    	#define SECONDONE 0
    	#include "bottle.cpp"
    	#undef ONES
    	#undef SECONDONE
    	#define ONES 0
    	#define SECONDONE 9
    	#include "bottle.cpp"
    
    	/* Clean up */
    	#undef TEXT
    
    #else /* TEXT, LOOP */
    /*	Here is the basic 'loop' which iterates about the outer digit */
    
    	/* First define the print macro which outputs one line of xx beer */
    	/* We have to define it over the second define 'raw' to combine */
    	/* prescan with concatenation */
    	#define raw(TENS,ONES) TENS ## ONES
    	#define print(TENS,ONES) raw(TENS,ONES) bottles of beer on the wall
    
    	/* Tell bottle.cpp to invoke the inner loop when #included */
    	#define LOOP
    
    	/* #define outer digit and process inner loop */
    	#define TENS 9
    	#define SECONDTEN 8
    	#include "bottle.cpp"
    
    	/* Do this for the other digits 8 to 0, now with #undef */
    	/* Since LOOP gets #undef'd, we have to define it again */
    	#define LOOP
    	#undef TENS
    	#define TENS 8
    	#undef SECONDTEN
    	#define SECONDTEN 7
    	#include "bottle.cpp"
    	#define LOOP
    	#undef TENS
    	#define TENS 7
    	#undef SECONDTEN
    	#define SECONDTEN 6
    	#include "bottle.cpp"
    	#define LOOP
    	#undef TENS
    	#define TENS 6
    	#undef SECONDTEN
    	#define SECONDTEN 5
    	#include "bottle.cpp"
    	#define LOOP
    	#undef TENS
    	#define TENS 5
    	#undef SECONDTEN
    	#define SECONDTEN 4
    	#include "bottle.cpp"
    	#define LOOP
    	#undef TENS
    	#define TENS 4
    	#undef SECONDTEN
    	#define SECONDTEN 3
    	#include "bottle.cpp"
    	#define LOOP
    	#undef TENS
    	#define TENS 3
    	#undef SECONDTEN
    	#define SECONDTEN 2
    	#include "bottle.cpp"
    	#define LOOP
    	#undef TENS
    	#define TENS 2
    	#undef SECONDTEN
    	#define SECONDTEN 1
    	#include "bottle.cpp"
    	#define LOOP
    	#undef TENS
    	#define TENS 1
    	#undef SECONDTEN
    	#define SECONDTEN 0
    	#include "bottle.cpp"
    	#define LOOP
    	#undef TENS
    	#define TENS 0
    	#undef SECONDTEN
    
    	/* We @define SECONDTEN as 10 to indicate that we are outputting */
    	/* the last block and therefore need only 9 verses */
    	#define SECONDTEN 10
    	#include "bottle.cpp"
    #endif
    

    EXEC

    * EXEC version of 99 Bottles of beer program
    * By Torbjørn Vaaje (etotv@eto.ericsson.se)
    *
    &BEERS = 99
    &S = ES
    &LOOP 5 99
    &TYPE &BEERS BOTTL&S OF BEER ON THE WALL, &BEERS BOTTL&S OF BEER.
    &BEERS = &BEERS - 1
    &IF &BEERS = 1 &S = E
    &IF &BEERS = 0 &BEERS = NO_MORE
    &TYPE TAKE ONE DOWN AND PASS IT AROUND, &BEERS BOTTL&S OF BEER ON THE WALL
    

    Focus

    Focus is a fourth generation data reporting/management language/toolset. It runs on a numerous platforms, from Windows up to MVS. http://www.ibi.com/
    -* Randy Gleason
    -* 99 beer challenge
    
     -REPEAT ENDBEER FOR &COUNTER FROM 99 TO 1 STEP -1
     -SET &PL = IF &COUNTER EQ 1 THEN '' ELSE 's' ;
     -TYPE &COUNTER bottle&PL of beer on the wall, &COUNTER bottle&PL of beer
     -TYPE Take one down, pass it around
     -TYPE
     -ENDBEER
     -TYPE No more bottles of beer on the wall, No more bottles of beer
     -TYPE And we all shout out..WHO'S BUYING THE NEXT ROUND!
    

    Express

    Custom language used by IRI Software
    "  Language:  Express
    "  Written by Lori Smallwood, IRI Software
    "  April 12, 1997
    
    vrb _beer  int
    _beer = 99
    
    while _beer gt 0
      do
        shw joinchars(_beer ' bottles of beer on the wall,')
        shw joinchars(_beer ' bottles of beer... ')
        shw 'Take one down, pass it around,'
        _beer = _beer - 1
        shw joinchars(_beer ' bottles of beer on the wall!')
      doend
    

    Excel

    Admittedly, yet another VB application.
    Sub Beers()
    ' 99 bottles of beer on the wall
    ' Visual Basic for Excel version
    ' by Alejandro Julien (ajulien@tonatiuh.sis.uia.mx)
    ' Done with Excel 7 (Windows '95)
    '
    ' It will start from the first cell of the first worksheet
    ' and move on downwards.
        Dim Cervezas As Integer 'Cervezas = beer in spanish
        Dim miCelda As Integer  'miCelda = myCell in spanish
        Worksheets(1).Activate
        ' Colors
        Range("A1:AA1").Interior.Color = RGB(0, 0, 128)
        ActiveCell.Offset(1, 0).Value = "by Alejandro Julien"
        Range("A1:A204").Font.Color = RGB(0, 0, 128)
        ' Title
        Range("A1").Select
        With ActiveCell
            .Value = "The 99 bottles of beer on the wall song"
            .Font.Size = 18
            .Font.Color = RGB(255, 255, 255)
        End With
        With ActiveCell.Offset(2, 0)
            .Value = "(ajulien@tonatiuh.sis.uia.mx)"
            With .Font
                .Italic = True
                .Size = 8
            End With
        End With
        miCelda = 3
        ' GO!
        For Cervezas = 99 To 2 Step -1
            ActiveCell.Offset(miCelda, 0).Value = Cervezas & " bottles of beer on the wall, " & Cervezas & " bottles of beer"
            miCelda = miCelda + 1
            ActiveCell.Offset(miCelda, 0).Value = "take one down and pass it around"
            miCelda = miCelda + 1
        Next
        ' ONE_BEER_EXCEPTION handling *whew!*
        ActiveCell.Offset(miCelda, 0).Value = "One bottle of beer on the wall, one bottle of beer"
        miCelda = miCelda + 1
        ActiveCell.Offset(miCelda, 0).Value = "take it down and pass it around"
        miCelda = miCelda + 1
        ' Beer's over
        ActiveCell.Offset(miCelda, 0).Value = "No more bottles of beer on the wall, no more bottles of beer"
        miCelda = miCelda + 1
        ActiveCell.Offset(miCelda, 0).Value = "Go to the store and buy some more"
        miCelda = miCelda + 1
        ' Sponsor's message
        With ActiveCell.Offset(miCelda, 0)
            .Value = "...but make sure it's mexican beer!"
            .Font.Italic = True
            .Font.Size = 8
        End With
        Application.Caption = "Cerveza mexicana siempre!"
        ' No kidding. If you have the chance, try a good mexican beer (:
        '-------
        ' This piece of code goes for the "99 bottles of beer" homepage,
        ' and may be used by whoever finds it useful to show Language,
        ' way of doing the chore, or proof that programmers seem to have
        ' no life (even though this is not a complete truth...)
        ' <#include "disclaim.h>
    End Sub
    

    dc

    dc is the Desk Calculator for *nix; It works on reverse polish notation, and a few other commands. The output of this routine is a little jagged, as dc has no commands to control screen formatting.
    Usage: dc 99bottles
    where this source file is saved as 99bottles NB: A blank line is required at the end of the file Without it, dc will not quit.
    [   bottles of beer on the wall
    ]sa
    [   bottles of beer
    ]sb
    [   take one down, pass it around
    ]sc
    [   
    ]sd
    99sn
    [lalnpsnPlblnp1-snPlcPlalnpsnPldPln0
    

    dc

    dc is the Desk Calculator for *nix; It works on reverse polish notation, and a few other commands. The output of this routine is a little jagged, as dc has no commands to control screen formatting.
    Usage: dc 99bottles
    where this source file is saved as 99bottles NB: A blank line is required at the end of the file Without it, dc will not quit.
    [   bottles of beer on the wall
    ]sa
    [   bottles of beer
    ]sb
    [   take one down, pass it around
    ]sc
    [   
    ]sd
    99sn
    [lalnpsnPlblnp1-snPlcPlalnpsnPldPln0
    

    E

    E is the macro language for IBM's EPM editor.
    ;  99 bottles of beer in E, the macro language for IBM's EPM editor.
    -- Todd Fox
    /* The most interesting thing about this language is that it has 3
     * different commenting styles and that the macros must be recompiled
     * directly into the editor to be used. */
    
    defproc make_bottle_text(num_bottles)
       if (num_bottles > 1) then
          bottle_text = num_bottles || ' bottles'
       elseif (num_bottles = 1) then
          bottle_text = num_bottles || ' bottle'
       else
          bottle_text = 'No bottles'
       endif
    
       return(bottle_text)
    
    defproc sing_beer_main_line(num_bottles, is_long)
       lyrics = make_bottle_text(num_bottles) || ' of beer'
    
       if (is_long) then
          lyrics = lyrics || ' on the wall'
       endif
    
       insertline lyrics
    
    defproc sing_beer_song()
       init_bottle_cnt = 99
       curr_bottle_cnt = init_bottle_cnt
    
       do while curr_bottle_cnt >= 1
          sing_beer_main_line(curr_bottle_cnt, 1)
          sing_beer_main_line(curr_bottle_cnt, 0)
          insertline 'Take one down and pass it around'
          curr_bottle_cnt = curr_bottle_cnt - 1
          sing_beer_main_line(curr_bottle_cnt, 1)
          insertline '' -- don't use "insert", existing text will get mixed 
    in
       enddo
    
       sing_beer_main_line(curr_bottle_cnt, 1)
       sing_beer_main_line(curr_bottle_cnt, 0)
       insertline 'Go to the store and buy some more'
       curr_bottle_cnt = init_bottle_cnt
       sing_beer_main_line(curr_bottle_cnt, 1)
    
    
    ; Define a command to execute it from the EPM command line.
    
    defc sing_beer_song
       call sing_beer_song()
    
    ; Execute with ctrl-X
    
    def c_X = 'sing_beer_song'
    
    ; done
    
    

    DSSP

    For Info see http://www.dssp.msk.ru
    [  99 bottles in DSSP
       Programmer: Laszlo Aszalos <aszalos@math.klte.hu>
    
       Run it with 99 BOTTLE
    ]
    
    B10
    : BOTTLE [N] LOT_OF ONE_LEFT ZERO [] ;
    : LOT_OF [N] CR C 1- DO ONE_BOTTLE D ;
    : ONE_BOTTLE [N]
         ON_THE_WALL .", " CR NUMBER_OFF BOTTLES ."," CR
         TAKE 1- [N-1] C 1 = IF0 MANY ;
    : MANY ON_THE_WALL ."." CR ;
    : TAKE ."take one down, pass it around," CR ;
    : ON_THE_WALL NUMBER_OFF BOTTLES ." on the wall" ;
    : BOTTLES ." bottles of beer" ;
    
    : ONE_LEFT ONE_ON_THE_WALL ."." CR ONE_ON_THE_WALL ."," CR BOTTLE1 
    ."," CR ; 
    : ONE_ON_THE_WALL BOTTLE1 ." on the wall" ;
    : BOTTLE1 ." 1 bottle of beer" ;
    
    : ZERO TAKE ZERO_ON ."." CR ZERO_ON ."," CR  NO_MORE ."," CR
           ."go to the store, and buy some more!" CR ;
    : ZERO_ON  NO_MORE ." on the wall" ;
    : NO_MORE ."no more bottles of beer" ;
    : NUMBER_OFF C 2 TON ;
    : NUMBER_OFF C 2 TON ;
    

    Compilation Copyright 1995, 1996, 1997 Tim Robinson. All Rights Reserved
    Permission to copy enthusiastically granted to instructors of computer science
    (who would like to demonstrate the styles of different programming languages
    to their students) provided that the names of the contributors are retained.

    More beer
    Back to the Funhouse