Language Sather
(A more elaborate version)
Date: | 06/06/09 |
Author: | Michael Talbot-Wilson |
URL: | n/a |
Comments: | 3 |
Info: | n/a |
Score: | ![]() |
-- A more elaborate version of 99 Bottles Of Beer. -- Michael Talbot-Wilson, May-June 2009. ----------------------------------------------------------------- partial class N is const starting_number : INT := 99; end; class BEER -- The main class, containing main, where execution starts and ends. -- Compile with: cs -main BEER -chk_all all -o beer beer.sa is include N; main(args:ARRAY{STR}):INT is protect SING{B}::sing(starting_number); when STR then #ERR + #FMT("%s: %s\n", args[0], exception); return 1 end; return 0 end end; class SING{D_TYPE < $DITTY} is sing(verses:INT) pre verses > 0 is w : D_TYPE; w := D_TYPE::create(verses); loop #OUT + w + w.act! end end end; class B < $DITTY -- Bottles On The Wall is private const voidmsg:STR:="Class calls (:: calls) " "on the methods of class B will not be refreshing."; private attr num:INT; private attr at_start:INT; private invariant:BOOL is return void(self) or num.is_bet(-1, at_start) end; create(i:INT):SAME pre i > 0 post ~void(result) is r ::= new; r.num := i; r.at_start := i; return r end; private bottle:STR is return bottle(num) end; private bottle(i:INT):STR is if i = 1 then return "bottle" end; return "bottles" end; str: STR is if void(self) then raise voidmsg end; r:STR; case num when -1 then r:=""; when 0 then r:="No more bottles of beer on the wall, " "no more bottles of beer.\n" else r:=#FMT("<> <> of beer on the wall, <> <> of beer.\n", num, bottle, num, bottle).str; end; return r end; -- of routine str act!:STR pre void(self) or ~num.is_neg is if void(self) then raise voidmsg end; loop num := num-1; if num < 0 then yield "Go to the store and buy some more, " + at_start.str + " " + bottle(at_start) + " of beer on the wall.\n" elsif num = 0 then yield "Take it down and pass it around, " "no more bottles of beer on the wall.\n\n" else yield "Take one down and pass it around, " + num.str + " " + bottle + " of beer on the wall.\n\n" end; if num < 0 then quit end end end -- of iterator act! end; -- of class B abstract class $DITTY < $STR is create(arg:INT):SAME; str:STR; act!:STR end;
Download Source | Write Comment
Download Source | Write Comment
Add Comment
Please provide a value for the fields Name,
Comment and Security Code.
This is a gravatar-friendly website.
E-mail addresses will never be shown.
Enter your e-mail address to use your gravatar.
Please don't post large portions of code here! Use the form to submit new examples or updates instead!
Comments
private attr at_start:INT;
should be
readonly attr at_start:INT;
Then class B would be more useful. You could have an alternative main
class, e.g. to print out just one verse:
class ANO is
main is
w ::= #B(33);
loop
#OUT + w + w.act!;
until!(w.num < 33);
end;
end;
end;