Voting

Category

real language

Bookmarking

Del.icio.us Digg Diigo DZone Earthlink Google Kick.ie
Windows Live LookLater Ma.gnolia Reddit Rojo StumbleUpon Technorati

Language Eiffel: Analysis, Design and Programming

(ECMA-367 syntax and 10 language features)

Date:12/05/09
Author:Finnian Reilly
URL:n/a
Comments:0
Info:http://www.ecma-international.org/publications/standards/Ecma-367.htm
Score: (5.00 in 1 votes)
class
	THE_99_BOTTLES_OF_BEER_APPLICATION

create
	make

feature {NONE} -- Initialization

	make is
			-- Run application.
		local
			lyrics: SONG_LYRICS
			bottle_count: INTEGER
		do
			print ("Lyrics of the song " + Max_bottles.out + " Bottles of Beer")
			io.put_new_line
			io.put_new_line

			create lyrics.make

			from
				bottle_count := Max_bottles
			invariant
				is_true: bottle_count + lyrics.verse_count = Max_bottles

			until bottle_count < 0 loop
				lyrics.new_verse

				lyrics.append_long_status_clause (bottle_count)
				lyrics.append_status_clause (bottle_count)
				lyrics.new_sentence

				bottle_count := bottle_count - 1

				if bottle_count < 0 then
					lyrics.append_go_to_the_store_clause
					lyrics.append_long_status_clause (Max_bottles)
				else
					lyrics.append_take_one_down_clause
					lyrics.append_long_status_clause (bottle_count)
				end
			end

			lyrics.print_to_medium (io.output)
		end

feature {NONE} -- Constants

	Max_bottles: INTEGER is 99

end -- class APPLICATION

class
	SONG_LYRICS

inherit
	LINKED_LIST [VERSE]
		rename
			make as make_list,
			count as verse_count,
			last as	last_verse
		end

create
	make

feature -- Initialization

	make is
			--
		do
			make_list
		end

feature -- Element change

	append_long_status_clause (bottle_count: INTEGER) is
			--
		local
			long_status: LONG_BOTTLE_STATUS_CLAUSE
		do
			long_status := bottle_count
			append_to_last_sentence (long_status)
		end

	append_status_clause (bottle_count: INTEGER) is
			--
		local
			status: BOTTLE_STATUS_CLAUSE
		do
			status := bottle_count
			append_to_last_sentence (status)
		end

	append_go_to_the_store_clause is

		do
			append_to_last_sentence ("Go to the store and buy some more")
		end

	append_take_one_down_clause is

		do
			append_to_last_sentence ("Take one down and pass it around")
		end

	append_to_last_sentence (clause: CLAUSE) is

		do
			if last_verse.last_sentence.is_empty then
				clause.capitalize_first
			end
			last_verse.last_sentence.extend (clause)
		end

feature -- Access

	new_verse is

		do
			extend (create {VERSE}.make)
			new_sentence
		end

	new_sentence is

		do
			last_verse.extend (create {SENTENCE}.make)
		end

feature -- Output		

	print_to_medium (io_medium: IO_MEDIUM) is
			--

		do
			do_all (agent {VERSE}.print_to_medium (io_medium))
		end

end -- class SONG_LYRICS

class
	VERSE

inherit
	LINKED_LIST [SENTENCE]
		rename
			last as last_sentence
		end

create
	make

feature -- Output

	print_to_medium (io_medium: IO_MEDIUM) is
			--
		do
			do_all (agent {SENTENCE}.print_to_medium (io_medium))
			io_medium.put_new_line
		end

end -- class VERSE

class
	SENTENCE

inherit
	LINKED_LIST [CLAUSE]
		rename
			item as clause,
			extend as extend_list
				-- Workaround for a bug in 6.3, fixed in 6.4 (inherited precondition not reached)
		end

create
	make

feature -- Element change

	extend (a_clause: like clause) is
			--
		require
			first_sentence_starts_with_capital_letter:
				is_empty implies not a_clause.i_th_word (1).item (1).is_alpha or else a_clause.i_th_word
(1).item (1).is_upper
		do
			extend_list (a_clause)
		end

