Acme-Cow-Interpreter
view release on metacpan or search on metacpan
bin/text2cow.pl view on Meta::CPAN
#
# Print program usage.
#
sub print_usage () {
print <<"EOF" or die "$PROGNAME: print failed: $!\n";
Usage: $PROGNAME [programfile]
Prints Cow source code that, when executed, prints a given text.
-h print usage and exit
-v print version information and exit
If file is omitted, text is read through the standard input.
Example: \$ printf 'Hello, World!\\n' | $PROGNAME > hello.cow
\$ cow hello.cow
Hello, World!
Report bugs to <pjacklam\@gmail.com>.
EOF
}
################################################################################
# output COMMAND
#
# Prints a COMMAND to the standard output.
sub output {
my $cmd = shift;
if ($ncmd_on_line == 20) {
print "\n" or die "$PROGNAME: print failed: $!\n";
$ncmd_on_line = 0;
} elsif ($ncmd_on_line > 0) {
print " " or die "$PROGNAME: print failed: $!\n";
}
print $cmd or die "$PROGNAME: print failed: $!\n";
++ $ncmd_on_line;
}
################################################################################
## Process command line options and arguments.
################################################################################
Getopt::Std::getopts('hv') or die <<"EOF";
For more information: $PROGNAME -h
EOF
print_usage, exit if $opt_h;
print_version, exit if $opt_v;
################################################################################
## This is where the real action begins.
################################################################################
die "$PROGNAME: Too many input arguments" if @ARGV > 1;
local $/ = undef; # file slurp mode
my $text = <>; # get input text string
die "$PROGNAME: No input" unless defined $text;
my $n = length $text; # get the number of characters in the string
my $prev_ord; # this variable holds the previous ordinal value
for (my $i = 0 ; $i < $n ; ++ $i) {
my $chr = substr($text, $i, 1); # get this character ...
my $ord = ord($chr); # ... and its ordinal value
if ($i == 0) {
# Increment current memory block value by 1 until we have got the right
# ordinal value.
for (my $j = 0 ; $j < $ord ; ++ $j) {
output('MoO');
}
} else {
if ($ord > $prev_ord) {
# Increment from previous value.
for (my $j = $prev_ord ; $j < $ord ; ++ $j) {
output('MoO');
}
} else {
if (($prev_ord - $ord) <= $ord) {
# Decrement from previous value.
for (my $j = $prev_ord ; $j > $ord ; -- $j) {
output('MOo');
}
} else {
# Reset current memory block value to 0, and increment to the
# desired value.
output('OOO');
for (my $j = 0 ; $j < $ord ; ++ $j) {
output('MoO');
}
}
}
}
# Print the character.
output('Moo');
$prev_ord = $ord;
}
print "\n" or die "$PROGNAME: print failed: $!\n";
( run in 1.977 second using v1.01-cache-2.11-cpan-140bd7fdf52 )