SNOBOL

    * 99 BOTTLES OF BEER IN SNOBOL (UNTESTED)
             BEER = 99
    MOREBEER OUTPUT = BEER ' BOTTLES OF BEER ON THE WALL'
             OUTPUT = BEER ' BOTTLES OF BEER'
             OUTPUT = 'TAKE ONE DOWN, PASS IT AROUND'
             BEER = BEER - 1
             OUTPUT = BEER ' BOTTLES OF BEER ON THE WALL'
             GT(BEER,0)   : S(MOREBEER)
             OUTPUT = 'NO MORE BOTTLES OF BEER ON THE WALL'
             OUTPUT = 'NO MORE BOTTLES OF BEER'
             OUTPUT = 'GO TO THE STORE AND BUY SOME MORE'
             OUTPUT = '99 BOTTLES OF BEER'
    END
    

    Smalltalk

    "Programmer: patrick m. ryan - pryan@access.digex.net
    "http://www.access.digex.net/~pryan
    
    99 to: 1 by: -1 do: [ :i |
    	i print. ' bottles of beer on the wall, ' print.
    	i print. ' bottles of beer. ' print.
    	'take one down, pass it around, ' print.
    	(i-1) print. ' bottles of beer on the wall, ' print.
    ]
    

    Vax DCL

    
    $ I=100
    $ FIRSTLOOP:
    $ IF (I.EQ. 1) THEN GOTO LAST_BOTTLE
    $ WRITE SYS$OUTPUT I," BOTTLES OF BEER ON THE WALL"
    $ WRITE SYS$OUTPUT I," BOTTLES OF BEER"
    $ WRITE SYS$OUTPUT "IF ONE OF THEM SHOULD HAPPEN TO FALL"
    $ WRITE SYS$OUTPUT I-1," BOTTLE OF BEER ON THE WALL"
    $ WRITE SYS$OUTPUT "  "
    $ I=I-1
    $ GOTO FIRSTLOOP
    $ LAST_BOTTLE:
    $ WRITE SYS$OUTPUT "1 BOTTLE OF BEER ON THE WALL"
    $ WRITE SYS$OUTPUT "1 BOTTLE OF BEER"
    $ WRITE SYS$OUTPUT "IF IT SHOULD HAPPEN TO FALL"
    $ WRITE SYS$OUTPUT "NO MORE BOTTLES OF BEER ON THE WALL"
    
    

    --- A noteworthy alternative

    ; VMS DCL version of 99 Bottles of Beer
    $ I=100
    $ FIRSTLOOP:
    $ C=0
    $ L=1
    $ PAUSE:
    $ C=C+1
    $ IF (I.EQ. 1) THEN GOTO LAST_BOTTLE
    $ IF (C .EQ. 1500) THEN GOTO FIRSTCLEAN
    $ GOTO PAUSE
    $ FIRSTCLEAN:
    $ GOTO WIPESCN
    $ FIRSTLINE:
    $ WRITE SYS$OUTPUT I," bottles of beer on the wall,"
    $ C=0
    $ L=2
    $ FIRSTPAUSE:
    $ C=C+1
    $ IF (C .EQ. 2000) THEN GOTO SECONDCLEAN
    $ GOTO FIRSTPAUSE
    $ SECONDCLEAN:
    $ GOTO WIPESCN
    $ SECONDLINE:
    $ WRITE SYS$OUTPUT I," bottles of beer."
    $ C=0
    $ L=3
    $ SECONDPAUSE:
    $ C=C+1
    $ IF (C .EQ. 1500) THEN GOTO THIRDCLEAN
    $ GOTO SECONDPAUSE
    $ THIRDCLEAN:
    $ GOTO WIPESCN
    $ THIRDLINE:
    $ WRITE SYS$OUTPUT "If one of them should happen to fall...."
    $ C=0
    $ L=4
    $ THIRDPAUSE:
    $ C=C+1
    $ IF (C .EQ. 1500) THEN GOTO FOURTHCLEAN
    $ GOTO THIRDPAUSE
    $ FOURTHCLEAN:
    $ GOTO WIPESCN
    $ FOURTHLINE:
    $ WRITE SYS$OUTPUT I-1," bottles of beer on the wall."
    $ I=I-1
    $ GOTO FIRSTLOOP
    $ LAST_BOTTLE:
    $ C=0
    $ L=5
    $ FOURTHPAUSE:
    $ C=C+1
    $ IF (C .EQ. 1500) THEN GOTO FITHCLEAN
    $ GOTO FOURTHPAUSE
    $ FITHCLEAN:
    $ GOTO WIPESCN
    $ FITHLINE:
    $ WRITE SYS$OUTPUT "1 bottle of beer on the wall,"
    $ C=0
    $ L=6
    $ FITHPAUSE:
    $ C=C+1
    $ IF (C .EQ. 1200) THEN GOTO SIXTHCLEAN
    $ GOTO FITHPAUSE
    $ SIXTHCLEAN:
    $ GOTO WIPESCN
    $ SIXTHLINE:
    $ WRITE SYS$OUTPUT "1 bottle of beer..."
    $ C=0
    $ L=7
    $ SIXTHPAUSE:
    $ C=C+1
    $ IF (C .EQ. 2200) THEN GOTO SEVENTHCLEAN
    $ GOTO SIXTHPAUSE
    $ SEVENTHCLEAN:
    $ GOTO WIPESCN
    $ SEVENTHLINE:
    $ WRITE SYS$OUTPUT "If it should happen to fall...."
    $ C=0
    $ L=8
    $ LASTPAUSE:
    $ C=C+1
    $ IF (C .EQ. 2000) THEN GOTO LASTCLEAN
    $ GOTO LASTPAUSE
    $ LASTCLEAN:
    $ GOTO WIPESCN
    $ LASTLINE:
    $ WRITE SYS$OUTPUT "No more bottles of beer on the wall."
    $ GOTO QUIT
    $ WIPESCN:
    $ C=0
    $ WIPE:
    $ C=C+1
    $ WRITE SYS$OUTPUT " "
    $ IF (C .EQ. 25) THEN GOTO SONGLINE
    $ GOTO WIPE
    $ SONGLINE:
    $ IF (L .EQ. 1) THEN GOTO FIRSTLINE
    $ IF (L .EQ. 2) THEN GOTO SECONDLINE
    $ IF (L .EQ. 3) THEN GOTO THIRDLINE
    $ IF (L .EQ. 4) THEN GOTO FOURTHLINE
    $ IF (L .EQ. 5) THEN GOTO FITHLINE
    $ IF (L .EQ. 6) THEN GOTO SIXTHLINE
    $ IF (L .EQ. 7) THEN GOTO SEVENTHLINE
    $ IF (L .EQ. 8) THEN GOTO LASTLINE
    $ QUIT:
    

    SAS

    /* SAS version of 99 bottles of beer        */
    /* by Whitey (whitey@netcom.com) - 06/05/95 */
    
    data _null_;
       do i = 99 to 1 by -1;
          put i 'bottles of beer on the wall,' i 'bottles of beer,';
          put 'take one down, pass it around,';
          j = i - 1;
          if j = 0 then
             put 'no more ' @;
          else
             put j @;
          put 'bottles of beer on the wall.';
       end;
    run;
    

    TeX/LaTeX

    %% TeX/LaTeX version of 99 bottles of Beer
    %%
    %% Craig J Copi - copi@oddjob.uchicago.edu
    %%
    \parindent=0pt
    \newcount\beercurr
    \def\beer#1{\beercurr=#1\let\next=\removebeer\removebeer}
    \def\removebeer{
     \ifnum\beercurr>1 
       \the\beercurr\ bottles of beer on the wall,\par 
       \the\beercurr\ bottles of beer,\par 
       take one down, pass it around,\par 
       \advance\beercurr by -1 
       \the\beercurr\ bottle\ifnum1<\beercurr{s}\fi\ of beer on the wall.\par 
       \vskip 2ex\relax
     \else 
       1 bottle of beer on the wall,\par 1 bottle of beer,\par 
       take one down, pass it around,\par no bottles of beer on the wall.\par 
       \vskip .5ex
       Time to buy some more beer\ldots. \let\next=\relax
     \fi 
     \next}
    
    \beer{99}
    

    Tutor

    *--- Chris Lopez - lopez@huey.vp.uiuc.edu ---*
    *--- start of code ---*
    define
            maxbeer = 99
            origin:n1
            beer            $$ # of beers remaining
            atloc           $$ where to start writing this line
            nextlin(x) = (x <= (x+100) $mod$ 3200)
    *
    mode    rewrite
    calc    beer  <= maxbeer
            atloc <= 1
    loop
    .       at      nextlin(atloc)
    .       showt   beer,2
    .       * Warning: trailing space on following line
    .       write    bottles of beer on the wall,
    .       showt   beer,2
    .       write    bottles of beer.
    .       at      nextlin(atloc)
    .       write   Take one down, pass it around.
    outloop ((beer<=beer-1) < 2)
    .       showt   beer-1,2
    .       write    bottles of beer.
    endloop
    *
    write    1 bottle of beer.
    at      nextlin(atloc)
    write    1 Bottle of beer on the wall,  1 bottle of beer.
             Take it down, pass it around, no bottles of beer on the wall.
    *
    pause   keys=all
    jumpout q
    
    *--- end of code ---*
    

    TCL

    # Tcl version of 99 bottles of beer on the wall
    # Author: Don Libes (libes@nist.gov)
    #
    
    proc bottles {i} {
    	return "$i bottle[expr $i!=1?"s":""] of beer"
    }
    
    proc line123 {i} {
    	puts "[bottles $i] on the wall,"
    	puts "[bottles $i],"
    	puts "take one down, pass it around,"
    }
    
    proc line4 {i} {
    	puts "[bottles $i] on the wall.\n"
    }
    
    for {set i 99} {$i>0} {} {
    	line123 $i
    	incr i -1
    	line4 $i
    }
    
    

    SML

    See here for more info
    (* SML version of 99 bottles of beer *)
    (* written by Norvald - norvald@hsr.no *)
    let
        val itoa = Makestring.intToStr
        fun getabeer 0 = (print "Go to the store and buy some more,\n";
    		      print "99 bottles of beer on the wall.\n")
          | getabeer 1 = (print "1 bottle of beer on the wall,\n";
    		      print "1 bottle of beer,\n";
    		      print "Take one down, pass it around,\n";
    		      print "0 bottle of beer on the wall.\n\n";
    		      getabeer (0)) 
          | getabeer x = (print (itoa(x)^" bottles of beer on the wall,\n"); 
    		      print (itoa(x)^" bottles of beer,\n");
    		      print "Take one down, pass it around,\n";
    		      print (itoa(x-1)^" bottles of beer on the wall.\n\n");
    		      getabeer (x-1)) 
    in
        getabeer 99;
    end
    

    SQL

    remark	99 bottles of beer with Oracle SQL*Plus
    remark	R.vandePol@voeding.tno.nl	< Rob van de Pol>
    remark
    remark	assuming that YourTable contains at least 99 rows ;-)
    remark
    remark	RowNum is an Oracle psuedo column indicating the sequence the rows
    remark	were selected.
    
    SELECT 	TO_CHAR(100-rownum)||' bottles of beer on the wall, ' ||
    		TO_CHAR(100-rownum)||' bottles of beer,' ,
    	'take one down and pass it around, ' ,
    	DECODE ( TO_CHAR(99-rownum) , '0' , 'No more' , TO_CHAR(99-rownum) )||
    		' bottles of beer,'
    FROM 	YourTable
    WHERE 	rownum < 100
    

    Scheme

    ;;; Tim Goodwin (tim@pipex.net)
    
    (define bottles
      (lambda (n)
        (cond ((= n 0) (display "No more bottles"))
              ((= n 1) (display "One bottle"))
              (else (display n) (display " bottles")))
        (display " of beer")))
    
    (define beer
      (lambda (n)
        (if (> n 0)
            (begin
              (bottles n) (display " on the wall") (newline)
              (bottles n) (newline)
              (display "Take one down, pass it around") (newline)
              (bottles (- n 1)) (display " on the wall") (newline)
              (newline)
              (beer (- n 1))))))
    
    (beer 99)
    

    4DOS Batch

    @ECHO OFF
    
    :: BEER.BTM - 4DOS version 5.5 batch (btm) file
    :: by Rodney M. Savard <rodney.savard%phun@phunnet.org>
    
    SETLOCAL
    
    SET plural=`s`
    
    DO bottle = 99 TO 1 BY -1
       ECHOS %bottle% bottle%plural% of beer on the wall,
       ECHO  %bottle% bottle%plural% of beer.
    
       ECHOS Take one down, pass it around,
    
       IFF (%@EVAL[%bottle% - 1]) == (0) THEN
          ECHO  no more bottles of beer on the wall.
       ELSE
          IF (%@EVAL[%bottle% - 1]) == (1) UNSET plural
          ECHO  %@EVAL[%bottle% - 1] bottle%plural% of beer on the wall.
          ECHO.
       ENDIFF
    ENDDO
    
    ENDLOCAL
    

    Verilog

    Verilog is a hardware modelling language.
    /***********************************************************
    *    Module: 99 bottles of beer
    * By Danny Mulligan
    ***********************************************************/
    module beer;
        integer i;
        initial begin
            for (i=99; i>0; i=i-1)
            begin
                $display("%0d bottles of beer on the wall,", i);
                $display("%0d bottles of beer,", i);
                $display("Take one down and pass it around,");
                if (i==1)
                    $display("No more bottles of beer on the wall.\n");
                else
                    $display("%0d bottles of beer on the wall.\n", i-1);
            end
            $display("Go to the store and buy some more.");
        end
    end
    

    Simula

    BEGIN
      COMMENT
         Simula version of 99 beers
         Maciej Macowicz (mm@cpe.ipl.fr)
         Status: UNTESTED :)
      ;
      INTEGER bottles;
    
      FOR bottles:= 99 STEP -1 UNTIL 1 DO 
      BEGIN
        OutInt(bottles,1);
        OutText("bottle(s) of beer on the wall, ");
        OutInt(bottles,1);
        Outtext("bottle(s) of beer");
        OutImage;
        Outtext("Take one down, pass it around, ");
        OutInt(bottles,1);
        OutText("bottle(s) of beer on the wall, ");
      END;
      OutText("1 bottle of beer on the wall, one bottle of beer."); 
      Outimage;
      OutText("Take one down, pass it around, no more bottles of beer on the wall");
      OutImage
    END    
    

    Sather

    Click for information.
    -- Sather for 99 Bottles of Beer
    --
    -- David Stoutamire (davids@icsi.berkeley.edu)
    
    class MAIN is
       main is
          loop
             b::=99.downto!(1);
             #OUT + bob(b) + " on the wall, "
                  + bob(b) + ".\n"
                  + "Take one down, pass it around, "
                  + bob(b-1) + " on the wall.\n\n";
          end
       end;
    
       bob(i:INT):STR is
          case i
          when 0 then return "no more bottles of beer";
          when 1 then return "1 bottle of beer";
          else return i.str + " bottles of beer";
          end
       end
    end
    

    VHDL

    VHDL is VHSIC (Very High Speed Integrated Circuits) Hardware Description Language used for hardware design and testing.
    --  This is the VHDL (ANSI/IEEE Std 1076 - 1993)
    --  version of the beer song.
    --  F. J. Ludicky, Sundstrand Aerospace
    
    entity beer_song is
        port(bottles: out integer;
            words: out string(1 to 28);
            start_singing: in boolean);
    end beer_song;
    
    architecture silly of beer_song is
    begin
        lets_sing: process
        begin
            wait on start_singing until start singing;
            for index_bottles in 99 downto 1 loop
                    bottles <= index_bottles;
                    words <= "bottles of beer on the wall,";
                    wait for 5 sec;
                    bottles <= index_bottles;
                    words <= "bottles of beer,            ";
                    wait for 5 sec;
                    words <= "take one down,              ";
                    wait for 5 sec;
                    words <= "pass it around,             ";
                    wait for 5 sec;
                    bottles <= index_bottles - 1;
                    words <= "bottles of beer on the wall."
                    wait for 5 sec.
            end loop;
            assert false report "No more beer!" severity warning;
        end process lets_sing;
    end silly;
    

    Superbase

    SUB main()
     REM "99 bottles of beer", Superbase SBL version
     REM written by Mark Pilgrim, f8dy@netaxs.com
     REM [ If my boss is reading this, I'd just like to reassure
     REM   him that I wrote this on my own time. -MP ]
     DIM i%%,beer$,bottle$
     OPEN WINDOW "99 bottles of beer"
     bottle$ = " bottles "
     beer$ = "99"
     FOR i%% = 99 TO 1 STEP - 1
       ? beer$ + bottle$ + "of beer on the wall,"
       ? beer$ + bottle$ + "of beer,"
       ? "Take " + IF (i%% > 1,"one","it") + " down, pass it around,"
       IF i%% > 1 THEN 
         beer$ = LTRIM$ ( TRIM$ ( STR$ (i%% - 1)))
         IF i%% = 2 THEN bottle$ = " bottle "
         ? beer$ + bottle$ + "of beer on the wall."
         ? 
       ELSE 
         ? "No more bottles of beer on the wall."
       END IF 
     NEXT 
     END SUB 
    

    Unix DC

    DC is Unix's desk calculator
    [ Sing the classic '99 Bottles of Beer', using the Unix dc utility.  ]sd
    [                                                                    ]sd
    [ Run this one by typing 'dc < bottles.dc' at the Unix prompt, where ]sd
    [ bottles.dc is the file containing these lines.                     ]sd
    [ Author: Kevin Quick  kquick@iphase.com                             ]sd
    [                                                                    ]sd
    [ bottles of beer]sb[ on the wall]sw[,]sc
    [take one down, pass it around]st[.]sp[no more]sk
    [10 13lplwlbln1-10 13lclt10 13lclbln32lclwlbln]sl
    [lzxPPPPlzxPPPPPPPPlzxPPPPP]so[lkP]sx[dZselyxsd]su
    [d10le1-dse^ /d10/10*-48+P le0<y]sy[d0=xd0<u]sz
    [llxloxln1-dsn0<r]sr[Plf1-dsf0<g]sg
    99snlrx10P
    

    Trac

    #(#*( TRAC version of 99 bottles of beer.                            ))
    #(#*( written by Akira KIDA, SDI00379@niftyserve.or.jp               ))
    #(#*(                                                                ))
    #(#*( To run this, save the entire script as `beer.trac', and then   ))
    #(#*( type three lines in order.                                     ))
    #(#*(                                                                ))
    #(#*(    #(ld,beer.trac)                                             ))
    #(#*(    #(cl,beer,99)                                               ))
    #(#*(    '                                                           ))
    #(#*(                                                                ))
    #(ds,bottle,(#(gr,1,B,(No more bottles),(#(gr,2,B,(B bottle),(B bottles))))))
    #(ss,bottle,B)
    #(ds,beer,(#(gr,1,B,,
    (#(ps,#(cl,bottle,B) of beer on the wall(,) #(cl,bottle,B) of beer.(
    )Take one down(,) pass it around.(
    )#(cl,bottle,##(-,B,1)) of beer on the wall.(
    )(
    ))#(cl,beer,##(-,B,1))))))
    #(ss,beer,B)
    

    Sisal

    Click for more information.
    % ------------------------------------------------------------
    % The classic N bottles of beer problem.  The Sisal language
    % is implicitly parallel and functional.  It is not really desigined
    % for string processing (scientific numeric stuff is more like it!)
    % The following program will run in parallel on Crays, the
    % SGI Challenge, the Meiko, etc....  and run just swell on
    % your average ordinary PC too.  More information on the Sisal
    % language project can be found at
    % 
    % http://www.llnl.gov/sisal/SisalHomePage.html
    %
    % or contact sisal-info@sisal.llnl.gov
    %
    % Author: Pat Miller (patmiller@llnl.gov)
    % 
    % ------------------------------------------------------------
    
    define main
    
    type string = array[character];
    
    % ------------------------------------------------------------
    % OUCH -- have to really start from scratch
    % ------------------------------------------------------------
    function DigitToChar(d : integer returns character)
      character(integer('0')+d)
    end function
    
    % ------------------------------------------------------------
    % Sisal has no I/O runtime library for strings so we
    % can build up the ASCII representation a digit at a time
    % The sign handling is there for completeness and is not needed
    % to do the BEER problem
    % ------------------------------------------------------------
    function itoa(n : integer returns string)
      array_setl(
      let
        s := for initial
    	   x := abs(n);
    	   d := array[1: DigitToChar( mod(x,10) )];
             while x > 10 repeat
    	   x := old x / 10;
    	   d := array_addl(old d,DigitToChar(mod(x,10)));
    	 returns
    	   value of d
    	 end for
      in
        if n < 0 then array_addl(s,'-') else s end if
      end let
      ,1)
    end function
    
    % ------------------------------------------------------------
    % Produce one stanza of the 99 bottles of beer song.  Some care
    % is taken to keep it grammatical
    % ------------------------------------------------------------
    function BottlesOfBeer(i : integer returns array[string])
      let
        s,bottles,preface,n,nextbottles :=
          if i = 1 then
    	"1"," bottle","If that bottle","No more"," bottles"
          elseif i = 2 then
    	itoa(2)," bottles","If one of those bottles",itoa(1)," bottle"
          else
    	itoa(i)," bottles","If one of those bottles",itoa(i-1)," bottles"
          end if;
      in
        array[1:
          s || bottles || " of beer on the wall", 
          s || bottles || " of beer!",
          preface || " should happen to fall... ",
          n || nextbottles || " of beer on the wall!",
          ""
        ]
      end let
    end function
      
    
    % ------------------------------------------------------------
    % This main loop executes in parallel stuffing the 4 lines
    % of each stanza into an array holding the whole song
    % ------------------------------------------------------------
    function main(n : integer returns array[string])
      for i in 0,n-1
        howmany := n-i;
        stanza := BottlesOfBeer(howmany);
      returns value of catenate stanza
      end for ||
      array[1: "Time to buy more beer"]
    end function
    

    sed

    The UNIX stream editor. The creator of sed didn't think it's interesting to edit empty files, so this needs some kind of input, e.g.
    echo '' | sed -f 99.sed
    1{
            s/.*/99 bottles of beer on the wall/
            h
            : x
            p
            s/ on.*//
            p
            s/.*/take :&: down, pass it around/
            /one/{
                    s/:.*:/it/
                    p
                    g
                    s/on\(.*le\)/no mor\1s/
                    p
                    s/.*//
                    q
            }
            s/:.*:/one/
            p
            g
            y/1234567890/0123456789/
            /^.[0-8] /{
                    s/^.//
                    x
                    s/\(.\).*/\1/
                    G
                    s/\n//
            }
            s/^0//
            s/^1\( .*le\)s/one\1/
            h
            p
            s/.*//
            p
            g
            b x
    }
    

    Turing

    Turing is a commercially supported language used in 50% of Ontario schools.
    %  Ric Holt  holt@csri.toronto.edu
    %  Turing language version of 99 bottles of beer
    for decreasing i : 99 .. 1
        put i, " bottle(s) of beer on the wall, ", i, " bottle(s) of beer"
        put "Take one down, pass it around, ", i - 1,
            " bottle(s) of beer on the wall"
    end for
    

    Surf

    More information here.
    (begin 'SINGING
    
      (define HOW-MANY-BOTTLES
        (lambda (bottles where)
          (format stdout "%d bottle%d of beer%d\n"
    	      (list (if (> bottles 0) bottles "No more")
    		    (if (= bottles 1) "" "s")
    		    where))))
    
      (recurse DRINKING (bottles 99)
        (how-many-bottles bottles " on the wall,")
        (how-many-bottles bottles ",")
        (if (= bottles 0)
    	(display stdout "Go the the store, and buy some more!\n")
    	(begin (display stdout "You take one down, pass it around,\n")
    	       (how-many-bottles (- bottles 1) " on the wall.\n")
    	       (drinking (- bottles 1)))))
    
      'GO-TO-THE-STORE)
    

    Surf

    The person who sent this was Ed Gamble who promised more info on this language. If it's not on his web page, pester him.
    (begin 'SINGING
    
      (define HOW-MANY-BOTTLES
        (lambda (bottles where)
          (format stdout "%d bottle%d of beer%d\n"
    	      (list (if (> bottles 0) bottles "No more")
    		    (if (= bottles 1) "" "s")
    		    where))))
    
      (recurse DRINKING (bottles 99)
        (how-many-bottles bottles " on the wall,")
        (how-many-bottles bottles ",")
        (if (= bottles 0)
    	(display stdout "Go the the store, and buy some more!\n")
    	(begin (display stdout "You take one down, pass it around,\n")
    	       (how-many-bottles (- bottles 1) " on the wall.\n")
    	       (drinking (- bottles 1)))))
    
      'GO-TO-THE-STORE)
    

    SPITBOL

    * MaxSPITBOL version (SPITBOL implementation on
    * the Macintosh from Catspaw, Inc. (Salida, CO).
    * NOTE:  I have no connection w/them other than being
    * a long-time satisfied user of their product
    * D.H.  <hedges@pilot.njin.net>
    
         p0 = "NO MORE" ;  p1 = " BOTTLE" ; p2 = "S" ; p3 = " OF BEER"
         p4 = " ON THE WALL" ; p5 = "TAKE ONE DOWN, PASS IT AROUND"
    
         b = 99
         p6 = ((NE(b,0) b, p0) p1 (NE(b,1) p2,) p3)
    A1   OUTPUT = p6 p4 ; OUTPUT = p6 ; OUTPUT = p5
         b = b - 1
         p6 = ((NE(b,0) b, p0) p1 (NE(b,1) p2,) p3)
         OUTPUT = p6 p4 ; OUTPUT = ; NE(b,0)                   :S(A1)
    END
    

    zsh

    Yet another UNIX shell.
    #!/usr/local/bin/zsh
    alias dec_beer='let beer="\$beer - 1"'
    alias print_strophe='echo "$beer bottle$s of beer on the wall,"
    	echo "$beer bottle$s of beer,"
    	echo "take one down, pass it around,"
    	dec_beer
    	if [ "$beer" -eq "1" ]
    	then
    		unset s
    	fi
    	if [ "$beer" -eq "0" ]
    	then
    		beer="No"
    		s="s"
    	fi
    	echo "$beer bottle$s of beer on the wall."
    	echo'
    
    
    beer=99
    s="s"
    while [ "$beer" -ne "No" ]
    do
    	print_strophe
    done
    

    Sendmail

    Sendmail is used by mail systems for routing and controlling e-mail delivery. It was never really intended for general purpose programming, but here you go.
    # Save this to /tmp/foo.bar
    # echo '49 9 9' | /usr/lib/sendmail -bt -d21 -C/tmp/foo.bar
    # Sorry, Smail is too brain dead to run this.  Use sendmail instead.
    # Programmed by: Felix von Leitner 
    
    DH"take one down\, pass it around\,"
    DG"bottles of beer"
    DF"$G on the wall\."
    DE"$G on the wall\,"
    DN"No beer left\."
    
    S45
    R$- 2 $*	foo bar $1 1 $F
    R$- 3 $*	$1 2 $F
    R$- 4 $*	$1 3 $F
    R$- 5 $*	$1 4 $F
    R$- 6 $*	$1 5 $F
    R$- 7 $*	$1 6 $F
    R$- 8 $*	$1 7 $F
    R$- 9 $*	$1 8 $F
    R9 0 $*		8 9 $F
    R8 0 $*		7 9 $F
    R7 0 $*		6 9 $F
    R6 0 $*		5 9 $F
    R5 0 $*		4 9 $F
    R4 0 $*		3 9 $F
    R3 0 $*		2 9 $F
    R2 0 $*		1 9 $F
    R1 0 $*		0 9 $F
    R$- 1 $*	$1 0 $F
    Rfoo bar $- 1 $F	$1 1 $F
    R0 0 $*		$N
    
    S47
    R$- $- $E	$1 $2 $G,
    
    S48
    R$- $-		$>47 $1 $2 $E
    R$- $- $G,	$>45 $1 $2 $H
    R$- $- $F	$1 $2
    R$N		*burp*
    
    S49
    R$- $-					$>48 $1 $2
    

    SETL

    An online SETL server is available where you can run the program without the compiler.
    $ SETL version
    $ written by Arion Lei (philipl@cs.ust.hk)
    beer := {1,2..99};
    (until beer={})
      print(#beer, " bottles of beer on the wall,");
      print(#beer, " bottles of beer.  Take one down, pass it around,");
      $ take an arbitrary one down
      beer less := arb beer;
      if beer/={} then
        print(#beer, " bottles of beer on the wall.");
      end if beer/={};
    end until;
    print("No more bottles of beer on the wall, no more bottles of beer.");
    print("Go to the store and buy some more... 99 bottles of beer");
    

    Yorick

    Click here for further information.
    /*  The Bottles of Beer song (c) 1996 Eric Korpela
     *   Yorick version-- Modeled after the IDL version.
     * USAGE:  bottles or bottles, number
     */
    
    /* Set up our song structure............ */
    
    struct _song {
      int n0;
      string s1;
      int n1;
      string s2,s3;
      int n2;
      string s4;
    } 
    
    func bottles( number )
    {
    
      if (is_void(number)) { 
        number=99
        write,"BOTTLES: Defaulting to 99 bottles!"
      }
     
      song=array(_song(n0=0,s1=" bottles of beer on the wall.\n",n1=0,
                       s2=" bottles of beer.\n",
                       s3="You take one down and pass it around\n",
                       n2=0,
                       s4=" bottles of beer on the wall.\n"), number)
    
      /* put in the appropriate numbers */
    
      i=(number)-indgen(number)
      song(*).n0=i+1
      song(*).n1=i+1
      song(*).n2=i
     
      write,song.n0,song.s1,song.n1,song.s2,song.s3,song.n2,song.s4
     
    }
    

    VIM

    VIM is an editor language similar to vi The ^[ and ^X represent and Esc and Ctrl-X respecively
    :" This is a beer program for VIM.
    :" Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
    :" Run by :so! beer
    i102 bottles^[0v$"bd
    qzA of beer on the wall^Xq
    qa"bp@zA,
       ^["bpA of beer.
    ^[q
    qcATake one down, pass it around,
       ^["bp0^X03lv$"by@zA.
    
    ^[q
    qd@a@cq
    :0
    dG98@dA1 bottle^[0v$"bd@aA1 bottles^[0v$"bd@c@aAGo to the store and buy some more,
       100 bottles^[@zA...^[
    
    

    vi

    vi is the classic, pre-emacs text editor for U**x.
    I
    ! 99 bottles of beer lyrics generation using vi macros!
    ! 
    ! instructions:
    !  1. rename your .exrc (so you have no existing macros to conflict with mine)
    !  2. vi outfile < this_file >/dev/null 2>&1
    ! the output will be in outfile
    !
    ! Please note that this file is littered with control characters.
    !   All ^V, and ^] and ^M character sequences are control characters.
    !   The other occurrences of ^ are actually supposed to be there.
    !
    ! I also might be the first to point out that I took the liberty of
    ! using 'bc' to do my recalculations (sorry).
    !
    ! Scott Engberg
    ! 6/8/96
    ! Scott.Engberg@mfa.com
    !
    ^[Gd1G
    :set magic
    :map F A bottles of beer on the wall^V^M
    :map K A bottles of beer^V^M
    :map H Atake one down pass it around^V^M
    :map Q "aP
    :map O "ayy
    :map W A-1
    :map E !!bc^V^M
    :map S :s/^\([1-9]\)/\1/^V^M
    :map R OF^V^[QK^V^[H^V^[QW^V^[EST
    :map T R
    i99^[R^[
    G
    ?^0
    dG
    oNo more bottles of beer on the wall!^[
    :wq!
    

    Visual Basic

       'Jeff Shepherd 9/12/96 
       '99 Bottles of Beer for Visual Basic
       '(1) Start a new project, paste a single listbox on the form.
       '(2) Double-click on the form, paste the following code into
       'the Form_Load sub. (3) Hit F5 to run
    
       Dim n As Integer
       Dim s As String
    
       Width = 6000
       Height = Screen.Height * 2 / 3
       Top = (Screen.Height - Height) / 2
       Left = (Screen.Width - Width) / 2
       Caption = "99 Bottles of Beer"
       List1.Top = 0
       List1.Left = 0
       List1.Width = Form1.ScaleWidth
       List1.Height = Form1.ScaleHeight
    
       List1.AddItem s & "99 bottles of Beer on the wall,"
       List1.AddItem s & "99 bottles of Beeeer..."
       List1.AddItem "You take one down, pass it around..."
       For n = 98 To 1 Step -1
          s = IIf(n = 1, n & " final bottle", n & " bottles")
          List1.AddItem s & " of Beer on the wall."
          List1.AddItem ""
          List1.AddItem s & " of Beer on the wall,"
          List1.AddItem s & " of Beeeer..."
          List1.AddItem "You take one down, pass it around..."
       Next n
       List1.AddItem "No more bottles of Beer on the wall."
    

    Turing Machine

    In the dawn of the computing era, Alan Turing proposed a type of computer. This is an implementation of 99BoB for such a machine. Full details available at http://coli.uni-sb.de/~theiling/pub/Turing%20Machine/
    % `99 Bottles of Beer' on a Turing Machine
    
    % written 6/97 by Henrik Theiling 
    
    %% This defines \delta, the transition function.  There are four entries
    %% on each line:
    %%   CurrentCharacter OldState    NewCharacterOrAction NewState
    %%
    %% Thus each line defines:
    %%   \delta (CurrentCharacter,OldState) = (NewCharacterOrAction, NewState)
    %%
    
    % initialise tape with # cr "99" (#)
      #    0      ->    1
      #    1      cr    2
      cr   2      ->    3
      #    3      \9    3
      \9   3      ->    4
      #    4      \9    4
      \9   4      ->    10
      #    10     1000  10
      1000 10     <-    100
    
    % write `bottle' or `bottles':
    % check for `1'
      ?    100    ?    105
      \1   100    <-   102
      ?    102    ?    105
      cr   102    cr   120  % write `bottle', not `bottles'
    
    % write `bottles' (first shift back to the left):
      \0   105    ->   105
      \1   105    ->   105
      \2   105    ->   105
      \3   105    ->   105
      \4   105    ->   105
      \5   105    ->   105
      \6   105    ->   105
      \7   105    ->   105
      \8   105    ->   105
      \9   105    ->   105
      ?    105    ->   106
      #    106    b    106
      b    106    ->   107
      #    107    o    107
      o    107    ->   108
      #    108    t    108
      t    108    ->   109
      #    109    t    110
      t    110    ->   111
      #    111    l    111
      l    111    ->   112
      #    112    e    112
      e    112    ->   113
      #    113    s    200
    
    % write `bottle' (first shift back to the left):
      \1   120    ->   120
      cr   120    ->   120
      ?    120    ->   121
      #    121    b    121
      b    121    ->   122
      #    122    o    122
      o    122    ->   123
      #    123    t    123
      t    123    ->   124
      #    124    t    124
      t    124    ->   125
      #    125    l    125
      l    125    ->   126
      #    126    e    200
    
    % return subroutine 1:
      ?    200    <-   200
      1000 200    #    1000
      2000 200    _    2000
      3000 200    _    3000
      5000 200    #    5000
      6000 200    _    6000
      7000 200    cr   7000
      9100 200    #    9100
      9200 200    _    9200
      9300 200    _    9300
      #    200    #    stop
    
    % return subroutine 2:
      ?    210    ->   210
      4000 210    cr   4000
      8000 210    cr   8000
      9000 210    #    9000
      9400 210    cr   9400
    
    %
    % This is the main loop:
    %
    % 1000 is the return state for the first line after `bottle' or `bottles'
    % has been written.
      #    1000   ->   1001
      ?    1001   ->   1001
      #    1001   2000 1002
      2000 1002   ->   300   % write `of beer'
    
      ?    2000   ->   2000
      #    2000   3000 2000
      3000 2000   ->   400   % write `on the wall'
    
      ?    3000   ->   3000
      #    3000   4000 500   % copy number
    
      ?    4000   ->   4000
      #    4000   5000 4000
      5000 4000   <-   100   % write `bottle' or `bottles'
    
      #    5000   ->   5001
      ?    5001   ->   5001
      #    5001   6000 5002
      6000 5002   ->   300   % write `of beer'
    
      ?    6000   ->   6000
      #    6000   7000 6000
      7000 6000   ->   700   % write `Take one away and pass it around,'
    
      ?    7000   ->   7000
      #    7000   8000 500   % copy number
    
      ?    8000   ->   8000
      #    8000   _    8001
      _    8001   ->   8001
      #    8001   9000 8001
      9000 8001   <-   8002   % decrement number
      _    8002   <-   800
    
      cr   9000   ->   9004   % zero: all zeros have been eliminated...
      #    9000   <-   9000
      _    9000   #    9001
      #    9001   <-   9000
      ?    9000   ->   9002
      #    9002   9100 9002
      9100 9002   <-   100   % write `bottle' or `bottles'
    
      #    9004   \0   9004
      \0   9004   ->   9000
    
      #    9100   ->   9101
      ?    9101   ->   9101
      #    9101   9200 9101
      9200 9101   ->   300    % write `of beer'
    
      ?    9200   ->   9200
      #    9200   9300 9200
      9300 9200   ->   400   % write `on the wall'
    
      ?    9300   ->   9300
      #    9300   .    9300  % write a full-stop
      .    9300   ->   9301
      #    9301   cr   9301  % and an additional newline
      cr   9301   ->   9302
      #    9302   9400 500   % copy number
    
      cr   9400   ->   9400
      \0   9400   ->   9400
      ?    9400   ->   9401
      ?    9401   ->   9401
      #    9401   1000 9401
      1000 9401   <-   100  % start again
      #    9400   <-   9900 % write `Time to go to the store.' and stop
    
      \0   9900   T    9900
      T    9900   ->   9901
      #    9901   i    9901
      i    9901   ->   9902
      #    9902   m    9902
      m    9902   ->   9903
      #    9903   e    9903
      e    9903   ->   9904
      #    9904   _    9904
      _    9904   ->   9905
      #    9905   t    9905
      t    9905   ->   9906
      #    9906   o    9906
      o    9906   ->   9907
      #    9907   _    9907
      _    9907   ->   9908
      #    9908   g    9908
      g    9908   ->   9909
      #    9909   o    9909
      o    9909   ->   9910
      #    9910   _    9910
      _    9910   ->   9911
      #    9911   t    9911
      t    9911   ->   9912
      #    9912   o    9912
      o    9912   ->   9913
      #    9913   _    9913
      _    9913   ->   9914
      #    9914   t    9914
      t    9914   ->   9915
      #    9915   h    9915
      h    9915   ->   9916
      #    9916   e    9916
      e    9916   ->   9917
      #    9917   _    9917
      _    9917   ->   9918
      #    9918   s    9918
      s    9918   ->   9919
      #    9919   t    9919
      t    9919   ->   9920
      #    9920   o    9920
      o    9920   ->   9921
      #    9921   r    9921
      r    9921   ->   9922
      #    9922   e    9922
      e    9922   ->   9923
      #    9923   .    200   % go back to the beginning and halt
    
    % write `of beer':
      #    300    o    300
      o    300    ->   301
      #    301    f    301
      f    301    ->   302
      #    302    _    302
      _    302    ->   303
      #    303    b    303
      b    303    ->   304
      #    304    e    304
      e    304    ->   305
      #    305    e    305
      e    305    ->   306
      #    306    r    200 % return <-
    
    % write `on the wall':
      #    400    o    400
      o    400    ->   401
      #    401    n    401
      n    401    ->   402
      #    402    _    402
      _    402    ->   403
      #    403    t    403
      t    403    ->   404
      #    404    h    404
      h    404    ->   405
      #    405    e    405
      e    405    ->   406
      #    406    _    406
      _    406    ->   407
      #    407    w    407
      w    407    ->   408
      #    408    a    408
      a    408    ->   409
      #    409    l    409
      l    409    ->   410
      #    410    l    200 % return <-
    
    % write `Take one away and pass it around,':
      #    700    T    700
      T    700    ->   701
      #    701    a    701
      a    701    ->   702
      #    702    k    702
      k    702    ->   703
      #    703    e    703
      e    703    ->   704
      #    704    _    704
      _    704    ->   705
      #    705    o    705
      o    705    ->   706
      #    706    n    706
      n    706    ->   707
      #    707    e    707
      e    707    ->   708
      #    708    _    708
      _    708    ->   709
      #    709    a    709
      a    709    ->   710
      #    710    w    710
      w    710    ->   711
      #    711    a    711
      a    711    ->   712
      #    712    y    712
      y    712    ->   713
      #    713    _    713
      _    713    ->   714
      #    714    a    714
      a    714    ->   715
      #    715    n    715
      n    715    ->   716
      #    716    d    716
      d    716    ->   717
      #    717    _    717
      _    717    ->   718
      #    718    p    718
      p    718    ->   719
      #    719    a    719
      a    719    ->   720
      #    720    s    720
      s    720    ->   721
      #    721    s    721
      s    721    ->   722
      #    722    _    722
      _    722    ->   723
      #    723    i    723
      i    723    ->   724
      #    724    t    724
      t    724    ->   725
      #    725    _    725
      _    725    ->   726
      #    726    a    726
      a    726    ->   727
      #    727    r    727
      r    727    ->   728
      #    728    o    728
      o    728    ->   729
      #    729    u    729
      u    729    ->   730
      #    730    n    730
      n    730    ->   731
      #    731    d    731
      d    731    ->   732
      #    732    ,    200 % return <-
    
    % decrement decimal number in ASCII format (hangs on underflow):
      \2   800    \1   210
      \3   800    \2   210
      \4   800    \3   210
      \5   800    \4   210
      \6   800    \5   210
      \7   800    \6   210
      \8   800    \7   210
      \9   800    \8   210
      \1   800    \0   802
      \0   800    \9   801
      \9   801    <-   800
      \0   802    <-   802
      ?    802    ->   210
      cr   802    ->   803
      \0   803    \9   803
      \9   803    ->   803
      _    803    <-   804
      \9   804    _    210
    
    % copy number:
      ?    500    <-   500
      #    500    _    501
      ?    501    <-   501
      cr   501    ->   502
      \0   502    #    600
      \1   502    #    610
      \2   502    #    620
      \3   502    #    630
      \4   502    #    640
      \5   502    #    650
      \6   502    #    660
      \7   502    #    670
      \8   502    #    680
      \9   502    #    690
      _    502    ->   210 % return ->
    
    % Copying ciphers:
    
    % copy `0' to the right:
      #    600    ->   601
      ?    601    ->   601
      #    601    \0   602
      ?    602    <-   602
      #    602    \0   603
      \0   603    ->   502 % next cipher
    
    % copy `1' to the right:
      #    610    ->   611
      ?    611    ->   611
      #    611    \1   612
      ?    612    <-   612
      #    612    \1   613
      \1   613    ->   502 % next cipher
    
    % copy `2' to the right:
      #    620    ->   621
      ?    621    ->   621
      #    621    \2   622
      ?    622    <-   622
      #    622    \2   623
      \2   623    ->   502 % next cipher
    
    % copy `3' to the right:
      #    630    ->   631
      ?    631    ->   631
      #    631    \3   632
      ?    632    <-   632
      #    632    \3   633
      \3   633    ->   502 % next cipher
    
    % copy `4' to the right:
      #    640    ->   641
      ?    641    ->   641
      #    641    \4   642
      ?    642    <-   642
      #    642    \4   643
      \4   643    ->   502 % next cipher
    
    % copy `5' to the right:
      #    650    ->   651
      ?    651    ->   651
      #    651    \5   652
      ?    652    <-   652
      #    652    \5   653
      \5   653    ->   502 % next cipher
    
    % copy `6' to the right:
      #    660    ->   661
      ?    661    ->   661
      #    661    \6   662
      ?    662    <-   662
      #    662    \6   663
      \6   663    ->   502 % next cipher
    
    % copy `7' to the right:
      #    670    ->   671
      ?    671    ->   671
      #    671    \7   672
      ?    672    <-   672
      #    672    \7   673
      \7   673    ->   502 % next cipher
    
    % copy `8' to the right:
      #    680    ->   681
      ?    681    ->   681
      #    681    \8   682
      ?    682    <-   682
      #    682    \8   683
      \8   683    ->   502 % next cipher
    
    % copy `9' to the right:
      #    690    ->   691
      ?    691    ->   691
      #    691    \9   692
      ?    692    <-   692
      #    692    \9   693
      \9   693    ->   502 % next cipher
    

    Tiny Fugue

    Tiny Fugue is a mud client language
    ; 99 bottles of beer in TF macros.
    ; by Carey Evans.
    ;
    ; Type "/beer" to use after loading it.
    
    /def beerecho = /echo - %{*}
    /def beerbreath = /echo
    
    ; Uncomment the following lines instead to send to the MUD:
    ; /def beerecho = say %{*}
    ; /def beerbreath = :takes a deep breath.
    
    /def beerbottles = \
        /if ({1} == 1) /echo 1 bottle of beer%; \
        /else /echo %{1} bottles of beer%; \
        /endif
    
    /def beer1 = /beerecho $(/beerbottles %{1}) on the wall%2
    /def beer2 = /beerecho $(/beerbottles %{1}).
    /def beer3 = /beerecho Take one down and pass it around,
    
    /def beer = \
        /let bottles=%{1-99}%; \
        /while ( bottles > 0 ) \
    	/beer1 %{bottles} ,%; \
    	/beer2 %{bottles}%; \
    	/beer3%; \
    	/let bottles=$[bottles - 1]%; \
    	/if ( bottles == 0 ) /break%; /endif%; \
    	/beer1 %{bottles} .%; \
    	/beerbreath%; \
        /done%; \
        /beerecho No more bottles of beer on the wall.
    

    SR

    SR (Synchronizing Resources) is an educational language with built-in multi-threading and multi-processing. The language is available at ftp://ftp.cs.arizona.edu/sr/
    # SR version of 99 bottles of beer
    # by David Larsson 
    # mailto:f92dala@dd.chalmers.se    http://www.dd.chalmers.se/~f92dala
    #
    # This version demonstrates some of SR's concurrent aspects, simulating
    # the (common?) situation where 99 people drink one bottle of beer each
    # simultaneously, while singing exactly one verse of the song.
    #
    resource main()
        op sing_it(int; string[120])
    
        # Create 99 processes (or, rather, threads)
        # for the verses in the song
        process swing_it(bottle := 1 to 99)
            var bottle1_str, bottle2_str : string[15];
    
            if bottle > 2 ->
                bottle1_str := string(bottle) || " bottles";
                bottle2_str := string(bottle-1) || " bottles";
            [] bottle = 2 ->
                bottle1_str := "2 bottles";
                bottle2_str := "1 bottle";
            [] else ->
                bottle1_str := "1 bottle";
                bottle2_str := "No more bottles";
            fi
            
            # Send the verse back to the main thread
            send sing_it(bottle, 
                      bottle1_str || " of beer on the wall, "
                       || bottle1_str || " of beer...\n"  
                       || "Take one down and pass it around\n" 
                       || bottle2_str || " of beer on the wall\n");
        end swing_it
    
        # Make sure the verses get printed in the right order
        fa expected := 99 downto 1 ->
            in sing_it(bottle, verse) st bottle = expected ->
                write(verse);
            ni
        af
    
        # I guess the bartender sings this one
        write("Go to the store, buy some more!");
        write("99 bottles of beer on the wall");
    end main
    

    Simscript

    SIMSCRIPT is a simulation language from CACI and runs on PCs and VAXen.
    '' 99 Bottles of Beer using SIMSCRIPT
    '' Author: Jeremy Konopka  
    
    PREAMBLE
            PROCESSES
                    INCLUDE brewer, drinker
            RESOURCES
                    INCLUDE bottle
            DEFINE countem AS A INTEGER VARIABLE
    
    END
    
    MAIN
            CREATE EVERY bottle(1)
            LET U.bottle(1) = 1
            LET countem=100
            ACTIVATE A brewer NOW
            START SIMULATION
            PRINT 1 LINE THUS
               No more bottles of beer on the wall.
    
    END
    
    PROCESS brewer
            FOR I=1 TO 99
            DO
                    ACTIVATE A drinker NOW
            LOOP
    END
    
    PROCESS drinker
    
            REQUEST 1 bottle(1)
            RELINQUISH 1 bottle(1)
            LET countem = countem - 1
    
            IF countem > 1 
            PRINT 3 LINES WITH countem, countem THUS
              ** bottles of beer on the wall.
              ** bottles of beeeeer ...,
              Take one down, pass it around,
            ELSE
            PRINT 3 LINES WITH countem, countem THUS
              ** bottle of beer on the wall.
              ** bottle of beeeeer ...,
              Take it down, pass it around,
            ALWAYS
            IF countem > 2 
            PRINT 2 LINES WITH countem-1 THUS
              ** bottles of beer on the wall.
    
            ALWAYS
            IF countem = 2 
            PRINT 2 LINES THUS
              One more bottle of beer on the wall.
    
            ALWAYS
    END
    

    Word Basic

    For the Microsoft Word word processor.
    ' Word Basic version of 99 bottles of beer
    ' by Cory Sandahl (sandahl@u.washington.edu) 12/10/96
    
    Sub MAIN
    
    FileNew .NewTemplate = 1, .Template = "Normal.DOT"
    StartOfDocument
    s$ = "s"
    
    For NumberOfBeers = 99 To 1 Step - 1
    
        Insert Str$(NumberOfBeers) + " bottle" + s$ + " of beer on the wall," + Chr$(11)
        Insert Str$(NumberOfBeers) + " bottle" + s$ + " of beer..." + Chr$(11)
        Insert "Take one down, pass it around," + Chr$(11)
        
        If (NumberOfBeers - 1) < 2 Then
            s$ = ""
        End If
    
        Insert Str$(NumberOfBeers - 1) + " bottle" + s$ + " of beer on the wall. " + Chr$(11) + Chr$(11)
    
    Next
    Insert Chr$(11) + Chr$(11) + "No more beer.  Bye-bye."
    
    End Sub
    

    Silk

    Silk is a language for generating web pages on the fly.
    
    <%sub default()%>
    <html><title>SilkyBeers</title><body><h1>99 beers on the wall, silk style...</h1><br><br><br>
    <%
    	nBeers = 99
    	while (nBeers > 0)
    		?CStr(nBeers) & " bottles of beer on the wall,"
    		?Cstr(nBeers) & " bottles of beer..."
    		?"Take one down, pass it around,"
    		nBeers = nBeers - 1
    		?CStr(nBeers) & " bottles of beer on the wall.<br>"
    	wend
    %>
    </body></html>
    <%end sub%>
    
    

    Usertalk

    Macintosh scripting language
    on ninetyNineBottles() {
      local {
        lyrics = "";
        bottleStartCount = 99;
        bottleString = "";
        eol = "\r"};
    
      on numBottles(theCount) {
        local {
          s = ""};
        case theCount {
          0 {
            s = "No more bottles"};
          1 {
            s = "1 more bottle"}}
        else {
          s = theCount + " bottles"};
        return(s)};
    
      on finishVerse(theCount) {
        local {
          s = "Take one down and pass it around, " + eol};
        s = s + numBottles(theCount - 1) + " of beer on the wall."\
        + eol + eol;
        return(s)};
    
      for bottleCount = bottleStartCount downto 1 {
        bottleString = numBottles(bottleCount);
        lyrics = lyrics + bottleString + " of beer on the wall, "\
        + bottleString + " of beer." + eol + finishVerse(bottleCount)};
      lyrics = lyrics + "No more bottles of beer on the wall, "\
      + "no more bottles of beer." + eol\
      + "Go to the store and buy some more." + eol\
      + "99 bottles of beer on the wall.";
      return(lyrics)};
    
    theLyrics = @workspace.lyrics99;
    
    if not defined (theLyrics^) {
      new (wptextType, theLyrics)};
    
    target.set (theLyrics);
    
    wp.setText(ninetyNineBottles());
    
    edit (theLyrics); Ťopen it in a window
    
    window.zoom("workspace.lyrics99")
    

    Terse

    \\\\\\\\
    \ Beer \
    \\\\\\\\
    \
    \   Program to print the lyrics to "99 Bottles of Beer on the Wall"
    \   Runs under any version of DOS, 176 byte .COM file.
    \
    \   Written in TERSE by jim-neil@digital.net (Jim Neil).  TERSE is
    \   an x86 specific language that has the same level of control as
    \   assembly, with the look-and-feel and ease-of-use of a HLL.
    \
    \   For more information on TERSE, visit the TERSE website at:
    \                      http://www.terse.com
    
    main Group code,data;
    Assume cs:main,ds:main;
    O Equ ;
    
    code Segment byte;
    Org 0100h;
    
    data Segment byte;
      ' m0 =" Bottle$";
      ' m1 =" of Beer on the Wall";
      ' nl =(10,13,'$');
      ' m2 =" of Beer", =(10,13);
      ' m3 ="Take one down and pass it around", =(10,13,'$');
    data EndS;
    
    Beer Proc;
      cx = 99;                      \ cx = number to do.
      {                             \ for cx = 99..1, do...
        dx = O(nl); ah = 9; !21h;   \ new line.
        al = cl; =.Bottles;         \ print number and "Bottle(s)".
        dx = O(m1); ah = 9; !21h;   \ output lyric line 1.
        al = cl; =.Bottles;         \ print number and "Bottle(s)".
        dx = O(m2); ah = 9; !21h;   \ output lyric lines 2-3.
        al = cl-; =.Bottles;        \ print number - 1 and "Bottle(s)".
        dx = O(m1); ah = 9; !21h;   \ output lyric line 4.
      }-.;                          \ loop till done...
      !20h;                         \ return to DOS.
    Beer EndP;
    
    \\\\\\\\\\\
    \ Bottles \
    \\\\\\\\\\\
    \
    \   Bottles prints "n Bottle(s)", controling plural based on the
    \   value of n passed in al.
    \
    \   Entry Conditions:
    \       al = n.
    \       ah = Scratch;
    \       dx = Scratch;
    \
    \   Exit Conditions:
    \       ax = scratch.
    \       dx = scratch.
    
    Bottles Proc;
      =ax; =.BinDec;                \ print number of beers.
      dx = O(m0); ah = 9; !21h;     \ output "bottle".
      ax=; al - 1 ? <>              \ if not 1...
      { dl = 's'; ah = 2; !21h; };  \ make it plural.
      .=;                           \ and, return...
    Bottles EndP;
    
    \\\\\\\\\\
    \ BinDec \
    \\\\\\\\\\
    \
    \   BinDec prints a binary number (0-63h) in al to the screen
    \   in decimal with leading zero supression.
    \
    \   Entry Conditions:
    \       ah = scratch.
    \       al = number to convert.
    \       dx = scratch.
    \
    \   Exit Conditions:
    \       ax = scratch.
    \       dx = scratch.
    
    BinDec Proc Near;
      "*; ax + '00'; dh = al;       \ split and convert, dh = save LSB.
      ah - '0' ? <>                 \ if MSB is non-zero...
      { dl = ah; ah = 2; !21h; };   \ then, output MSB.
      dl = dh; ah = 2; !21h;        \ output LSB.
      .=;                           \ and return...
    BinDec EndP;
    
    code EndS;
    End Beer;
    

    TinTin

    Yet another Mud client language like tinyfugue.
    #nop 99 Bottles of beer for TinTin++ (Mud Client)
    #nop Coded 1997, Andrew Forster 
    #var {do} {#showme}
    #nop (can use say if you want to sing to the mud :-) )
    #alias {beer %0} {#math {wang} {%%0-1}; $do %0 bottles of beer on the
    wall; $do %0 bottles of beer; $do take one down, pass it around,;
    beerloop; nobeer;}
    #nop The initial part of the beer call
    #alias {beerloop} {bl $wang}
    #nop a weird way of doing it, but the only way I can see of getting the
    #nop maths to propagate into the beer statement.
    #alias {bl %0} {#loop {%%0, 2} {$do %0 bottles of beer on the wall; $do
    -------; $do %0 bottles of beer on the wall; $do %0 bottles of beer; $do
    take one down, pass it around; $do one bottle of beer on the wall}}
    #nop The main loop of the beer passing
    #alias {nobeer} {$do --------; $do one bottle of beer on the wall; $do
    one bottle of beer; $do take one down pass it around; $do fuck me
    there's no beer left; }
    #nop No beer left. So give up :-)
    

    Trumpet

    This is the scripting language used by the Trumpet Winsock dialer.
    #  99 Bottles of Beer on the Wall
    #  Written by Andrew Turley aturley@sound.net
    $para = " bottle"
    $parb = " of beer on the wall,"
    $parc = " of beer."
    $pard = "Take one down, pass it around,"
    $pare = " of beer on the wall."
    $parf = "no bottles of beer on the wall!"
    $pl = "s"
    %beer = 99
    repeat
      display %beer
      display $para
      if ! %beer = 1
        display $pl
      end
      display $parb\n
      display %beer
      display $para
      if ! %beer = 1
        display $pl
      end  
      display $parc\n
      display $pard\n
      %beer = %beer - 1
      if %beer > 0
        display %beer
        display $para
        if %beer > 1
          display $pl 
        end
        display $pare\n
      end
      if %beer = 0
        display $parf\n
      end
      display \n
    until %beer = 0
    

    VICC

    VICC is a Pascal-like language used in a Compilers course at Helsinki University of Technology
    // 99 Bottles of Beer in VICC = VICC's Intended for Compiler Courses
    // (C) 1996 Juha Autero
    
    DEFINE nl(tabify : Int) : Int
      IF tabify != 0 THEN
        WriteString("\n\t");
      ELSE
        WriteString("\n");
      END;
      RETURN 0;
    END;
    
    DEFINE beer(b : Int) : Int
      WriteInt(b);
      WriteString(" bottles of beer");
      RETURN 0;
    END;
    
    DEFINE Main() : Int
      DEFINE i : Int;
      i := 99;
      WHILE i >= 1 DO
        nl(1);
        beer(i);
        WriteString(" on the wall,");
        nl(1);
        beer(i);    
        WriteString(".");
        nl(1);
        WriteString("Take one down, pass it around");
        nl(1);
        beer(i - 1);
        WriteString(" on the wall.");
        nl(0);
        i := i - 1;
      DONE;
    END;
    

    UltraMacros

    This is a scripting language for AppleWorks word processor on the Apple ][. Run this by pressing the Solid-Apple-B key. (Code courtesy Scott Alfter (salfter@theonramp.net) )
    start
    B:<all><oa-q esc>1<rtn>3<rtn>1<rtn>BottlesOfBeer<rtn x=99 begin print x>
    bottles of beer on the wall,<rtn print x> bottles of beer,<rtn>Take one
    down, pass it around,<rtn x=x-1 print x> bottles of beer on the wall.<rtn
    rtn ifnot x=0 rpt elseoff>!
    

    troff

    Similar to nroff, this is a text-formatting language.
    .\"
    .\" 99 bottles of beer.
    .\" [ntg]roff macro
    .\" Jaap Akkerhuis
    .\"
    .if n .pl 1
    .nr b 99 1
    .nf
    .ds b "of beer
    .ds s, " \*b on the wall,
    .ds t take one down, pass it around,
    .ds s. " \*b on the wall.
    .ds B " bottles
    .de BB
    .if \\nb=1 .rn BB xx
    \\nb\\*B\\*(s, \\nb\\*B \\*b,
    \\*t
    .if \\n-b=1 .ds B " bottle
    .if \\nb \\nb\\*B\\*(s.
    .BB
    ..
    .BB
    no more\*Bs\*(s.
    

    SAUL

    Home-brew language. See http://keaggy.intmed.mcw.edu/saul.html for details
    ;
    ; 99 Bottles of Beer in SAUL
    ;    (http://keaggy.intmed.mcw.edu/saul.html)
    ;
    ; RTK, rkneusel@post.its.mcw.edu, 10-Apr-97
    ;
    
           fixn(0)
           setn(n,99)
    :loop, putn(n)
           disp(` bottles of beer on the wall, `)
           putn(n)
           disp(` bottles of beer.`)
           putc(13)
           disp(`Take one down, pass it around, `)
           subt(n,1,m)
           putn(m)
           comp(m,1)
           brne(:here)
           disp(` bottle of beer on the wall.`)
           jump(:there) 
    :here, disp(` bottles of beer on the wall.`)
    :there,putc(13)
           putc(13)
           comp(n,2)
           breq(:last)
           subt(n,1,n)
           jump(:loop)
    :last, disp(`1 bottle of beer on the wall, 1 bottle of beer.`)
           putc(13)
           disp(`Take one down, pass it around, `)
           disp(`no more bottles of beer on the wall.`)  
           endp
    

    Transact SQL

    See also SQL.
    /*	Microsoft Transact-SQL version of the beer song
    **	Joseph Thoennes, thoennes@paranet.com
    */
    set nocount on
    create table #beer (bottle tinyint identity)
    while (select isnull(max(bottle),0) from #beer) < 99 insert into #beer
    default values
    select ltrim(str(bottle)) + ' bottle' + case when bottle > 1 then 's' end
    + ' of beer on the wall, '
    + ltrim(str(bottle)) + ' bottle' + case when bottle > 1 then 's' end + '
    of beer, take '
    + case when bottle > 1 then 'one' else 'it' end + ' down, pass it around,
    '
    + case when bottle - 1 > 0 then ltrim(str(bottle - 1)) else 'no more' end
    + ' bottle' + case when bottle - 1 <> 1 then 's' end + ' of beer on the
    wall.'
    from #beer order by bottle desc
    drop table #beer
    

    TECO

    TECO is a text-editor/programming-language that looks more like line noise than something people are supposed to understand. The ^A is a literal Ctrl-A keystroke, and the ^[ is a literal ESC key.
    ! -- TECO version of 99 Bottles of beer
      -- Hacked by Akira KIDA, <SDI00379@niftyserve.or.jp> !
    
    hk@i#
    qp-1"> qp:= ^A bottles^A '
    qp-1"= qp:= ^A bottle^A '
    qp"= ^ANo more bottles^A '
    ^A of beer^A
    #hxbhk
    
    @i#
    qnup
    qn<
       mb ^A on the wall, ^A
       mb ^A.
    Take one down, pass it around.
    ^A
       qp-1up
       mb ^A on the wall.
    ^A
    >#
    hxmhk
    
    99un
    mmex^[^[
    

    YACC

    I had my own notions of how this should work, but James was nice enough to send this one, so here it is. YACC stands for "Yet Another Compiler Compiler" and it's purpose is to create compiler grammars and parse them. Conventionally, YACC should read ordered text and do something intelligent with it. In this case, the code should be driven by text that represents the beer to be consumed. C source code is generated by YACC to do the dirty work. This is a language that makes languages. Consequently, it is in a world unto itself.
    %{
    /*
    ** 99 bottles of beer yacc-like
    ** by: James Copher jec@netcom.com
    */
    
    #include
    static int bottles=99;
    %}
    
    %union{ int bottle; }
    %token  BOTTLES NOMORE
    %type  beer nomore
    %start round
    
    %%
    round    : beer nomore {
                YYACCEPT;
            };
    beer    : BOTTLES {
                printf("%d bottles of beer on the wall\n%d bottles of beer\n"
                    "Take one down,\npass it around\n",$1,$1);
            }
            | beer BOTTLES {
                printf("%d bottle%s of beer on the wall\n\n"
                    "%d bottle%s of beer on the wall\n%d bottle%s of beer\n"
                    "Take one down\npass it around\n",
                    $2,$2!=1?"s":"",$2,$2!=1?"s":"",$2,$2!=1?"s":"");
            };
    nomore	: NOMORE {
                printf("No more bottles of beer on the wall\n");
            };
    %%
    
    yyerror(){}
    yylex(){ if(bottles){ yylval.bottle=bottles--; return BOTTLES; } return NOMORE; }
    main(){ yyparse(); }
    

    4Test

    4Test is the language used for GUI testing by Segue Software's QA Partner.
    // 4Test Version of 99 Bottles of beer
    //
    // Eric DeCosta 
    //
    testcase bottles()
    	INTEGER bottles
    	for (bottles = 99; bottles >0;)
    		print("{bottles}  bottle(s) of beer on the wall,")
    		print("{bottles}  bottle(s) of beer.")
    		print("Take one down, pass it around,")
    		print("{--bottles} bottle(s) of beer on the wall.")
    

    SPSS

    SPSS is a statistical programming language.
    ****************************************************************************
    * File:			beer.sps
    * Source Code:	SPSS 5.0
    * System/OS:		HP/UNIX
    * Written By:		Keith Chidsey (keithc@gsbc.com)
    *
    * Write out lyrics to "99 Bottles of Beer on the Wall" to file .
    ****************************************************************************
    
    FILE HANDLE    	DUMMY/NAME'BEER.SPS'/LRECL=80
    FILE HANDLE    	BEERSONG/NAME'BEERSONG'/LRECL=80
    
    DATA LIST 		FILE=DUMMY FIXED RECORDS=1/
    				DUMMY(A1)
    
    STRING			LYRIC1,LYRIC2,SPACE(A80)
    
    LOOP			BOTTLES=99 TO 1 BY -1
    COMPUTE		LYRIC1=CONCAT(STRING(BOTTLES,F2),
     				' BOTTLES OF BEER ON THE WALL, ',
    				STRING(BOTTLES,F2),
    				' BOTTLES OF BEER.')
    COMPUTE		LYRIC2=CONCAT('TAKE ONE DOWN, PASS IT AROUND, ',
    				STRING(BOTTLES-1,F2),
    				' BOTTLES OF BEER ON THE WALL.')
    WRITE			OUTFILE=BEERSONG RECORDS=3/
    				LYRIC1/LYRIC2/SPACE
    END LOOP
    EXECUTE
    
    FINISH
    

    VScript

    VScript version, a script language for Virc'96/97, an IRC client for Windows 95.
    // BEER.VSC - Beer 1.0
    // Developed under Visual IRC '96 1.00rc5a
    
    Name Beer 1.0
    
    // Aliases
    
    Alias BEER
      @l $Bottle=99
      while ( $Bottle > 1 )
        TextOut clBlue $Bottle Bottles of beer on the wall,
        TextOut clBlue   $Bottle Bottles of beer.
        $Bottle--
        TextOut clBlue Take one down, pass it around,
        TextOut clBlue    $Bottle Bottles of beer on the wall.
        TextOut clBlue
      endwhile
    
      TextOut clRed 1 Bottle of Beer on the wall,
      TextOut clRed    1 Bottle of Beer.
      TextOut clRed Take One Down, Pass it around,
      TextOut clRed    No more bottles of Beer on the wall.
    
      -@ $Bottle
    EndAlias
    

    SuperTalk

    -- Here's 99 Bottles of Beer on the Wall in the
    -- SuperTalk language. Card field "NumberOfBottles"
    -- has a 99 in it but the user can change this
    -- before clicking on the start button.
    -- 
    -- Christine Keuper 
    -- 
    
    
    on mouseUp
      
      repeat until cd fld "NumberOfBottles" <= 1
    
        put cd fld "NumberOfBottles" && "bottles of beer on the wall," &&
          cd fld "NumberOfBottles" &&  "bottles of beer" & RETURN & 
          "You take one down and pass it around," && 
          cd fld "NumberOfBottles" - 1 && "bottles of beer on the wall." & 
          RETURN  & RETURN after cd fld "lyrics"
    
        subtract 1 from cd fld "NumberOfBottles"
    
      end repeat
      
      put cd fld "NumberOfBottles" && "bottle of beer on the wall," && 
        cd fld "NumberOfBottles" && "bottle of beer" & RETURN & 
        "You take one down and pass it around," && 
        cd fld "NumberOfBottles" - 1 && "bottles of beer on the wall." & 
        RETURN  & RETURN after cd fld "lyrics"
    
      subtract 1 from cd fld "NumberOfBottles"
      
    end mouseUp
    

    SAOL

    SAOL is the music-synthesis language which is part of the MPEG-4 standard. There's a homepage for SAOL at http://sound.media.mit.edu
    Orchestra (beer.saol) :
    
    global {
      srate 1000; // sip rate
      krate 100;  // beer rate
    }
    
    instr beer() {
      ksig drink;
    
      drink = kline(99,1,1);
    
      if (drink == 0) {
        kdump("No bottles of beer on the wall.");
        kdump("Everybody's drunk!");
        turnoff;
        }
    
      else {
        if (drink == 1) {
          kdump(drink," bottle of beer on the wall.");
          kdump(drink," bottle of beer.");
        } 
        else { 
          kdump(drink," bottles of beer on the wall.");
          kdump(drink," bottles of beer.");
        }
        kdump("Take one down, pass it around,");
    
        if (drink-1 == 1) {
          kdump(drink-1," bottle of beer on the wall.");
        } 
        else { 
          kdump(drink-1," bottles of beer on the wall.");
        }
        kdump();
      }
    }
    
    ------------
    
    Score (beer.sasl) :
    
    0 beer 1
    

    Visual Foxpro

    ********************************************
    * TAKE1DN.PRG  (For Visual Foxpro)         *
    * 99 Bottles: A simulation                 *
    * Richard Katz                             *
    * richkatz@earthlink.net                   *
    ********************************************
    
    wall=createobject("dispcontainer")
    wall.name="wall"
    clear
    
    **************************************
    * First put the beer on the wall.
    for i=1 to 99
        oname="b"+ltri(str(i))
        wall.addobject(oname,"bottle")
    endfor
    
    **************************************
    * So we can get what's in the bottles...
    obcont=wall.objects(1).content
    
    ***************************************
    * And away we go.
    do while wall.controlcount>0 
       ? wall.dispself(), "of",obcont,"on the",lower(wall.name)+","
       ? wall.dispself(), "of", obcont    
       wall.removeobject(wall.objects(wall.controlcount).name)
       ? wall.dispself(), "of", obcont
       if wall.controlcount>0
          ?? ",  Oh..."
       endif      
    enddo   
    define class dispcontainer as container
    proc dispself
    
    return ltri(str(this.controlcount))+" "+this.dispobj()
    proc dispobj    
       if this.controlcount>0
          obout=lower(this.objects(1).class)
       else
          obout="nothing"
       endif
       if this.controlcount<>1
          obout=obout+"s"
       endif
    return obout   
    enddefine
    
    define class bottle as custom
      content="beer"
      proc destroy
        ? "take one down, pass it around."
      endproc
    enddefine
    

    ZZT

    An ansi gaming language, apparently with no looping constructs. I trimmed the middle section for simplicity.
    - -- - --- -- ---- ---- --------------------------------.
     keebler@wco.com - http://wco.com/~keebler/             |
     keebler/keebobler on IRC                               :
    @Beerman
    #cycle 1
    #send chug
    #end
    :sing
    bottles of beer!  Take one down, pass it around
    #sleep 1
    #zap chug
    #send chug
    #end
    :chug
    99 bottles of beer on the wall
    99
    #send sing
    #end
    :chug
    98 bottles of beer on the wall
    98
    #send sing
    #end
    :chug
    2 bottles of beer on the wall
    2
    #send sing
    #end
    :chug
    1 bottles of beer on the wall
    1
    #send sing
    #end
    :chug
    No more bottles of beer on the wall,
    no more bottles of beer.
    Go to the store, buy some more,
    99 bottles of beer on the wall!
    #die
    #en

    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.

    Back to the Funhouse