#!/usr/bin/env perl use warnings; use strict; use feature qw/say state/; use Data::Dumper; use Capture::Tiny qw/capture_stdout/; my $DEBUG = 0; for my $filename (@ARGV) { open my $fh, '<', $filename or die "$filename: $!"; my $input = do { local $/; <$fh> }; # slurp close $fh; my $code = translate($input); $DEBUG and say ">>>>> Generated Code:\n", $code, "<<<<<"; # execute my ($output, $rv) = capture_stdout { eval $code }; $rv or die "eval failed: ".($@//'unknown error'); say ">>>>> Output:\n", $output, "<<<<<"; } sub translate { my ($input) = @_; state $packcnt = 1; my $pack = "Generated".$packcnt++; my $output = "{ package $pack;\n"; $output.= "no warnings; no strict;\n"; $output.= "#line 1 \"$pack\"\n"; while ($input=~/(.*?)<%/sgc) { $output.= "print ".perlstr($1).";\n" if length($1); $input=~/(.*?)%>\n?/sgc or die "couldn't find %>"; my $code = $1; $code =~ s/^=/print /; $code .= ";" unless $code=~/;\s*$/; $output.= "$code\n"; } my $str = substr $input, pos($input)//0; $output.= "print ".perlstr($str).";\n" if length($str); $output.= "} # end package $pack\n1;\n"; return $output; } sub perlstr { Data::Dumper->new([''.shift]) ->Terse(1)->Indent(0)->Useqq(1)->Dump }