Acme-Chef
view release on metacpan or search on metacpan
lib/Acme/Chef.pm view on Meta::CPAN
# Please read the pod documentation in this file for
# details on how to reach the author and copyright issues.
package Acme::Chef;
use 5.006;
use strict;
use warnings;
use Carp;
use vars qw/$VERSION/;
$VERSION = '1.03';
use Acme::Chef::Recipe;
use Acme::Chef::Container;
use Acme::Chef::Ingredient;
=head1 NAME
Acme::Chef - An interpreter for the Chef programming language
=head1 SYNOPSIS
# Using the script that comes with the distribution.
chef.pl file.chef
# Using the module
use Acme::Chef;
my $compiled = Acme::Chef->compile($code_string);
print $compiled->execute();
my $string = $compiled->dump(); # requires Data::Dumper
# Save it to disk, send it over the web, whatever.
my $reconstructed_object = eval $string;
# or:
$string = $compiled->dump('autorun'); # requires Data::Dumper
# Save it to disk, send it over the web, whatever.
my $output_of_chef_program = eval $string;
=head1 DESCRIPTION
Chef is an esoteric programming language in which programs look like
recipes. I needn't mention that using it in
production environment, heck, using it for anything but entertainment
ought to result in bugs and chaos in reverse order.
All methods provided by Acme::Chef are adequately described in the
synopsis. If you don't think so, you need to read the source code.
There has been an update to the Chef specification. I have implemented
the changes and marked them in the following documentation with
"I<new specification>".
With that out of the way, I would like to present a pod-formatted
copy of the Chef specification from David Morgan-Mar's homepage
(L<http://www.dangermouse.net/esoteric/chef.html>).
=head2 METHODS
This is a list of methods in this package.
=over 2
=item compile
Takes Chef source code as first argument and compiles a Chef program from it.
This method doesn't run the code, but returns a program object.
=cut
sub compile {
my $proto = shift;
my $class = ref $proto || $proto;
my $code = shift;
defined $code or croak "compile takes one argument: a code string.";
my $self = {};
bless $self => $class;
my @paragraphs = $self->_get_paragraphs( $code );
my @recipes = $self->_paragraphsToRecipes(\@paragraphs);
$_->compile() foreach @recipes;
$self->{start_recipe} = $recipes[0]->recipe_name();
$self->{recipes} = {
map { ($_->recipe_name(), $_) } @recipes
};
return $self;
}
=item execute
Takes no arguments. Runs the program and returns its output.
=cut
sub execute {
my $self = shift;
my $start_recipe = $self->{recipes}->{ $self->{start_recipe} }->new();
$start_recipe->execute($self->{recipes});
return $start_recipe->output();
}
lib/Acme/Chef.pm view on Meta::CPAN
$serves = '';
}
}
push @recipes, Acme::Chef::Recipe->new(
name => $recipe_name,
comments => $comments,
ingredients => $ingredients,
cooking_time => $cooking_time,
temperature => $temperature,
method => $method,
serves => $serves,
);
}
return @recipes;
}
1;
__END__
=back
=head1 DESIGN PRINCIPLES
=over 2
=item *
Program recipes should not only generate valid output, but be easy to
prepare and delicious.
=item *
Recipes may appeal to cooks with different budgets.
=item *
Recipes will be metric, but may use traditional cooking measures such as
cups and tablespoons.
=back
=head1 LANGUAGE CONCEPTS
=head2 Ingredients
All recipes have ingredients! The ingredients hold individual data values.
All ingredients are numerical, though they can be interpreted as Unicode
for I/O purposes. Liquid ingredients will be output as Unicode characters,
while dry or unspecified ingredients will be output as numbers.
=head2 Mixing Bowls and Baking Dishes
Chef has access to an unlimited supply of mixing bowls and baking dishes.
These can contain ingredient values. The ingredients in a mixing bowl or
baking dish are ordered, like a stack of pancakes. New ingredients are
placed on top, and if values are removed they are removed from the top.
Note that if the value of an ingredient changes, the value in the mixing
bowl or baking dish does not. The values in the mixing bowls and baking
dishes also retain their dry or liquid designations.
Multiple mixing bowls and baking dishes are referred to by an ordinal
identifier - "the 2nd mixing bowl". If no identifier is used, the recipe
only has one of the relevant utensil. Ordinal identifiers must be digits
followed by "st", "nd", "rd" or "th", not words.
=head1 SYNTAX ELEMENTS
The following items appear in a Chef recipe. Some are optional. Items
must appear in the order shown below, with a blank line (two newlines)
between each item.
=head2 Recipe Title
The recipe title describes in a few words what the program does. For
example: "Hello World Souffle", or "Fibonacci Numbers with Caramel Sauce".
The recipe title is always the first line of a Chef recipe, and is
followed by a full stop.
recipe-title.
=head2 Comments
Comments are placed in a free-form paragraph after the recipe title.
Comments are optional.
=head2 Ingredient List
The next item in a Chef recipe is the ingredient list. This lists the
ingredients to be used by the program. The syntax is
Ingredients.
[initial-value] [[measure-type] measure] ingredient-name
[further ingredients]
Ingredients are listed one per line. The intial-value is a number.
I<New specification: The initial-value is now optional. Attempting to
use an ingredient without a defined value is a run-time error.>
The optional measure can be any of the following:
=over 2
=item *
C<g> | C<kg> | C<pinch[es]> : These always indicate dry measures.
=item *
C<ml> | C<l> | C<dash[es]> : These always indicate liquid measures.
=item *
C<cup[s]> | C<teaspoon[s]> | C<tablespoon[s]> : These indicate measures
which may be either dry or liquid.
=back
The optional measure-type may be any of the following:
( run in 2.990 seconds using v1.01-cache-2.11-cpan-437f7b0c052 )