XML-Axk
view release on metacpan or search on metacpan
lib/XML/Axk/Preparse.pm view on Meta::CPAN
# TODO permit the caller to say what to do with lines before the first pragma
unless(/^\h*(#|$)/) { # Ignore blanks and comments before the
# first Ln.
die "Source text can't come before a pragma line" unless @retval;
}
$retval[-1]->{text} .= $_;
#say "Stashed $_";
}
close $fh;
return \@retval, $hasLang if wantarray;
return \@retval;
} #pieces()
=head2 assemble
Assemble a script for C<eval> based on the results of a call to pieces().
Usage:
my $srNewText = assemble($filename, $lrPieces);
=cut
sub assemble {
my ($filename, $lrPieces) = @_ or croak("Need filename, pieces");
croak "Need pieces as a reference" unless ref $lrPieces eq 'ARRAY';
$filename =~ s{"}{-}g;
# as far as I can tell, #line can't handle embedded quotes.
my $retval = '';
foreach my $hrPiece (@$lrPieces) {
die "-B not yet implemented" if $hrPiece->{pragmas}->{B};
# Which language?
my $lang = ($hrPiece->{pragmas}->{L}->{digits} //
$hrPiece->{pragmas}->{L}->{name});
unless(defined $lang) {
$retval .= $hrPiece->{text};
next;
}
my $lang_module = "XML::Axk::L::L$lang";
# Does this language parse the source text itself?
my $want_text;
eval "require $lang_module";
die "Can't find language $lang: $@" if $@;
do {
no strict 'refs';
$want_text = ${"${lang_module}::C_WANT_TEXT"};
};
unless($want_text) { # Easy case: the script's code is still Perl
$retval .= "use $lang_module;\n";
$retval .= "#line $hrPiece->{start} \"$filename\"\n";
$retval .= $hrPiece->{text};
} else { # Harder case: give the Ln the source text
my $trailer =
"AXK_EMBEDDED_SOURCE_DO_NOT_TYPE_THIS_YOURSELF_OR_ELSE";
$retval .=
"use $lang_module \"$filename\", $hrPiece->{start}, " .
"<<'$trailer';\n";
$retval .= $hrPiece->{text};
$retval .= "\n$trailer\n";
# Don't need a #line because the next language will take care of it
}
}
return \$retval;
} #assemble()
=head2 preparse
Invokes pieces() and assemble(). Usage:
my $srTextOut = preparse($filename, $textIn);
C<textIn> can be a string or a string ref.
=cut
sub preparse {
my $filename = $_[0] or croak('Need filename');
my $srTextIn = $_[1] or croak('Need text');
$srTextIn = \$_[1] unless ref $srTextIn eq 'SCALAR';
my $lrPieces = pieces($srTextIn);
my $srTextOut = assemble($filename, $lrPieces);
return $srTextOut;
} #preparse()
1;
# vi: set ts=4 sts=4 sw=4 et ai fo-=ro foldmethod=marker: #
( run in 1.407 second using v1.01-cache-2.11-cpan-0b58ddf2af1 )