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;