#! /usr/bin/perl
use strict;
package Context;
my %versions = ();
sub new {
my $class = shift;
return bless {}, $class;
}
sub declareVersion {
my $self = shift;
my ($plugin, $version) = @_;
$versions{$plugin} = $version;
}
sub getVersion {
shift;
$versions{shift()}
}
sub addOpinion {
my $self = shift;
my ($plugin, $opinion) = @_;
$self->{$plugin} = [] unless exists $self->{$plugin};
push @{$self->{$plugin}}, $opinion;
}
package main;
sub usage;
# General tool stuff
use Getopt::Long;
my @plugins;
my $verbose;
GetOptions('plugin=s' => \@plugins, 'verbose' => \$verbose);
# Get input program.
my $snippet = eval {local $/; return <>};
print $snippet if $verbose;
# Load plugins
@plugins = grep {
eval{require "plugins/$_.pl"} ? 1 : (warn("Plug-in $_ failed to load.\n"), 0)
} @plugins;
# Start a new context;
my $ctx = Context->new;
# Initialization:
foreach (@plugins) {
$_->init($ctx) if UNIVERSAL::can($_, 'init');
}
# Do the stuff
foreach (@plugins) {
$_->evaluate($ctx, $snippet);
}
# Simple output.
while (my ($plugin, $opinions) = each %$ctx) {
my $ver = undef;
my $verstr = ($ver = Context->getVersion($plugin)) ?
"(Version $ver) " : '';
print "The plugin $plugin ${verstr}says:\n";
print join '\n', map { "\t$_\n" } @$opinions;
}
####
package grammar;
sub init {
my $pkg = shift;
my $ctx = shift;
$ctx->declareVersion($pkg, '0.1');
}
sub evaluate {
my $pkg = shift;
my ($ctx, $snippet) = @_;
if ($snippet =~ /use\s+strict;/) {
$ctx->addOpinion($pkg, "Uses strict. OK");
} else {
$ctx->addOpinion($pkg, "Does not use strict; Heathen swine!!");
}
}
1;
##
##
package bench;
use Benchmark;
sub evaluate {
my $pkg = shift;
my ($ctx, $snippet) = @_;
$ctx->addOpinion($pkg, timestr(timeit(400000, $snippet)));
}
1;