Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Computing > NZ Computing > One Man Went To Mow

Reply
Thread Tools

One Man Went To Mow

 
 
Lawrence D'Oliveiro
Guest
Posts: n/a
 
      11-17-2009
This is an exercise in using the GNU M4 macro processor to generate a
nursery rhyme. I wonder if anyone has tried to use M4 as, say, a more
powerful substitute for the C-language preprocessor? Anyway...

Starting from the bottom up, first of all I needed a way to turn a number
into words, so 1 becomes “one”, and so on up to 10 (the maximum number of
verses I’m going to generate). Here’s what I came up with:

define(`n', `regexp(` x one two three four five six seven eight nine ten', `^\'repeat(` [^ ]+', $1)` \([^ ]+\)', `\1')')

so “n(1)” expands to “one” and so on, where “repeat” is defined as

define(`repeat', `ifelse($2, 0, `', $2, 1, `$1', `$1`'repeat(`$1', eval($2 - 1))')')

so for example “repeat(abc, 3)” expands to “abcabcabc”.

Next, a macro to capitalize the first letter of a word:

define(`cap', `regexp(`$1', `^\(.\)\(.*\)$', `translit(`\1', `a-z', `A-Z')\2')')

so “cap(london)” expands to “London”. How many verses am I going to output:

define(`nrverses', 10)

A macro to generate an appropriate singular or plural noun phrase:

define(`nmen', `cap(n($1)) ifelse($1, 1, man, men)')

thus, “nmen(1)” expands to “One man”, “nmen(2)” expands to “Two men” and so
on.

Factoring the simple, repetitive parts of the verses:

define(`tomow', ` went to mow')
define(`mow1', `tomow a meadow')

This macro generates the first line of each verse:

define(`firstline', `nmen($1)`'tomow,mow1')

The remaining lines of each verse:

define(`restlines', `ifelse($1, 1, `nmen(1) and his dog,mow1', `nmen($1)
restlines(eval($1 - 1))')')

Starting to come together now. Each complete verse:

define(`verse', `firstline($1)
restlines($1)')

This one generates all the verses from the specified one up to the last one:

define(`verses', `verse($1)`'ifelse($1, nrverses, `', `

verses(eval($1 + 1))')')

So tell it to output from the first verse:

verses(1)

et voil*, the complete output:

One man went to mow, went to mow a meadow
One man and his dog, went to mow a meadow

Two men went to mow, went to mow a meadow
Two men
One man and his dog, went to mow a meadow

Three men went to mow, went to mow a meadow
Three men
Two men
One man and his dog, went to mow a meadow

Four men went to mow, went to mow a meadow
Four men
Three men
Two men
One man and his dog, went to mow a meadow

Five men went to mow, went to mow a meadow
Five men
Four men
Three men
Two men
One man and his dog, went to mow a meadow

Six men went to mow, went to mow a meadow
Six men
Five men
Four men
Three men
Two men
One man and his dog, went to mow a meadow

Seven men went to mow, went to mow a meadow
Seven men
Six men
Five men
Four men
Three men
Two men
One man and his dog, went to mow a meadow

Eight men went to mow, went to mow a meadow
Eight men
Seven men
Six men
Five men
Four men
Three men
Two men
One man and his dog, went to mow a meadow

Nine men went to mow, went to mow a meadow
Nine men
Eight men
Seven men
Six men
Five men
Four men
Three men
Two men
One man and his dog, went to mow a meadow

Ten men went to mow, went to mow a meadow
Ten men
Nine men
Eight men
Seven men
Six men
Five men
Four men
Three men
Two men
One man and his dog, went to mow a meadow

Of course, if you copied my code literally, you’ll end up with lots of
spurious blank lines interspersed. Inserting appropriate instances of the
necessary “dnl” calls in all the right places is left as an exercise for the
reader.
 
Reply With Quote
 
 
 
 
Ron McNulty
Guest
Posts: n/a
 
      11-17-2009
On Nov 17, 10:01*pm, Lawrence D'Oliveiro <l...@geek-
central.gen.new_zealand> wrote:
> This is an exercise in using the GNU M4 macro processor to generate a
> nursery rhyme. I wonder if anyone has tried to use M4 as, say, a more
> powerful substitute for the C-language preprocessor? Anyway...
>
> Starting from the bottom up, first of all I needed a way to turn a number
> into words, so 1 becomes one, and so on up to 10 (the maximum number of
> verses Im going to generate). Heres what I came up with:
>
> * * define(`n', `regexp(` x one two three four five six seven eight nine ten', `^\'repeat(` [^ ]+', $1)` \([^ ]+\)', `\1')')
>
> so n(1) expands to one and so on, where repeat is defined as
>
> * * define(`repeat', `ifelse($2, 0, `', $2, 1, `$1', `$1`'repeat(`$1', eval($2 - 1))')')
>
> so for example repeat(abc, 3) expands to abcabcabc.
>
> Next, a macro to capitalize the first letter of a word:
>
> * * define(`cap', `regexp(`$1', `^\(.\)\(.*\)$', `translit(`\1', `a-z', `A-Z')\2')')
>
> so cap(london) expands to London. How many verses am I going to output:
>
> * * define(`nrverses', 10)
>
> A macro to generate an appropriate singular or plural noun phrase:
>
> * * define(`nmen', `cap(n($1)) ifelse($1, 1, man, men)')
>
> thus, nmen(1) expands to One man, nmen(2) expands to Two men and so
> on.
>
> Factoring the simple, repetitive parts of the verses:
>
> * * define(`tomow', ` went to mow')
> * * define(`mow1', `tomow a meadow')
>
> This macro generates the first line of each verse:
>
> * * define(`firstline', `nmen($1)`'tomow,mow1')
>
> The remaining lines of each verse:
>
> * * define(`restlines', `ifelse($1, 1, `nmen(1) and his dog,mow1', `nmen($1)
> * * restlines(eval($1 - 1))')')
>
> Starting to come together now. Each complete verse:
>
> * * define(`verse', `firstline($1)
> * * restlines($1)')
>
> This one generates all the verses from the specified one up to the last one:
>
> * * define(`verses', `verse($1)`'ifelse($1, nrverses, `', `
>
> * * verses(eval($1 + 1))')')
>
> So tell it to output from the first verse:
>
> * * verses(1)
>
> et voil, the complete output:
>
> One man went to mow, went to mow a meadow
> One man and his dog, went to mow a meadow
>
> Two men went to mow, went to mow a meadow
> Two men * * * * * * * * * * * * * * * * *
> One man and his dog, went to mow a meadow
>
> Three men went to mow, went to mow a meadow
> Three men * * * * * * * * * * * * * * * * *
> Two men * * * * * * * * * * * * * * * * * *
> One man and his dog, went to mow a meadow *
>
> Four men went to mow, went to mow a meadow
> Four men * * * * * * * * * * * * * * * * *
> Three men * * * * * * * * * * * * * * * *
> Two men * * * * * * * * * * * * * * * * *
> One man and his dog, went to mow a meadow
>
> Five men went to mow, went to mow a meadow
> Five men * * * * * * * * * * * * * * * * *
> Four men * * * * * * * * * * * * * * * * *
> Three men * * * * * * * * * * * * * * * *
> Two men * * * * * * * * * * * * * * * * *
> One man and his dog, went to mow a meadow
>
> Six men went to mow, went to mow a meadow
> Six men * * * * * * * * * * * * * * * * *
> Five men * * * * * * * * * * * * * * * *
> Four men * * * * * * * * * * * * * * * *
> Three men * * * * * * * * * * * * * * * *
> Two men * * * * * * * * * * * * * * * * *
> One man and his dog, went to mow a meadow
>
> Seven men went to mow, went to mow a meadow
> Seven men * * * * * * * * * * * * * * * * *
> Six men
> Five men
> Four men
> Three men
> Two men
> One man and his dog, went to mow a meadow
>
> Eight men went to mow, went to mow a meadow
> Eight men
> Seven men
> Six men
> Five men
> Four men
> Three men
> Two men
> One man and his dog, went to mow a meadow
>
> Nine men went to mow, went to mow a meadow
> Nine men
> Eight men
> Seven men
> Six men
> Five men
> Four men
> Three men
> Two men
> One man and his dog, went to mow a meadow
>
> Ten men went to mow, went to mow a meadow
> Ten men
> Nine men
> Eight men
> Seven men
> Six men
> Five men
> Four men
> Three men
> Two men
> One man and his dog, went to mow a meadow
>
> Of course, if you copied my code literally, youll end up with lots of
> spurious blank lines interspersed. Inserting appropriate instances of the
> necessary dnl calls in all the right places is left as an exercise for the
> reader.


Not sure what the point is Lawrence, but the same algorithm can be
expresses in ordinary programming languages with a similar number of
lines and far greater clarity. For instance in Java:

package fiddle;

public class MenMowing {
private static final int MAX_MEN = 10;
private static final String[] describeMen =
{"No", "One man", "Two men", "Three men", "Four men",
"Five men", "Six men", "Seven men", "Eight men", "Nine men",
"Ten men"};

public static void main(String[] args) {
for (int i = 1; i <= MAX_MEN; i++) {
System.out.println(describeMen[i] + "" + " went to mow, went to
mow a meadow");
for (int j = i; j >= 1; --j){
System.out.println(describeMen[j] + (j == 1 ? " and his dog
went to mow a meadow" : ""));
}
System.out.println();
}
}
}

Regards

Ron
 
Reply With Quote
 
 
 
 
Lawrence D'Oliveiro
Guest
Posts: n/a
 
      11-18-2009
In message <(E-Mail Removed)>, Ron McNulty wrote:

> On Nov 17, 10:01 pm, Lawrence D'Oliveiro <l...@geek-
> central.gen.new_zealand> wrote:
>
>> [my entire posting quoted]


Tip: there’s no need to quote my entire posting, everybody knows what I said.

> Not sure what the point is Lawrence, but the same algorithm can be
> expresses in ordinary programming languages with a similar number of
> lines and far greater clarity. For instance in Java:


But you cannot embed Java in a data file. That’s the key point of macro
processors, e.g.
<http://sourceforge.net/mailarchive/forum.php?thread_name=494B6AF6.4090002%40geek-central.gen.nz&forum_name=dvdauthor-users>,
<http://sourceforge.net/mailarchive/forum.php?thread_name=494C549B.40703%40geek-central.gen.nz&forum_name=dvdauthor-users>.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Mow the lawn. Engrish commercial joevan Computer Support 17 04-10-2009 09:54 PM
DVD Verdict reviews: HE-MAN AND THE MASTERS OF THE UNIVERSE: SEASON ONE, VOLUME ONE and more! DVD Verdict DVD Video 0 11-02-2005 09:21 AM
New releases: The Man With the Golden Arm, Cinderella Man & Dead & Buried; Updated complete downloadable R1 DVD DB & info lists Doug MacLean DVD Video 0 08-16-2005 05:35 AM
Could not load type 'Namespace.Global' - one man's solution heromull ASP .Net 1 12-08-2004 03:42 PM
conflict between man perlipc and man perlfunc !? Jaap Karssenberg Perl Misc 0 01-09-2004 11:39 PM



Advertisments