| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
# |
|
2
|
|
|
|
|
|
|
# This file is part of App-PythonToPerl |
|
3
|
|
|
|
|
|
|
# |
|
4
|
|
|
|
|
|
|
# This software is Copyright (c) 2023 by Auto-Parallel Technologies, Inc. |
|
5
|
|
|
|
|
|
|
# |
|
6
|
|
|
|
|
|
|
# This is free software, licensed under: |
|
7
|
|
|
|
|
|
|
# |
|
8
|
|
|
|
|
|
|
# The GNU General Public License, Version 3, June 2007 |
|
9
|
|
|
|
|
|
|
# |
|
10
|
|
|
|
|
|
|
# [[[ HEADER ]]] |
|
11
|
|
|
|
|
|
|
# ABSTRACT: an include statement |
|
12
|
|
|
|
|
|
|
#use RPerl; |
|
13
|
|
|
|
|
|
|
package Python::Include; |
|
14
|
1
|
|
|
1
|
|
6
|
use strict; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
30
|
|
|
15
|
1
|
|
|
1
|
|
5
|
use warnings; |
|
|
1
|
|
|
|
|
12
|
|
|
|
1
|
|
|
|
|
43
|
|
|
16
|
|
|
|
|
|
|
our $VERSION = 0.008_000; |
|
17
|
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
# [[[ OO INHERITANCE ]]] |
|
19
|
1
|
|
|
1
|
|
5
|
use parent qw(Python::Component); |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
18
|
|
|
20
|
1
|
|
|
1
|
|
58
|
use Python::Component; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
45
|
|
|
21
|
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
# [[[ DATA TYPES ]]] |
|
23
|
|
|
|
|
|
|
package Python::Include::hashref::hashref; 1; |
|
24
|
|
|
|
|
|
|
package Python::Include; |
|
25
|
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
# [[[ CRITICS ]]] |
|
27
|
|
|
|
|
|
|
## no critic qw(ProhibitUselessNoCritic ProhibitMagicNumbers RequireCheckedSyscalls) # USER DEFAULT 1: allow numeric values & print op |
|
28
|
|
|
|
|
|
|
## no critic qw(RequireInterpolationOfMetachars) # USER DEFAULT 2: allow single-quoted control characters & sigils |
|
29
|
|
|
|
|
|
|
## no critic qw(ProhibitConstantPragma ProhibitMagicNumbers) # USER DEFAULT 3: allow constants |
|
30
|
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
# [[[ INCLUDES ]]] |
|
32
|
1
|
|
|
1
|
|
6
|
use Perl::Types; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
351
|
|
|
33
|
|
|
|
|
|
|
#use re 'debugcolor'; # output regex debugging info |
|
34
|
1
|
|
|
1
|
|
7
|
use Champ; |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
37
|
|
|
35
|
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
# DEV NOTE: not actually used in this class, but needed so python_preparsed_to_perl_source() |
|
37
|
|
|
|
|
|
|
# can accept the same args as all Python::Component classes |
|
38
|
1
|
|
|
1
|
|
5
|
use OpenAI::API; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
1850
|
|
|
39
|
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
# [[[ OO PROPERTIES ]]] |
|
41
|
|
|
|
|
|
|
our hashref $properties = { |
|
42
|
|
|
|
|
|
|
component_type => my string $TYPED_component_type = 'Python::Function', |
|
43
|
|
|
|
|
|
|
python_file_path => my string $TYPED_python_file_path = undef, |
|
44
|
|
|
|
|
|
|
python_line_number_begin => my integer $TYPED_python_line_number_begin = undef, |
|
45
|
|
|
|
|
|
|
python_line_number_end => my integer $TYPED_python_line_number_end = undef, |
|
46
|
|
|
|
|
|
|
python_source_code => my string $TYPED_python_source_code = undef, |
|
47
|
|
|
|
|
|
|
python_modules => my string::arrayref $TYPED_python_modules = undef, |
|
48
|
|
|
|
|
|
|
python_subcomponents => my string::arrayref $TYPED_python_subcomponents = undef, |
|
49
|
|
|
|
|
|
|
python_alias => my string $TYPED_python_alias = undef, |
|
50
|
|
|
|
|
|
|
python_has_parentheses => my boolean $TYPED_python_has_parentheses = undef, |
|
51
|
|
|
|
|
|
|
perl_source_code => my string $TYPED_perl_source_code = undef, |
|
52
|
|
|
|
|
|
|
}; |
|
53
|
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
# [[[ SUBROUTINES ]]] |
|
55
|
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
# PYIN01x |
|
57
|
|
|
|
|
|
|
sub python_preparsed_to_perl_source { |
|
58
|
|
|
|
|
|
|
# translate a chunk of Python source code into Perl source code |
|
59
|
0
|
|
|
0
|
0
|
|
{ my string $RETURN_TYPE }; |
|
|
0
|
|
|
|
|
|
|
|
60
|
0
|
|
|
|
|
|
( my Python::Include $self, my OpenAI::API $openai ) = @ARG; |
|
61
|
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
# DEV NOTE: this subroutine should handle most of the common types of includes in Python, as described in unofficial Python websites |
|
63
|
|
|
|
|
|
|
# https://note.nkmk.me/en/python-import-usage |
|
64
|
|
|
|
|
|
|
# https://realpython.com/python-import/ |
|
65
|
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
# NEED UPGRADE: correctly handle all advanced functionality and edge cases, as specified in the official Python documentation |
|
67
|
|
|
|
|
|
|
# https://docs.python.org/3/reference/import.html |
|
68
|
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
# error if no OpenAI API |
|
70
|
0
|
0
|
|
|
|
|
if (not defined $openai) { |
|
71
|
0
|
|
|
|
|
|
croak 'ERROR EPYIN010: undefined OpenAI API, croaking'; |
|
72
|
|
|
|
|
|
|
} |
|
73
|
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
# error or warning if no Python source code |
|
75
|
0
|
0
|
0
|
|
|
|
if ((not exists $self->{python_source_code}) or |
|
|
|
|
0
|
|
|
|
|
|
76
|
|
|
|
|
|
|
(not defined $self->{python_source_code}) or |
|
77
|
|
|
|
|
|
|
($self->{python_source_code} eq q{})) { |
|
78
|
0
|
|
|
|
|
|
croak 'ERROR EPYIN011: non-existent or undefined or empty Python source code, croaking'; |
|
79
|
|
|
|
|
|
|
} |
|
80
|
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
# DEV NOTE, PYIN012: $self->{python_preparsed} not used in this class, no need to error check |
|
82
|
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
# initialize object properties |
|
84
|
0
|
|
|
|
|
|
$self->{python_modules} = [undef]; |
|
85
|
0
|
|
|
|
|
|
$self->{python_subcomponents} = [undef]; |
|
86
|
0
|
|
|
|
|
|
$self->{python_alias} = undef; |
|
87
|
|
|
|
|
|
|
|
|
88
|
0
|
|
|
|
|
|
print 'in Python::Include::python_preparsed_to_perl_source(), have champ($self->{python_source_code}) = \'', champ($self->{python_source_code}), '\'', "\n"; |
|
89
|
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
# remove all backslashes, which can only appear at the end of a line and which only signify line continuation; |
|
91
|
|
|
|
|
|
|
# since \s matches \n, removal of backslashes allows all the following regexes to automatically work for multi-line includes |
|
92
|
0
|
|
|
|
|
|
my string $python_source_code_clean = $self->{python_source_code}; |
|
93
|
0
|
|
|
|
|
|
$python_source_code_clean =~ s/\\//gxms; |
|
94
|
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
# also remove all trailing comments, because only comments on the last line are correctly matched by the regexes below |
|
96
|
0
|
|
|
|
|
|
$python_source_code_clean =~ s/\#[^\n]*\n/\n/gxms; |
|
97
|
|
|
|
|
|
|
|
|
98
|
0
|
|
|
|
|
|
print 'in Python::Include::python_preparsed_to_perl_source(), have champ($python_source_code_clean) = \'', champ($python_source_code_clean), '\'', "\n"; |
|
99
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
# DEV NOTE, CORRELATION PYIN000: any changes to test includes below must also be made in t/00_includes.py |
|
101
|
|
|
|
|
|
|
# DEV NOTE: comments do not need to be preceded by whitespace |
|
102
|
|
|
|
|
|
|
# import FOO |
|
103
|
|
|
|
|
|
|
# import F.OO |
|
104
|
|
|
|
|
|
|
# import F.OO# test comment |
|
105
|
|
|
|
|
|
|
# import F.OO # test comment |
|
106
|
|
|
|
|
|
|
# import \ |
|
107
|
|
|
|
|
|
|
# FOO |
|
108
|
0
|
0
|
|
|
|
|
if ($python_source_code_clean =~ m/^\s*import\s+([\w\.]+)\s*(\#.*)?$/) { |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
109
|
0
|
|
|
|
|
|
print 'in Python::Include::python_preparsed_to_perl_source(), matched regex #0, have $1 = \'', $1, '\'', "\n"; |
|
110
|
0
|
|
|
|
|
|
$self->{python_modules} = [$1]; |
|
111
|
0
|
|
|
|
|
|
$self->{perl_source_code} = 'use ' . $1 . ';'; |
|
112
|
|
|
|
|
|
|
} |
|
113
|
|
|
|
|
|
|
# DEV NOTE: commas may be either preceded or followed by optional whitespace |
|
114
|
|
|
|
|
|
|
# import FOO, BAR, BAT, BAX |
|
115
|
|
|
|
|
|
|
# import F.OO , B.AR, BA.T, B.A.X |
|
116
|
|
|
|
|
|
|
# import F.OO,B.AR,BA.T,B.A.X# test comment |
|
117
|
|
|
|
|
|
|
# import F.OO, B.AR, BA.T, B.A.X # test comment |
|
118
|
|
|
|
|
|
|
# import \ |
|
119
|
|
|
|
|
|
|
# FOO, B.AR, \ |
|
120
|
|
|
|
|
|
|
# BA.T, B.A.X # test comment |
|
121
|
|
|
|
|
|
|
elsif ($python_source_code_clean =~ m/^\s*import\s+((?:[\w\.]+\s*\,\s*)+[\w\.]+)\s*(\#.*)?$/) { |
|
122
|
0
|
|
|
|
|
|
print 'in Python::Include::python_preparsed_to_perl_source(), matched regex #1, have $1 = \'', $1, '\'', "\n"; |
|
123
|
0
|
|
|
|
|
|
$self->{python_modules} = [split /\,\s+/, $1]; |
|
124
|
0
|
|
|
|
|
|
foreach my string $python_module (@{$self->{python_modules}}) { |
|
|
0
|
|
|
|
|
|
|
|
125
|
0
|
|
|
|
|
|
$self->{perl_source_code} .= 'use ' . $python_module . '; '; |
|
126
|
|
|
|
|
|
|
} |
|
127
|
0
|
|
|
|
|
|
substr $self->{perl_source_code}, -2, 2, ''; # strip trailing ' ' created by for() loop above |
|
128
|
|
|
|
|
|
|
} |
|
129
|
|
|
|
|
|
|
# from FOO import BAR |
|
130
|
|
|
|
|
|
|
# from F.OO import B.AR |
|
131
|
|
|
|
|
|
|
# from F.OO import B.AR# test comment |
|
132
|
|
|
|
|
|
|
# from F.OO import B.AR # test comment |
|
133
|
|
|
|
|
|
|
# from \ |
|
134
|
|
|
|
|
|
|
# F.OO \ |
|
135
|
|
|
|
|
|
|
# import \ |
|
136
|
|
|
|
|
|
|
# B.AR # test comment |
|
137
|
|
|
|
|
|
|
# from . import BAR |
|
138
|
|
|
|
|
|
|
# from . import B.AR |
|
139
|
|
|
|
|
|
|
# from . import B.AR# test comment |
|
140
|
|
|
|
|
|
|
# from . import B.AR # test comment |
|
141
|
|
|
|
|
|
|
# from \ |
|
142
|
|
|
|
|
|
|
# . \ |
|
143
|
|
|
|
|
|
|
# import \ |
|
144
|
|
|
|
|
|
|
# B.AR # test comment |
|
145
|
|
|
|
|
|
|
elsif ($python_source_code_clean =~ m/^\s*from\s+([\w\.]+)\s+import\s+([\w\.]+)\s*(\#.*)?$/) { |
|
146
|
0
|
|
|
|
|
|
print 'in Python::Include::python_preparsed_to_perl_source(), matched regex #2, have $1 = \'', $1, '\', $2 = \'', $2, '\'', "\n"; |
|
147
|
0
|
|
|
|
|
|
$self->{python_modules} = [$1]; |
|
148
|
0
|
|
|
|
|
|
$self->{python_subcomponents} = [$2]; |
|
149
|
0
|
|
|
|
|
|
$self->{perl_source_code} = 'use ' . $1 . ' qw(' . $2 . ');'; |
|
150
|
|
|
|
|
|
|
} |
|
151
|
|
|
|
|
|
|
# DEV NOTE: commas may be either preceded or followed by optional whitespace |
|
152
|
|
|
|
|
|
|
# from FOO import BAR, BAT, BAX |
|
153
|
|
|
|
|
|
|
# from F.OO import B.AR , BA.T, B.A.X |
|
154
|
|
|
|
|
|
|
# from F.OO import B.AR,BA.T,B.A.X# test comment |
|
155
|
|
|
|
|
|
|
# from F.OO import B.AR, BA.T, B.A.X # test comment |
|
156
|
|
|
|
|
|
|
# from \ |
|
157
|
|
|
|
|
|
|
# F.OO \ |
|
158
|
|
|
|
|
|
|
# import B.AR, \ |
|
159
|
|
|
|
|
|
|
# BA.T, B.A.X # test comment |
|
160
|
|
|
|
|
|
|
# from FOO import \ |
|
161
|
|
|
|
|
|
|
# BAR, \ |
|
162
|
|
|
|
|
|
|
# BAT, \ |
|
163
|
|
|
|
|
|
|
# BAX |
|
164
|
|
|
|
|
|
|
# from FOO import FU, FEW, \ |
|
165
|
|
|
|
|
|
|
# BAR, BHAR \ |
|
166
|
|
|
|
|
|
|
# ,BAT, \ |
|
167
|
|
|
|
|
|
|
# BAX, BHAX |
|
168
|
|
|
|
|
|
|
# from F.OO import F.U, F.E.W, \ |
|
169
|
|
|
|
|
|
|
# B.AR, BH.AR, \ |
|
170
|
|
|
|
|
|
|
# BA.T, \ |
|
171
|
|
|
|
|
|
|
# B.A.X, B.H.A.X # test comment |
|
172
|
|
|
|
|
|
|
elsif ($python_source_code_clean =~ m/^\s*from\s+([\w\.]+)\s+import\s+((?:[\w\.]+\s*\,\s*)+[\w\.]+)\s*(\#.*)?$/) { |
|
173
|
0
|
|
|
|
|
|
print 'in Python::Include::python_preparsed_to_perl_source(), matched regex #3, have $1 = \'', $1, '\', $2 = \'', $2, '\'', "\n"; |
|
174
|
0
|
|
|
|
|
|
$self->{python_modules} = [$1]; |
|
175
|
0
|
|
|
|
|
|
$self->{python_subcomponents} = [split /\,\s+/, $2]; |
|
176
|
0
|
|
|
|
|
|
$self->{perl_source_code} = 'use ' . $1 . ' qw(' . join(' ', @{$self->{python_subcomponents}}) . ');'; |
|
|
0
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
} |
|
178
|
|
|
|
|
|
|
# DEV NOTE: parentheses do not need to be surrounded by whitespace |
|
179
|
|
|
|
|
|
|
# DEV NOTE: commas may be either preceded or followed by optional whitespace |
|
180
|
|
|
|
|
|
|
# DEV NOTE: extra commas are allowed at the end of parentheses-enclosed lists |
|
181
|
|
|
|
|
|
|
# from FOO import ( BAR, BAT, BAX ) |
|
182
|
|
|
|
|
|
|
# from FOO import ( B.AR , BA.T, B.A.X, ) |
|
183
|
|
|
|
|
|
|
# from FOO import(B.AR,BA.T,B.A.X)#test comment |
|
184
|
|
|
|
|
|
|
# from FOO import ( B.AR, BA.T, B.A.X ) # test comment |
|
185
|
|
|
|
|
|
|
# NEED ANSWER: how to handle comments in multi-line includes? |
|
186
|
|
|
|
|
|
|
# from FOO import ( |
|
187
|
|
|
|
|
|
|
# BAR, |
|
188
|
|
|
|
|
|
|
# BAT, |
|
189
|
|
|
|
|
|
|
# BAX |
|
190
|
|
|
|
|
|
|
# ) |
|
191
|
|
|
|
|
|
|
# from FOO import ( FU, FEW, |
|
192
|
|
|
|
|
|
|
# BAR, BHAR, |
|
193
|
|
|
|
|
|
|
# BAT, |
|
194
|
|
|
|
|
|
|
# BAX, BHAX, |
|
195
|
|
|
|
|
|
|
# ) |
|
196
|
|
|
|
|
|
|
# from F.OO import ( F.U, F.E.W, |
|
197
|
|
|
|
|
|
|
# B.AR, BH.AR, |
|
198
|
|
|
|
|
|
|
# BA.T, |
|
199
|
|
|
|
|
|
|
# B.A.X, B.H.A.X |
|
200
|
|
|
|
|
|
|
# ) |
|
201
|
|
|
|
|
|
|
# from FOO import ( \ |
|
202
|
|
|
|
|
|
|
# BAR, \ |
|
203
|
|
|
|
|
|
|
# BAT,# test comment |
|
204
|
|
|
|
|
|
|
# BAX \ |
|
205
|
|
|
|
|
|
|
# )# test comment |
|
206
|
|
|
|
|
|
|
# from FOO import ( FU, FEW, \ |
|
207
|
|
|
|
|
|
|
# BAR, BHAR, \ |
|
208
|
|
|
|
|
|
|
# BAT, |
|
209
|
|
|
|
|
|
|
# BAX, BHAX \ |
|
210
|
|
|
|
|
|
|
# ) |
|
211
|
|
|
|
|
|
|
# from \ |
|
212
|
|
|
|
|
|
|
# F.OO \ |
|
213
|
|
|
|
|
|
|
# import \ |
|
214
|
|
|
|
|
|
|
# ( \ |
|
215
|
|
|
|
|
|
|
# F.U, F.E.W, \ |
|
216
|
|
|
|
|
|
|
# B.AR, BH.AR, \ |
|
217
|
|
|
|
|
|
|
# BA.T, \ |
|
218
|
|
|
|
|
|
|
# B.A.X, B.H.A.X \ |
|
219
|
|
|
|
|
|
|
# ) |
|
220
|
|
|
|
|
|
|
elsif ($python_source_code_clean =~ m/^\s*from\s+([\w\.]+)\s+import\s*\(\s*((?:[\w\.]+\s*\,\s*)+[\w\.]+\s*\,?)\s*\)\s*(\#.*)?$/) { |
|
221
|
0
|
|
|
|
|
|
print 'in Python::Include::python_preparsed_to_perl_source(), matched regex #4, have $1 = \'', $1, '\', $2 = \'', $2, '\'', "\n"; |
|
222
|
0
|
|
|
|
|
|
$self->{python_modules} = [$1]; |
|
223
|
0
|
|
|
|
|
|
$self->{python_subcomponents} = [split /\,\s+/, $2]; |
|
224
|
0
|
|
|
|
|
|
$self->{perl_source_code} = 'use ' . $1 . ' qw(' . join(' ', @{$self->{python_subcomponents}}) . ');'; |
|
|
0
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
} |
|
226
|
|
|
|
|
|
|
# import FOO as F |
|
227
|
|
|
|
|
|
|
# import F.OO as F |
|
228
|
|
|
|
|
|
|
# import F.OO as F# test comment |
|
229
|
|
|
|
|
|
|
# import F.OO as F # test comment |
|
230
|
|
|
|
|
|
|
# import \ |
|
231
|
|
|
|
|
|
|
# F.OO \ |
|
232
|
|
|
|
|
|
|
# as \ |
|
233
|
|
|
|
|
|
|
# F # test comment |
|
234
|
|
|
|
|
|
|
elsif ($python_source_code_clean =~ m/^\s*import\s+([\w\.]+)\s+as\s+([\w\.]+)\s*(\#.*)?$/) { |
|
235
|
0
|
|
|
|
|
|
print 'in Python::Include::python_preparsed_to_perl_source(), matched regex #5, have $1 = \'', $1, '\', $2 = \'', $2, '\'', "\n"; |
|
236
|
0
|
|
|
|
|
|
$self->{python_modules} = [$1]; |
|
237
|
0
|
|
|
|
|
|
$self->{python_alias} = $2; |
|
238
|
|
|
|
|
|
|
# NEED ANSWER: does this work??? |
|
239
|
|
|
|
|
|
|
# NEED ANSWER: do we need the 'use FOO qw(:ALL);' below? |
|
240
|
|
|
|
|
|
|
# NEED ANSWER: do we need to use Exporter below??? |
|
241
|
|
|
|
|
|
|
# alias a Perl package/class as another pre-existing package/class |
|
242
|
|
|
|
|
|
|
# by creating a new empty package that just inherits from the other one |
|
243
|
|
|
|
|
|
|
# eval(q{package F; use parent qw(FOO); use FOO qw(:ALL); 1;}); use F; |
|
244
|
0
|
|
|
|
|
|
$self->{perl_source_code} = 'eval(q{package ' . $2 . '; use parent qw(' . $1 . '); use ' . $1 . ' qw(:ALL); 1;}); use ' . $2 . ';'; |
|
245
|
|
|
|
|
|
|
} |
|
246
|
|
|
|
|
|
|
# from FOO import BAR as B |
|
247
|
|
|
|
|
|
|
# from F.OO import B.AR as B |
|
248
|
|
|
|
|
|
|
# from F.OO import B.AR as B# test comment |
|
249
|
|
|
|
|
|
|
# from F.OO import B.AR as B # test comment |
|
250
|
|
|
|
|
|
|
# from \ |
|
251
|
|
|
|
|
|
|
# F.OO \ |
|
252
|
|
|
|
|
|
|
# import \ |
|
253
|
|
|
|
|
|
|
# B.AR \ |
|
254
|
|
|
|
|
|
|
# as \ |
|
255
|
|
|
|
|
|
|
# B # test comment |
|
256
|
|
|
|
|
|
|
elsif ($python_source_code_clean =~ m/^\s*from\s+([\w\.]+)\s+import\s+([\w\.]+)\s+as\s+([\w\.]+)\s*(\#.*)?$/) { |
|
257
|
0
|
|
|
|
|
|
print 'in Python::Include::python_preparsed_to_perl_source(), matched regex #6, have $1 = \'', $1, '\', $2 = \'', $2, '\', $3 = \'', $3, '\'', "\n"; |
|
258
|
0
|
|
|
|
|
|
$self->{python_modules} = [$1]; |
|
259
|
0
|
|
|
|
|
|
$self->{python_subcomponents} = [$2]; |
|
260
|
0
|
|
|
|
|
|
$self->{python_alias} = $3; |
|
261
|
|
|
|
|
|
|
# NEED ANSWER: does this work??? |
|
262
|
|
|
|
|
|
|
# alias a Perl function/variable/etc as another pre-existing function/variable/etc |
|
263
|
|
|
|
|
|
|
# by creating a new typeglob and setting it to the other one |
|
264
|
|
|
|
|
|
|
# use FOO; *B = *FOO::BAR; |
|
265
|
0
|
|
|
|
|
|
$self->{perl_source_code} = 'use ' . $1 . '; *' . $3 . ' = *' . $1 . '::' . $2 . ';'; |
|
266
|
|
|
|
|
|
|
} |
|
267
|
|
|
|
|
|
|
else { |
|
268
|
0
|
|
|
|
|
|
croak 'ERROR EPYIN013: cannot parse unrecognized include line \'', $self->{python_source_code}, '\', croaking'; |
|
269
|
|
|
|
|
|
|
} |
|
270
|
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
# NEED ANSWER: is the following statement correct? |
|
272
|
|
|
|
|
|
|
# Python syntax does not allow an import statement with both multiple modules and multiple subcomponents simultaneously |
|
273
|
0
|
0
|
0
|
|
|
|
if (((scalar @{$self->{python_modules}}) > 1) and |
|
|
0
|
|
|
|
|
|
|
|
274
|
0
|
|
|
|
|
|
((scalar @{$self->{python_subcomponents}}) > 1)) { |
|
275
|
0
|
|
|
|
|
|
croak 'ERROR EPYIN014: multiple modules and multiple subcomponents should never be parsed in a single include statement, croaking'; |
|
276
|
|
|
|
|
|
|
} |
|
277
|
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
# for multi-line includes, append newline character(s) to generated Perl source code, |
|
279
|
|
|
|
|
|
|
# in order to match original Python line spacing |
|
280
|
0
|
|
|
|
|
|
my string::arrayref $perl_source_code_lines = [split(/\n/, $self->{perl_source_code})]; |
|
281
|
0
|
|
|
|
|
|
my integer $line_count_perl = scalar @{$perl_source_code_lines}; |
|
|
0
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
# add 1 because beginning & ending on the same line counts as 1 line |
|
283
|
0
|
|
|
|
|
|
my integer $line_count_python = ($self->{python_line_number_end} - $self->{python_line_number_begin}) + 1; |
|
284
|
0
|
|
|
|
|
|
my integer $line_count_difference = $line_count_python - $line_count_perl; |
|
285
|
0
|
|
|
|
|
|
print 'in Python::Include::python_preparsed_to_perl_source(), have newline-appended $line_count_difference = ', $line_count_difference, "\n"; |
|
286
|
0
|
0
|
|
|
|
|
if ($line_count_difference > 0) { |
|
287
|
0
|
|
|
|
|
|
for (my integer $i = 0; $i < $line_count_difference; $i++) { |
|
288
|
0
|
|
|
|
|
|
push @{$perl_source_code_lines}, ''; |
|
|
0
|
|
|
|
|
|
|
|
289
|
0
|
|
|
|
|
|
print 'in Python::Include::python_preparsed_to_perl_source(), appending newline to match Python multi-line include', "\n"; |
|
290
|
|
|
|
|
|
|
} |
|
291
|
0
|
|
|
|
|
|
$self->{perl_source_code} = join "\n", @{$perl_source_code_lines}; |
|
|
0
|
|
|
|
|
|
|
|
292
|
0
|
|
|
|
|
|
print 'in Python::Include::python_preparsed_to_perl_source(), have newline-appended $self->{perl_source_code} = \'', $self->{perl_source_code}, '\'', "\n"; |
|
293
|
|
|
|
|
|
|
#die 'TMP DEBUG, MULTI-LINE INCLUDES'; |
|
294
|
|
|
|
|
|
|
} |
|
295
|
|
|
|
|
|
|
|
|
296
|
0
|
|
|
|
|
|
print 'in Python::Include::python_preparsed_to_perl_source(), end of subroutine, about to return $self->{perl_source_code} = \'', $self->{perl_source_code}, '\'', "\n"; |
|
297
|
|
|
|
|
|
|
#die 'TMP DEBUG, INCLUDES'; |
|
298
|
|
|
|
|
|
|
|
|
299
|
0
|
|
|
|
|
|
return $self->{perl_source_code}; |
|
300
|
|
|
|
|
|
|
} |
|
301
|
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
1; |