PAX
view release on metacpan or search on metacpan
lib/PAX/CodeUnitCompiler.pm view on Meta::CPAN
push @actions, {
command => $command,
action => $action,
};
}
my $rest = substr($tail, pos($tail) || 0);
return if !@actions;
my $unknown_action = _compile_dispatch_unknown_action($rest);
return {
bootstrap_source => $bootstrap_source,
command_default => _unescape_literal($default),
command_default_mode => $mode eq '||' ? 'or' : 'defined_or',
actions => \@actions,
unknown_action => $unknown_action,
};
}
sub _extract_braced_region {
my ($source, $start) = @_;
my $depth = 1;
my $i = $start;
while ($i < length($source)) {
my $char = substr($source, $i, 1);
$depth++ if $char eq '{';
$depth-- if $char eq '}';
return substr($source, $start, $i - $start) if $depth == 0;
$i++;
}
return;
}
sub _compile_dispatch_action {
my ($body) = @_;
if ($body =~ /\A\s*print\s+([A-Za-z_][A-Za-z0-9_:]*)::([A-Za-z_][A-Za-z0-9_]*)\(\)\s*,\s*"\\n"\s*;\s*exit\s+(\d+)\s*;\s*\z/s) {
return {
op => 'print_call',
target => $1 . '::' . $2,
args => [],
newline => 1,
exit_code => 0 + $3,
};
}
if ($body =~ /\A\s*print\s+([A-Za-z_][A-Za-z0-9_:]*)::([A-Za-z_][A-Za-z0-9_]*)\(\s*'([^'\\]*(?:\\.[^'\\]*)*)'\s*\)\s*,\s*"\\n"\s*;\s*exit\s+(\d+)\s*;\s*\z/s) {
return {
op => 'print_call',
target => $1 . '::' . $2,
args => [ _unescape_literal($3) ],
newline => 1,
exit_code => 0 + $4,
};
}
if ($body =~ /\A\s*require\s+([A-Za-z_][A-Za-z0-9_:]*)\s*;\s*print\s+\$([A-Za-z_][A-Za-z0-9_:]*)::([A-Za-z_][A-Za-z0-9_]*)\s*,\s*"\\n"\s*;\s*exit\s+(\d+)\s*;\s*\z/s) {
return {
op => 'print_required_global',
require_module => $1,
symbol => $2 . '::' . $3,
newline => 1,
exit_code => 0 + $4,
};
}
if ($body =~ /\APAX_EMBEDDED_ASSET_ROOT/ || $body =~ /\$ENV\{PAX_EMBEDDED_ASSET_ROOT\}/) {
return {
op => 'print_embedded_asset',
logical_path => 'banner.txt',
} if $body =~ /banner\.txt/;
}
return;
}
sub _compile_dispatch_unknown_action {
my ($body) = @_;
return if !defined $body || $body !~ /\S/;
if ($body =~ /\A\s*print\s+STDERR\s+"([^"\\]*(?:\\.[^"\\]*)*)\$cmd([^"\\]*(?:\\.[^"\\]*)*)"\s*;\s*exit\s+(\d+)\s*;\s*\z/s) {
return {
op => 'stderr_interpolate_cmd',
prefix => _unescape_literal($1),
suffix => _unescape_literal($2),
exit_code => 0 + $3,
};
}
return;
}
sub _unescape_literal {
my ($value) = @_;
$value //= '';
$value =~ s/\\"/"/g;
$value =~ s/\\'/'/g;
$value =~ s/\\\\/\\/g;
$value =~ s/\\n/\n/g;
$value =~ s/\\t/\t/g;
return $value;
}
sub _hybrid_compiled_unit {
my ($path, $kind, $logical_path, $package, $initializers, $subs, $unsupported_subs, $source) = @_;
my $bootstrap_source = _bootstrap_source($source);
my %residual_sub_sources;
for my $full (@$unsupported_subs) {
my ($short) = $full =~ /::([^:]+)\z/;
next if !$short;
my $sub_source = _extract_sub_source($source, $short) or next;
$residual_sub_sources{$full} = $sub_source;
}
my $residual_mode = 'per_sub';
if (_bootstrap_has_shared_lexicals($bootstrap_source)) {
%residual_sub_sources = ();
$residual_mode = 'module';
}
if (@$unsupported_subs != scalar(keys %residual_sub_sources)) {
%residual_sub_sources = ();
$residual_mode = 'module';
}
my $record = {
format => 'pcu_v1',
package => $package,
source_kind => $kind,
require_path => _require_path_for($path, $package),
initializers => $initializers,
subs => $subs,
unsupported_subs => $unsupported_subs,
( run in 0.684 second using v1.01-cache-2.11-cpan-71847e10f99 )