Skip to content

Commit 458ace9

Browse files
author
Chris White
committed
Export $self to :macro and :immediate code
Also, run macro/immediate code in the package of the script instead of in Text::PerlPP.
1 parent 198ab81 commit 458ace9

File tree

1 file changed

+63
-10
lines changed

1 file changed

+63
-10
lines changed

lib/Text/PerlPP.pm

Lines changed: 63 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ use constant OB_CONTENTS => 1;
5656
use constant OB_STARTLINE => 2;
5757

5858
# What $self is called inside a script package
59-
use constant PPP_SELF_INSIDE => '_PerlPP_Instance';
59+
use constant PPP_SELF_INSIDE => 'PSelf';
6060

6161
# Debugging info
6262
my @OBModeNames = qw(plain capture code echo command comment);
@@ -239,11 +239,58 @@ sub ExecuteCommand {
239239

240240
} elsif ( $cmd =~ /^macro\s++(.*+)$/si ) {
241241
$self->StartOB(); # plain text
242-
eval( $1 ); warn $@ if $@;
242+
243+
# Create the execution environment for the macro:
244+
# - Run in the script's package. Without `package`, the eval'ed
245+
# code runs in Text::PerlPP.
246+
# - Make $PSelf available with `our`. Each `eval` gets its own
247+
# set of lexical variables, so $PSelf would have to be referred
248+
# to with its full package name if we didn't have the `our`.
249+
# TODO add a pound line to this eval based on the current line number
250+
251+
my $code = qq{ ;
252+
package $self->{Package} {
253+
our \$@{[PPP_SELF_INSIDE]};
254+
$1
255+
};
256+
};
257+
258+
print "Macro code run:\n$code\n" =~ s/^/#/gmr
259+
if($self->{Opts}->{DEBUG});
260+
eval $code;
261+
my $err = $@; chomp $err;
243262
emit 'print ' . $self->PrepareString( $self->EndOB() ) . ";\n";
244263

264+
# Report the error, if any. Under -E, it's a warning.
265+
my $errmsg = "Error: $err\n in immediate " . substr($1, 0, 40) . '...';
266+
if($self->{Opts}->{DEBUG}) {
267+
warn $errmsg if $err;
268+
} else {
269+
die $errmsg if $err;
270+
}
271+
245272
} elsif ( $cmd =~ /^immediate\s++(.*+)$/si ) {
246-
eval( $1 ); warn $@ if $@;
273+
# TODO refactor common code between macro and immediate
274+
275+
# TODO add a pound line to this eval
276+
my $code = qq{ ;
277+
package $self->{Package} {
278+
our \$@{[PPP_SELF_INSIDE]};
279+
$1
280+
};
281+
};
282+
print "Immediate code run:\n$code\n" =~ s/^/#/gmr
283+
if($self->{Opts}->{DEBUG});
284+
eval( $code );
285+
my $err = $@; chomp $err;
286+
287+
# Report the error, if any. Under -E, it's a warning.
288+
my $errmsg = "Error: $err\n in immediate " . substr($1, 0, 40) . '...';
289+
if($self->{Opts}->{DEBUG}) {
290+
warn $errmsg if $err;
291+
} else {
292+
die $errmsg if $err;
293+
}
247294

248295
} elsif ( $cmd =~ /^prefix\s++(\S++)\s++(\S++)\s*+$/i ) {
249296
$self->{Prefixes}->{ $1 } = $2;
@@ -773,7 +820,16 @@ sub Main {
773820
$self->{Package} =~ s/^.*?([a-z_][a-z_0-9.]*).pl?$/$1/i;
774821
$self->{Package} =~ s/[^a-z0-9_]/_/gi;
775822
# $self->{Package} is not the whole name, so can start with a number.
776-
$self->{Package} .= $#Instances;
823+
$self->{Package} = "PPP_$self->{Package}$#Instances";
824+
825+
# Make $self accessible from inside the package.
826+
# This has to happen first so that :macro or :immediate blocks in the
827+
# script can access it while the input is being parsed.
828+
{
829+
no strict 'refs';
830+
${ "$self->{Package}::" . PPP_SELF_INSIDE }
831+
= $Text::PerlPP::Instances[$#Instances];
832+
}
777833

778834
$self->StartOB(); # Output from here on will be included in the generated script
779835

@@ -782,12 +838,9 @@ sub Main {
782838
$self->emit_pound_line( '<package header>', 1 );
783839

784840
# Open the package
785-
emit "package PPP_$self->{Package};\nuse 5.010001;\nuse strict;\nuse warnings;\n";
841+
emit "package $self->{Package};\nuse 5.010001;\nuse strict;\nuse warnings;\n";
786842
emit "use constant { true => !!1, false => !!0 };\n";
787-
788-
# Make $self accessible from inside the package.
789-
emit 'my $' . PPP_SELF_INSIDE .
790-
' = $Text::PerlPP::Instances[' . $#Instances . "];\n";
843+
emit 'our $' . PPP_SELF_INSIDE . ";\n"; # Lexical alias for $self
791844

792845
# Definitions
793846

@@ -873,7 +926,7 @@ sub Main {
873926

874927
} else {
875928
$self->StartOB(); # Start collecting the output of the Perl script
876-
my $result; # To save any errors from the eval
929+
my $result; # To save any errors from the eval
877930

878931
# TODO hide %Defs and others of our variables we don't want
879932
# $script to access.

0 commit comments

Comments
 (0)