App-PythonToPerl
view release on metacpan or search on metacpan
lib/Python/File.pm view on Meta::CPAN
elsif (((scalar @{$python_preparsed_target}) > 0) and
$python_preparsed_target->[-1]->isa('Python::Include') and
($python_preparsed_target->[-1]->{python_line_number_end} < 0)) {
print 'in python_file_to_python_preparsed(), inside multi-line include', "\n";
# accumulate current (possibly last) Python line of multi-line component
chomp $ARG;
$python_preparsed_target->[-1]->{python_source_code} .= "\n" . $ARG;
# update last active character
$python_last_active_character = $self->python_last_active_character_find($python_last_active_character, $ARG);
print 'in python_file_to_python_preparsed(), possibly updated last active character to \'', $python_last_active_character, '\'', "\n";
# multi-line includes with parentheses end differently than those without parentheses
if ($python_preparsed_target->[-1]->{python_has_parentheses}) {
# end multi-line include (w/ parentheses) when the last non-whitespace non-comment character is a close parentheses
if ($ARG =~ m/^.*\)\s*(?:\#.*)?$/) {
print 'in python_file_to_python_preparsed(), ending multi-line include w/ parentheses', "\n";
# set ending line number, indicating we are no longer inside this multi-line component
$python_preparsed_target->[-1]->{python_line_number_end} = $python_line_number;
next;
lib/Python/File.pm view on Meta::CPAN
elsif (((scalar @{$python_preparsed_target}) > 0) and
$python_preparsed_target->[-1]->isa('Python::Function') and
($python_preparsed_target->[-1]->{python_line_number_end_header} < 0)) {
print 'in python_file_to_python_preparsed(), inside multi-line function header', "\n";
# accumulate current (possibly last) Python line of multi-line component
chomp $ARG;
$python_preparsed_target->[-1]->{python_source_code} .= "\n" . $ARG;
# update last active character
$python_last_active_character = $self->python_last_active_character_find($python_last_active_character, $ARG);
print 'in python_file_to_python_preparsed(), possibly updated last active character to \'', $python_last_active_character, '\'', "\n";
# end multi-line function header when it matches the entire regex;
# DEV NOTE, CORRELATION PYFI100: all regex changes must be reflected in both locations,
# the only difference should be the optional trailing comment pattern \s*(?:\#.*\n)?\s*
# which is not in the header-opening regex and is used twice in the header-closing regex;
# DEV NOTE: do NOT join multiple lines into one line for regex match,
# need \n characters to detect trailing comments,
# \s matches \n so multiple lines do not need to be combined
# $1 $2 $3 ...
lib/Python/File.pm view on Meta::CPAN
elsif (((scalar @{$python_preparsed_target}) > 0) and
$python_preparsed_target->[-1]->isa('Python::Class') and
($python_preparsed_target->[-1]->{python_line_number_end_header} < 0)) {
print 'in python_file_to_python_preparsed(), inside multi-line class header', "\n";
# accumulate current (possibly last) Python line of multi-line component
chomp $ARG;
$python_preparsed_target->[-1]->{python_source_code} .= "\n" . $ARG;
# update last active character
$python_last_active_character = $self->python_last_active_character_find($python_last_active_character, $ARG);
print 'in python_file_to_python_preparsed(), possibly updated last active character to \'', $python_last_active_character, '\'', "\n";
# end multi-line class header when it matches the entire regex;
# DEV NOTE, CORRELATION PYFI101: all regex changes must be reflected in both locations,
# the only difference should be the optional trailing comment pattern \s*(?:\#.*\n)?\s*
# which is not in the header-opening regex and is used twice in the header-closing regex;
# DEV NOTE: do NOT join multiple lines into one line for regex match,
# need \n characters to detect trailing comments,
# \s matches \n so multiple lines do not need to be combined
if (# Python
lib/Python/File.pm view on Meta::CPAN
# DEV NOTE: if last active character is left parentheses or comma,
# then context is not void and this is not a comment
elsif (($ARG =~ m/^(\s*)\'\'\'(.*)\'\'\'\s*$/) and
($python_last_active_character ne '(') and
($python_last_active_character ne ',')) {
print 'in python_file_to_python_preparsed(), have single-line \'\'\'comment\'\'\'', "\n";
chomp $ARG; # trim trailing newline, if present
# update last active character
$python_last_active_character = $self->python_last_active_character_find($python_last_active_character, $ARG);
print 'in python_file_to_python_preparsed(), possibly updated last active character to \'', $python_last_active_character, '\'', "\n";
# check if previous component was same type
if (((scalar @{$python_preparsed_target}) > 0) and
$python_preparsed_target->[-1]->isa('Python::CommentSingleQuotes')) {
print 'in python_file_to_python_preparsed(), have single-line \'\'\'comment\'\'\', accumulating', "\n";
# accumulate multiple single-line components into a multi-line component
$python_preparsed_target->[-1]->{python_line_number_end} = $python_line_number; # update ending line number
$python_preparsed_target->[-1]->{python_source_code} .= "\n" . $ARG;
$python_preparsed_target->[-1]->{perl_source_code} .= "\n" . ($1 . '# ' . $2); # reformat comments & retain spacing
}
lib/Python/File.pm view on Meta::CPAN
# DEV NOTE: if last active character is left parentheses or comma,
# then context is not void and this is not a comment
elsif (($ARG =~ m/^(\s*)\"\"\"(.*)\"\"\"\s*$/) and
($python_last_active_character ne '(') and
($python_last_active_character ne ',')) {
print 'in python_file_to_python_preparsed(), have single-line \"\"\"comment\"\"\"', "\n";
chomp $ARG; # trim trailing newline, if present
# update last active character
$python_last_active_character = $self->python_last_active_character_find($python_last_active_character, $ARG);
print 'in python_file_to_python_preparsed(), possibly updated last active character to \'', $python_last_active_character, '\'', "\n";
# check if previous component was same type
if (((scalar @{$python_preparsed_target}) > 0) and
$python_preparsed_target->[-1]->isa('Python::CommentDoubleQuotes')) {
print 'in python_file_to_python_preparsed(), have single-line \"\"\"comment\"\"\", accumulating', "\n";
# accumulate multiple single-line components into a multi-line component
$python_preparsed_target->[-1]->{python_line_number_end} = $python_line_number; # update ending line number
$python_preparsed_target->[-1]->{python_source_code} .= "\n" . $ARG;
$python_preparsed_target->[-1]->{perl_source_code} .= "\n" . ($1 . '# ' . $2); # reformat comments & retain spacing
}
lib/Python/File.pm view on Meta::CPAN
# https://python-reference.readthedocs.io/en/latest/docs/operators/slash.html
# NEED ANSWER: can the line continuation backslash appear without any preceding whitespace?
elsif (($ARG =~ m/^\s*from\s+.*(\()[^\)]*$/) or
($ARG =~ m/^\s*from\s+.*\\$/) or
($ARG =~ m/^\s*c?import\s+.*\\$/)) {
print 'in python_file_to_python_preparsed(), have multi-line include, starting', "\n";
chomp $ARG; # trim trailing newline, if present
# update last active character
$python_last_active_character = $self->python_last_active_character_find($python_last_active_character, $ARG);
print 'in python_file_to_python_preparsed(), possibly updated last active character to \'', $python_last_active_character, '\'', "\n";
push @{$python_preparsed_target},
Python::Include->new(
{
component_type => 'Python::Include',
python_file_path => $self->{python_file_path},
python_line_number_begin => $python_line_number,
python_line_number_end => -1, # negative value means we are currently inside multi-line component
python_source_code => $ARG,
python_has_parentheses => (defined $1) ? 1 : 0,
lib/Python/File.pm view on Meta::CPAN
next;
}
# pre-parse single-line include statements;
# 'import', or 'cimport' for Pyrex, must be followed by open parentheses or whitespace
elsif ($ARG =~ m/^\s*(from\s+.+\s+)?c?import[\(\s].+$/) {
print 'in python_file_to_python_preparsed(), have single-line include', "\n";
chomp $ARG; # trim trailing newline, if present
# update last active character
$python_last_active_character = $self->python_last_active_character_find($python_last_active_character, $ARG);
print 'in python_file_to_python_preparsed(), possibly updated last active character to \'', $python_last_active_character, '\'', "\n";
push @{$python_preparsed_target},
Python::Include->new(
{
component_type => 'Python::Include',
python_file_path => $self->{python_file_path},
python_line_number_begin => $python_line_number,
python_line_number_end => $python_line_number,
python_source_code => $ARG,
perl_source_code => undef, # includes are not translated during pre-parse phase
lib/Python/File.pm view on Meta::CPAN
#die 'TMP DEBUG, FUNCTION HEADER';
# NEED UPGRADE: utilize optional trailing comment $6, include in generated Perl source code if present
# NEED UPGRADE: utilize optional trailing comment $6, include in generated Perl source code if present
# NEED UPGRADE: utilize optional trailing comment $6, include in generated Perl source code if present
chomp $ARG; # trim trailing newline, if present
# update last active character
$python_last_active_character = $self->python_last_active_character_find($python_last_active_character, $ARG);
print 'in python_file_to_python_preparsed(), possibly updated last active character to \'', $python_last_active_character, '\'', "\n";
# if multi-line function header, we must receive the function name as part of the first line,
# in order to pre-parse correctly below
$python_namespace_name = $2;
$python_component =
{
component_type => undef, # set below, either Python::Function or Python::Method or Python::InnerFunction
decorators => '', # empty value means no declared decorators; possibly set below
indentation => $1, # empty match returns empty string '', not undef
lib/Python/File.pm view on Meta::CPAN
# NEED UPGRADE: utilize optional trailing comment $5, include in generated Perl source code if present
# NEED UPGRADE: utilize optional trailing comment $5, include in generated Perl source code if present
# NEED UPGRADE: utilize optional trailing comment $5, include in generated Perl source code if present
print 'in python_file_to_python_preparsed(), have class, starting header', "\n";
chomp $ARG; # trim trailing newline, if present
# update last active character
$python_last_active_character = $self->python_last_active_character_find($python_last_active_character, $ARG);
print 'in python_file_to_python_preparsed(), possibly updated last active character to \'', $python_last_active_character, '\'', "\n";
# if multi-line class header, we must receive the class name as part of the first line,
# in order to pre-parse correctly below
$python_namespace_name = $2;
$python_component =
{
component_type => undef, # set below, either Python::Class or Python::LocalClass or Python::InnerClass
indentation => $1, # empty match returns empty string '', not undef
symbol => $python_namespace_name,
lib/Python/File.pm view on Meta::CPAN
# being inside this new class increases the namespace stack (deepens the current scope)
push @{$python_namespaces}, $python_preparsed_target->[-1];
next;
}
else {
print 'in python_file_to_python_preparsed(), have UNKNOWN line of code', "\n";
chomp $ARG; # trim trailing newline, if present
# update last active character
$python_last_active_character = $self->python_last_active_character_find($python_last_active_character, $ARG);
print 'in python_file_to_python_preparsed(), possibly updated last active character to \'', $python_last_active_character, '\'', "\n";
# ensure we correctly parse all namespaces (functions & classes)
if ($ARG =~ m/^(\s*)def\s+/) {
croak 'ERROR EPYFI006a: Python function with UNKNOWN format, croaking';
}
elsif ($ARG =~ m/^(\s*)class\s+/) {
croak 'ERROR EPYFI006b: Python class with UNKNOWN format, croaking';
}
# DEV NOTE, CORRELATION PYFI102: all Unknown logic in this if-elsif-else block must be copied
lib/Python/Function.pm view on Meta::CPAN
# de-parse & translate function body
foreach my Python::Component $python_preparsed_component (@{$self->{python_preparsed}}) {
print 'in Python::Function->python_preparsed_to_perl_source(), function \'', $self->{symbol_scoped}, '\', de-parsing & translating function body, about to call python_preparsed_to_perl_source() on $python_preparsed_component = ', Dumper($python_prepa...
push @{$perl_source_code_split}, $python_preparsed_component->python_preparsed_to_perl_source($openai);
print 'in Python::Function->python_preparsed_to_perl_source(), function \'', $self->{symbol_scoped}, '\', de-parsing & translating function body, ret from call to python_preparsed_to_perl_source(), received $perl_source_code_split->[-1] = \'', $perl_...
if ((not $python_preparsed_component->isa('Python::Comment')) and
(not $python_preparsed_component->isa('Python::Whitespace')) and
(not $python_preparsed_component->isa('Python::Blank'))) {
$final_active_component_index = (scalar @{$perl_source_code_split}) - 1;
print 'in Python::Function->python_preparsed_to_perl_source(), function \'', $self->{symbol_scoped}, '\', de-parsing & translating function body, updated $final_active_component_index = ', $final_active_component_index, "\n";
}
print 'in Python::Function->python_preparsed_to_perl_source(), function \'', $self->{symbol_scoped}, '\', de-parsing & translating function body, ret from call python_preparsed_to_perl_source()', "\n";
}
# close function body with curly brace, placed after the final active component in the function body,
# or directly after the function header if no active components in body
my string $function_end = ' } # END sub ' . $self->{symbol} . '()';
if ($final_active_component_index > -1) {
# end function after final active component in function body,
( run in 0.238 second using v1.01-cache-2.11-cpan-05444aca049 )