The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
#!/usr/bin/perl

use 5.012;
no warnings "experimental";

use Spp qw(spp_repl grammar_to_ast parse_text lint_grammar spp_to_spp);
use Spp::LintAst qw(lint_spp_ast);
use Spp::Grammar qw(get_spp_grammar);
use Spp::Builtin;
use Spp::Tools;

my $action  = $ARGV[0];
my $grammar = $ARGV[1];
my $text    = $ARGV[2];

given ($action) {
  when ('--update') { update_spp() }
  when ('--lint')   { lint($grammar) }
  when ('--spp')    { spp($grammar, $text) }
  default { spp_repl() }
}

sub update_spp {
   my $grammar = get_spp_grammar();
   my $ast     = grammar_to_ast($grammar);
   lint_spp_ast($ast);
   $ast = clean_ast($ast);
   my $code = ast_to_module($ast);
   if (-e 'Spp/Ast.pm') {
      my $time = get_time();
      rename('Spp/Ast.pm', "Spp/Ast.pm.$time");
   }
   write_file('Spp/Ast.pm', $code);
}

sub ast_to_module {
   my $ast = shift;
   my $str = <<'EOFF';
package Spp::Ast;

use 5.012;

use Exporter;
our @ISA    = qw(Exporter);
our @EXPORT = qw(get_spp_ast);

sub get_spp_ast {
   return <<'EOF'
EOFF
   return $str . from_estr($ast) . "\nEOF\n }\n1;";
}

sub lint {
   my $file = shift;
   my $grammar = read_file($file);
   lint_grammar($grammar);
}

sub spp {
   my ($grammar_file, $text_file) = @_;
   my $grammar = read_file($grammar_file);
   my $text    = read_file($text_file);
   say parse_text($grammar, $text);
}