feature -- Basic operations

	print_to_medium (io_medium: IO_MEDIUM) is
			--
		do
			from start until after loop
				if not isfirst then
					io_medium.put_string (", ")
				end
				clause.print_to_medium (io_medium)
				forth
			end
			io_medium.put_string (".")
			io_medium.put_new_line
		end

end -- class SENTENCE

class
	WORD_LIST

inherit
	LINKED_LIST [STRING]
		rename
			first as first_word,
			item as word,
			i_th as i_th_word
		end

feature	-- Initialization

	make_from_string (str: STRING) is
			--
		do
			make
			append_string (str)
		end

feature -- Element change

	capitalize_first is
			-- Make first letter uppercase
		require
			at_least_one_character: first_word.count >= 1
		do
			if not is_empty then
				first_word.put ((first_word @ 1).as_upper, 1)
			end
		end

	append_string (str: STRING) is
			-- Inline agent demo
		do
			str.split (' ').do_all (
				agent (a_word: STRING) do extend (a_word) end
			)
		end

	append_other (other: WORD_LIST) is
			--
		do
			other.do_all (agent extend)
		end

feature -- Output

	print_to_medium (io_medium: IO_MEDIUM) is
			--
		do
			from start until after loop
				if not isfirst then
					io_medium.put_character (' ')
				end
				io_medium.put_string (word)
				forth
			end
		end

end -- class WORD_LIST

class
	QUANTITY_EXPRESSION

inherit
	WORD_LIST
		rename
			make as make_list
		end

create
	make, make_from_tuple

convert
	make_from_tuple ({TUPLE [STRING, INTEGER]})

feature {NONE} -- Initialization	

	make (countable_noun: STRING; quantity: INTEGER) is
			--
		do
			make_list
			if quantity = 0 then
				append_string ("no more")
			else
				append_string (quantity.out)
			end
			extend (create {COUNTABLE_NOUN}.make (countable_noun, quantity))
		end

	make_from_tuple (args: TUPLE [STRING, INTEGER]) is
			--
		do
			make_list;
			(agent make).call (args)
		end

end -- class QUANTITY_EXPRESSION

class
	CLAUSE

inherit
	WORD_LIST

create
	make_from_string

convert
	make_from_string ({STRING})

end -- class CLAUSE

class
	BOTTLE_STATUS_CLAUSE

inherit
	CLAUSE
		rename
			make as make_empty
		end

create
	make

convert
	make ({INTEGER})

feature {NONE} -- Initialization

	make (quantity: INTEGER) is

		local
			bottle_quantity: QUANTITY_EXPRESSION
		do
			make_empty
			bottle_quantity := [Bottle_singular, quantity]
			append_other (bottle_quantity)
			append_string ("of beer")
		ensure
			correct_grammatical_form_for_zero_bottles:
				quantity = 0 implies i_th_word (1).as_lower.is_equal ("no") and i_th_word (3).is_equal
(Bottle_plural)

			correct_plural_form_for_one_bottle:
				quantity = 1 implies i_th_word (2).is_equal (Bottle_singular)

			correct_plural_form_for_more_than_one_bottle:
				quantity > 1 implies i_th_word (2).is_equal (Bottle_plural)
		end

feature -- Constants

	Bottle_singular: STRING is "bottle"

	Bottle_plural: STRING is
			--
		once
			create Result.make_from_string (Bottle_singular)
			Result.append_character ('s')
		end

end -- class BOTTLE_STATUS_CLAUSE

class
	LONG_BOTTLE_STATUS_CLAUSE

inherit
	BOTTLE_STATUS_CLAUSE
		redefine
			make
		end

create
	make

convert
	make ({INTEGER})

feature {NONE} -- Initialization

	make (quantity: INTEGER) is

		do
			Precursor (quantity)
			append_string ("on the wall")
		end

end -- class LONG_BOTTLE_STATUS_CLAUSE

class
	COUNTABLE_NOUN

inherit
	STRING
		rename
			make as make_word
		end

create
	make

feature {NONE} -- Implementation

	make (noun: STRING; quantity: INTEGER) is
			--
		do
			make_from_string (noun)
			if quantity /= 1 then
				append_character ('s')
			end
		end

end -- class COUNTABLE_NOUN

Download Source | Write Comment

Alternative Versions

Comments

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!

Name:

eMail:

URL:

Security Code:
  
Comment: