File Coverage

blib/lib/RPerl/Operation/Statement/Loop/For.pm
Criterion Covered Total %
statement 83 212 39.1
branch 14 74 18.9
condition 7 45 15.5
subroutine 6 8 75.0
pod n/a
total 110 339 32.4


line stmt bran cond sub pod time code
1             # [[[ HEADER ]]]
2             package RPerl::Operation::Statement::Loop::For;
3 4     4   23 use strict;
  4         9  
  4         96  
4 4     4   18 use warnings;
  4         234  
  4         97  
5 4     4   18 use RPerl::AfterSubclass;
  4         8  
  4         507  
6             our $VERSION = 0.007_100;
7              
8             # [[[ OO INHERITANCE ]]]
9 4     4   25 use parent qw(RPerl::Operation::Statement::Loop);
  4         8  
  4         18  
10 4     4   285 use RPerl::Operation::Statement::Loop;
  4         6  
  4         8190  
11              
12             # [[[ CRITICS ]]]
13             ## no critic qw(ProhibitUselessNoCritic ProhibitMagicNumbers RequireCheckedSyscalls) # USER DEFAULT 1: allow numeric values & print operator
14             ## no critic qw(RequireInterpolationOfMetachars) # USER DEFAULT 2: allow single-quoted control characters & sigils
15              
16             # [[[ OO PROPERTIES ]]]
17             our hashref $properties = {};
18              
19             # [[[ SUBROUTINES & OO METHODS ]]]
20              
21             sub ast_to_rperl__generate {
22 15     15   38 { my string_hashref::method $RETURN_TYPE };
  15         34  
23 15         52 ( my object $self, my string_hashref $modes) = @ARG;
24 15         72 my string_hashref $rperl_source_group = { PMC => q{} };
25 15         36 my string_hashref $rperl_source_subgroup;
26              
27             # RPerl::diag( 'in Loop::For->ast_to_rperl__generate(), received $self = ' . "\n" . RPerl::Parser::rperl_ast__dump($self) . "\n" );
28              
29 15         46 my string $self_class = ref $self;
30              
31             # unwrap LoopFor_181 and LoopFor_182 from Loop_178
32 15 50       66 if ( $self_class eq 'Loop_178' ) { # Loop -> LoopFor
33 15         73 $self = $self->{children}->[0];
34 15         46 $self_class = ref $self;
35             }
36              
37 15 100       83 if ( $self_class eq 'LoopFor_181' ) {
    50          
38              
39             # LoopFor -> 'for' MY TYPE_INTEGER VARIABLE_SYMBOL LPAREN SubExpression OP17_LIST_RANGE SubExpression ')' CodeBlock
40 8         39 my string $for = $self->{children}->[0];
41 8         34 my string $my = $self->{children}->[1];
42 8         33 my string $type_integer = $self->{children}->[2];
43 8         28 my string $variable_symbol = $self->{children}->[3];
44 8         26 my string $left_paren = $self->{children}->[4];
45 8         23 my object $subexpression0 = $self->{children}->[5];
46 8         26 my string $list_range = $self->{children}->[6];
47 8         20 my object $subexpression1 = $self->{children}->[7];
48 8         24 my string $right_paren = $self->{children}->[8];
49 8         21 my object $codeblock = $self->{children}->[9];
50              
51             # CREATE SYMBOL TABLE ENTRY
52             # DEV NOTE: allow re-declaration of loop iterator variables within other loop headers, they should not conflict
53 8 50 66     84 if (( exists $modes->{_symbol_table}->{ $modes->{_symbol_table}->{_namespace} }->{ $modes->{_symbol_table}->{_subroutine} }->{$variable_symbol} )
54             and ( $modes->{_symbol_table}->{ $modes->{_symbol_table}->{_namespace} }->{ $modes->{_symbol_table}->{_subroutine} }->{$variable_symbol}->{isa} ne
55             'RPerl::Operation::Expression::SubExpression::Variable::LoopIterator' )
56             )
57             {
58             die 'ERROR ECOGEASRP12, CODE GENERATOR, ABSTRACT SYNTAX TO RPERL: variable '
59             . $variable_symbol
60             . ' already declared in this scope, namespace '
61             . q{'} . $modes->{_symbol_table}->{_namespace} . q{'}
62             . ', subroutine/method '
63 0         0 . q{'} . $modes->{_symbol_table}->{_subroutine} . q{()'}
64             . ', dying' . "\n";
65             }
66 8         72 $modes->{_symbol_table}->{ $modes->{_symbol_table}->{_namespace} }->{ $modes->{_symbol_table}->{_subroutine} }->{$variable_symbol}
67             = { isa => 'RPerl::Operation::Expression::SubExpression::Variable::LoopIterator', type => $type_integer }; # NEED UPGRADE: replace fake class isa w/ real class here and below?
68              
69 8         44 $rperl_source_group->{PMC} .= $for . q{ } . $my . q{ } . $type_integer . q{ } . $variable_symbol . q{ } . $left_paren . q{ };
70 8         228 $rperl_source_subgroup = $subexpression0->ast_to_rperl__generate($modes);
71 8         197 RPerl::Generator::source_group_append( $rperl_source_group, $rperl_source_subgroup );
72 8         50 $rperl_source_group->{PMC} .= q{ } . $list_range . q{ };
73 8         190 $rperl_source_subgroup = $subexpression1->ast_to_rperl__generate($modes);
74 8         189 RPerl::Generator::source_group_append( $rperl_source_group, $rperl_source_subgroup );
75 8         38 $rperl_source_group->{PMC} .= q{ } . $right_paren . q{ };
76 8         214 $rperl_source_subgroup = $codeblock->ast_to_rperl__generate($modes);
77 8         237 RPerl::Generator::source_group_append( $rperl_source_group, $rperl_source_subgroup );
78             }
79             elsif ( $self_class eq 'LoopFor_182' ) {
80             # LoopFor -> 'for' LPAREN_MY TYPE_INTEGER VARIABLE_SYMBOL OP19_VARIABLE_ASSIGN OpNamedScolonOrSubExp VARIABLE_SYMBOL OP11_COMPARE_LT_GT OpNamedScolonOrSubExp SubExpressionOrVarMod ')' CodeBlock
81 7         59 my string $for = $self->{children}->[0];
82 7         26 my string $left_paren_my = $self->{children}->[1];
83 7         21 my string $type_integer = $self->{children}->[2];
84 7         21 my string $variable_symbol0 = $self->{children}->[3];
85 7         28 my string $assign = $self->{children}->[4];
86 7         18 my object $opnamed_or_subexp_scolon0 = $self->{children}->[5];
87 7         29 my string $variable_symbol1 = $self->{children}->[6];
88 7         30 my string $compare = $self->{children}->[7];
89 7         20 my object $opnamed_or_subexp_scolon1 = $self->{children}->[8];
90 7         18 my object $subexpression_or_varmod = $self->{children}->[9];
91 7         24 my string $right_paren = $self->{children}->[10];
92 7         20 my object $codeblock = $self->{children}->[11];
93              
94 7 100       35 if ( $variable_symbol0 ne $variable_symbol1 ) {
95 1         27 die 'ERROR ECOGEASRP06, CODE GENERATOR, ABSTRACT SYNTAX TO RPerl: C-style for() loop header variable mismatch, initial-condition variable '
96             . q{'}
97             . $variable_symbol0 . q{'}
98             . ' is different than exit-condition variable ' . q{'}
99             . $variable_symbol1 . q{'}
100             . ', dying' . "\n";
101             }
102              
103             # CREATE SYMBOL TABLE ENTRY
104 6 50 33     53 if (( exists $modes->{_symbol_table}->{ $modes->{_symbol_table}->{_namespace} }->{ $modes->{_symbol_table}->{_subroutine} }->{$variable_symbol0} )
105             and ( $modes->{_symbol_table}->{ $modes->{_symbol_table}->{_namespace} }->{ $modes->{_symbol_table}->{_subroutine} }->{$variable_symbol0}->{isa} ne
106             'RPerl::Operation::Expression::SubExpression::Variable::LoopIterator' )
107             )
108             {
109             die 'ERROR ECOGEASRP12, CODE GENERATOR, ABSTRACT SYNTAX TO RPERL: variable '
110             . $variable_symbol0
111             . ' already declared in this scope, namespace '
112             . q{'} . $modes->{_symbol_table}->{_namespace} . q{'}
113             . ', subroutine/method '
114 0         0 . q{'} . $modes->{_symbol_table}->{_subroutine} . q{()'}
115             . ', dying' . "\n";
116             }
117 6         50 $modes->{_symbol_table}->{ $modes->{_symbol_table}->{_namespace} }->{ $modes->{_symbol_table}->{_subroutine} }->{$variable_symbol0}
118             = { isa => 'RPerl::Operation::Expression::SubExpression::Variable::LoopIterator', type => $type_integer };
119              
120 6         43 $rperl_source_group->{PMC} .= $for . q{ } . $left_paren_my . q{ } . $type_integer . q{ } . $variable_symbol0 . q{ } . $assign . q{ };
121              
122 6         21 my string $opnamed_or_subexp_scolon0_type = ref $opnamed_or_subexp_scolon0;
123             # RPerl::diag( 'in Loop::For->ast_to_rperl__generate(), have $opnamed_or_subexp_scolon0_type = ' . "\n" . RPerl::Parser::rperl_ast__dump($opnamed_or_subexp_scolon0_type) . "\n" );
124              
125 6 100 66     51 if ( ( $opnamed_or_subexp_scolon0_type eq 'OpNamedScolonOrSubExp_250' )
    50          
126             or ( $opnamed_or_subexp_scolon0_type eq 'OpNamedScolonOrSubExp_251' ) )
127             {
128             # OpNamedScolonOrSubExp -> OP01_NAMED_SCOLON
129             # OpNamedScolonOrSubExp -> OP10_NAMED_UNARY_SCOLON
130 2         27 $rperl_source_group->{PMC} .= $opnamed_or_subexp_scolon0->{children}->[0];
131             }
132             elsif ( $opnamed_or_subexp_scolon0_type eq 'OpNamedScolonOrSubExp_252' ) { # OpNamedScolonOrSubExp -> SubExpression ';'
133 4         130 $rperl_source_subgroup = $opnamed_or_subexp_scolon0->{children}->[0]->ast_to_rperl__generate($modes); # subexpression
134 4         93 RPerl::Generator::source_group_append( $rperl_source_group, $rperl_source_subgroup );
135 4         14 $rperl_source_group->{PMC} .= $opnamed_or_subexp_scolon0->{children}->[1]; # semicolon
136             }
137             else {
138 0         0 die RPerl::Parser::rperl_rule__replace( 'ERROR ECOGEASRP00, CODE GENERATOR, ABSTRACT SYNTAX TO RPERL: Grammar rule '
139             . $opnamed_or_subexp_scolon0_type
140             . ' found where OpNamedScolonOrSubExp_250, OpNamedScolonOrSubExp_251, or OpNamedScolonOrSubExp_252 expected, dying' )
141             . "\n";
142             }
143              
144 6         30 $rperl_source_group->{PMC} .= q{ } . $variable_symbol1 . q{ } . $compare . q{ };
145              
146 6         19 my string $opnamed_or_subexp_scolon1_type = ref $opnamed_or_subexp_scolon1;
147             # RPerl::diag( 'in Loop::For->ast_to_rperl__generate(), have $opnamed_or_subexp_scolon1_type = ' . "\n" . RPerl::Parser::rperl_ast__dump($opnamed_or_subexp_scolon1_type) . "\n" );
148              
149 6 100 66     50 if ( ( $opnamed_or_subexp_scolon1_type eq 'OpNamedScolonOrSubExp_250' )
    50          
150             or ( $opnamed_or_subexp_scolon1_type eq 'OpNamedScolonOrSubExp_251' ) )
151             {
152             # OpNamedScolonOrSubExp -> OP01_NAMED_SCOLON
153             # OpNamedScolonOrSubExp -> OP10_NAMED_UNARY_SCOLON
154 2         10 $rperl_source_group->{PMC} .= $opnamed_or_subexp_scolon1->{children}->[0];
155             }
156             elsif ( $opnamed_or_subexp_scolon1_type eq 'OpNamedScolonOrSubExp_252' ) { # OpNamedScolonOrSubExp -> SubExpression ';'
157 4         94 $rperl_source_subgroup = $opnamed_or_subexp_scolon1->{children}->[0]->ast_to_rperl__generate($modes); # subexpression
158 4         89 RPerl::Generator::source_group_append( $rperl_source_group, $rperl_source_subgroup );
159 4         15 $rperl_source_group->{PMC} .= $opnamed_or_subexp_scolon1->{children}->[1]; # semicolon
160             }
161             else {
162 0         0 die RPerl::Parser::rperl_rule__replace( 'ERROR ECOGEASRP00, CODE GENERATOR, ABSTRACT SYNTAX TO RPERL: Grammar rule '
163             . $opnamed_or_subexp_scolon1_type
164             . ' found where OpNamedScolonOrSubExp_250, OpNamedScolonOrSubExp_251, or OpNamedScolonOrSubExp_252 expected, dying' )
165             . "\n";
166             }
167              
168 6         19 $rperl_source_group->{PMC} .= q{ };
169 6         156 $rperl_source_subgroup = $subexpression_or_varmod->ast_to_rperl__generate($modes);
170 6         137 RPerl::Generator::source_group_append( $rperl_source_group, $rperl_source_subgroup );
171 6         22 $rperl_source_group->{PMC} .= q{ } . $right_paren . q{ };
172 6         143 $rperl_source_subgroup = $codeblock->ast_to_rperl__generate($modes);
173 6         144 RPerl::Generator::source_group_append( $rperl_source_group, $rperl_source_subgroup );
174             }
175             else {
176 0         0 die RPerl::Parser::rperl_rule__replace( 'ERROR ECOGEASRP00, CODE GENERATOR, ABSTRACT SYNTAX TO RPERL: Grammar rule '
177             . $self_class
178             . ' found where Loop_178, LoopFor_181, or LoopFor_182 expected, dying' )
179             . "\n";
180             }
181 14         113 return $rperl_source_group;
182             }
183              
184             sub ast_to_cpp__generate__CPPOPS_PERLTYPES {
185 0     0     { my string_hashref::method $RETURN_TYPE };
  0            
186 0           ( my object $self, my string $loop_label, my string_hashref $modes) = @ARG;
187 0           my string_hashref $cpp_source_group = { CPP => q{// <<< RP::O::S::L::F __DUMMY_SOURCE_CODE CPPOPS_PERLTYPES >>>} . "\n" };
188              
189             #...
190 0           return $cpp_source_group;
191             }
192              
193             sub ast_to_cpp__generate__CPPOPS_CPPTYPES {
194 0     0     { my string_hashref::method $RETURN_TYPE };
  0            
195 0           ( my object $self, my string $loop_label, my string_hashref $modes) = @ARG;
196 0           my string_hashref $cpp_source_group = { CPP => q{} };
197 0           my string_hashref $cpp_source_subgroup;
198              
199             # RPerl::diag( 'in Loop::For->ast_to_cpp__generate__CPPOPS_CPPTYPES(), received $self = ' . "\n" . RPerl::Parser::rperl_ast__dump($self) . "\n" );
200             # RPerl::diag( 'in Loop::For->ast_to_cpp__generate__CPPOPS_CPPTYPES(), received $loop_label = ' . "\n" . RPerl::Parser::rperl_ast__dump($loop_label) . "\n" );
201              
202 0           my string $self_class = ref $self;
203              
204 0 0 0       if ((not exists $modes->{_inside_parallel_loop}) and (not defined $modes->{_inside_parallel_loop})) {
205 0           $modes->{_inside_parallel_loop} = 0;
206             }
207 0 0 0       if ((not exists $modes->{_current_parallel_loop}) and (not defined $modes->{_current_parallel_loop})) {
208 0           $modes->{_current_parallel_loop} = [];
209             }
210 0 0 0       if ((defined $loop_label) and ($loop_label =~ m/PARALLEL/gmxs)) {
211 0 0         if ($modes->{_inside_parallel_loop}) {
212 0           die 'ERROR Exxxxx, COMPILER, PARALLELIZATION: Can not declare nested PARALLEL loops, dying';
213             }
214 0           $modes->{_inside_parallel_loop} = 1;
215 0           push @{$modes->{_current_parallel_loop}}, 1;
  0            
216             }
217             else {
218 0           push @{$modes->{_current_parallel_loop}}, 0;
  0            
219             }
220             # RPerl::diag( 'in Loop::For->ast_to_cpp__generate__CPPOPS_CPPTYPES(), top of subroutine, have $modes->{_current_parallel_loop} = ' . "\n" . Dumper($modes->{_current_parallel_loop}) . "\n" );
221              
222             # unwrap LoopFor_181 and LoopFor_182 from Loop_178
223 0 0         if ( $self_class eq 'Loop_178' ) { # Loop -> LoopFor
224 0           $self = $self->{children}->[0];
225 0           $self_class = ref $self;
226             }
227              
228             # RANGE FOR LOOP
229             # LoopFor -> 'for' MY TYPE_INTEGER VARIABLE_SYMBOL LPAREN SubExpression OP17_LIST_RANGE SubExpression ')' CodeBlock
230 0 0         if ( $self_class eq 'LoopFor_181' ) {
    0          
231 0           my string $for = $self->{children}->[0];
232 0           my string $type_integer = $self->{children}->[2];
233 0           my string $variable_symbol = $self->{children}->[3];
234 0           my string $left_paren = $self->{children}->[4];
235 0           my object $subexpression0 = $self->{children}->[5];
236 0           my object $subexpression1 = $self->{children}->[7];
237 0           my string $right_paren = $self->{children}->[8];
238 0           my object $codeblock = $self->{children}->[9];
239              
240 0           substr $variable_symbol, 0, 1, q{}; # remove leading $ sigil
241              
242             # RPerl::diag( 'in Loop::For->ast_to_cpp__generate__CPPOPS_CPPTYPES(), have $modes->{_symbol_table} = ' . "\n" . Dumper($modes->{_symbol_table}) . "\n" );
243             # RPerl::diag( 'in Loop::For->ast_to_cpp__generate__CPPOPS_CPPTYPES(), have $modes->{_symbol_table}->{_namespace} = ' . "\n" . Dumper($modes->{_symbol_table}->{_namespace}) . "\n" );
244             # RPerl::diag( 'in Loop::For->ast_to_cpp__generate__CPPOPS_CPPTYPES(), have $modes->{_symbol_table}->{_subroutine} = ' . "\n" . Dumper($modes->{_symbol_table}->{_subroutine}) . "\n" );
245              
246             # CREATE SYMBOL TABLE ENTRY
247             # DEV NOTE: allow re-declaration of loop iterator variables within other loop headers, they should not conflict
248 0 0 0       if (( exists $modes->{_symbol_table}->{ $modes->{_symbol_table}->{_namespace} }->{ $modes->{_symbol_table}->{_subroutine} }->{$variable_symbol} )
249             and ( $modes->{_symbol_table}->{ $modes->{_symbol_table}->{_namespace} }->{ $modes->{_symbol_table}->{_subroutine} }->{$variable_symbol}->{isa} ne
250             'RPerl::Operation::Expression::SubExpression::Variable::LoopIterator' )
251             )
252             {
253             die 'ERROR ECOGEASCP12, CODE GENERATOR, ABSTRACT SYNTAX TO C++: variable '
254             . $variable_symbol
255             . ' already declared in this scope, namespace '
256             . q{'} . $modes->{_symbol_table}->{_namespace} . q{'}
257             . ', subroutine/method '
258 0           . q{'} . $modes->{_symbol_table}->{_subroutine} . q{()'}
259             . ', dying' . "\n";
260             }
261 0           $modes->{_symbol_table}->{ $modes->{_symbol_table}->{_namespace} }->{ $modes->{_symbol_table}->{_subroutine} }->{$variable_symbol}
262             = { isa => 'RPerl::Operation::Expression::SubExpression::Variable::LoopIterator', type => $type_integer }; # NEED UPGRADE: replace fake class isa w/ real class here and below?
263              
264             # COMPILE-TIME OPTIMIZATION #02: save loop iterators for declaration at the top of the subroutine/method
265 0 0 0       if ( ( not exists $modes->{_loop_iterators} ) or ( not defined $modes->{_loop_iterators} ) ) {
266 0           $modes->{_loop_iterators} = { $variable_symbol => $type_integer };
267             }
268             else {
269 0 0 0       if ( ( exists $modes->{_loop_iterators}->{$variable_symbol} ) and ( $modes->{_loop_iterators}->{$variable_symbol} ne $type_integer ) ) {
270             die 'ERROR ECOGEASCP40, CODE GENERATOR, ABSTRACT SYNTAX TO C++: Compile-time optimization, loop iterator '
271             . $variable_symbol
272             . ' declared as non-integer type '
273 0           . $modes->{_loop_iterators}->{$variable_symbol}
274             . ', dying' . "\n";
275             }
276 0           $modes->{_loop_iterators}->{$variable_symbol} = $type_integer;
277             }
278             # RPerl::diag( 'in Loop::For->ast_to_cpp__generate__CPPOPS_CPPTYPES(), Perl-style for() loop, have $modes->{_loop_iterators} = ' . "\n" . Dumper($modes->{_loop_iterators}) . "\n" );
279             # RPerl::diag( 'in Loop::For->ast_to_cpp__generate__CPPOPS_CPPTYPES(), Perl-style for() loop, before #pragma scop, have $modes->{_current_parallel_loop} = ' . "\n" . Dumper($modes->{_current_parallel_loop}) . "\n" );
280              
281 0 0         if ($modes->{_current_parallel_loop}->[-1]) {
282 0 0         if ($modes->{parallel} eq 'OPENMP') {
283 0           $cpp_source_group->{CPP} .= '#pragma scop' . "\n";
284             }
285             }
286 0           $cpp_source_group->{CPP} .= $for . q{ } . $left_paren . q{ } . $variable_symbol . q{ = };
287 0           $cpp_source_subgroup = $subexpression0->ast_to_cpp__generate__CPPOPS_CPPTYPES($modes);
288 0           RPerl::Generator::source_group_append( $cpp_source_group, $cpp_source_subgroup );
289              
290 0           my string $subexpression1_address = "$subexpression1";
291 0           my object $subexpression1_modified = RPerl::Generator::arrayref_convert_index_max_to_size($subexpression1);
292 0 0         if ( $subexpression1_address ne "$subexpression1_modified" ) {
293              
294             # COMPILE-TIME OPTIMIZATION #03: avoids subtraction and is-equal
295 0           $cpp_source_group->{CPP} .= q{; } . $variable_symbol . ' < ';
296 0           $cpp_source_subgroup = $subexpression1_modified->ast_to_cpp__generate__CPPOPS_CPPTYPES($modes);
297 0           RPerl::Generator::source_group_append( $cpp_source_group, $cpp_source_subgroup );
298             }
299             else {
300 0           $cpp_source_group->{CPP} .= q{; } . $variable_symbol . ' <= ';
301 0           $cpp_source_subgroup = $subexpression1->ast_to_cpp__generate__CPPOPS_CPPTYPES($modes);
302 0           RPerl::Generator::source_group_append( $cpp_source_group, $cpp_source_subgroup );
303             }
304              
305 0           $cpp_source_group->{CPP} .= q{; } . $variable_symbol . '++ ' . $right_paren . q{ };
306 0           $cpp_source_subgroup = $codeblock->ast_to_cpp__generate__CPPOPS_CPPTYPES( $loop_label, $modes );
307 0           RPerl::Generator::source_group_append( $cpp_source_group, $cpp_source_subgroup );
308              
309             # RPerl::diag( 'in Loop::For->ast_to_cpp__generate__CPPOPS_CPPTYPES(), Perl-style for() loop, before #pragma endscop, have $modes->{_current_parallel_loop} = ' . "\n" . Dumper($modes->{_current_parallel_loop}) . "\n" );
310 0 0         if ($modes->{_current_parallel_loop}->[-1]) {
311 0 0         if ($modes->{parallel} eq 'OPENMP') {
312 0           $cpp_source_group->{CPP} .= '#pragma endscop' . "\n";
313             }
314 0           $modes->{_inside_parallel_loop} = 0;
315             }
316 0           pop @{$modes->{_current_parallel_loop}};
  0            
317             }
318             # C-STYLE FOR LOOP
319             elsif ( $self_class eq 'LoopFor_182' ) {
320             # LoopFor -> 'for' LPAREN_MY TYPE_INTEGER VARIABLE_SYMBOL OP19_VARIABLE_ASSIGN OpNamedScolonOrSubExp VARIABLE_SYMBOL OP11_COMPARE_LT_GT OpNamedScolonOrSubExp SubExpressionOrVarMod ')' CodeBlock
321 0           my string $for = $self->{children}->[0];
322 0           my string $type_integer = $self->{children}->[2];
323 0           my string $variable_symbol0 = $self->{children}->[3];
324 0           my string $assign = $self->{children}->[4];
325 0           my object $opnamed_or_subexp_scolon0 = $self->{children}->[5];
326 0           my string $variable_symbol1 = $self->{children}->[6];
327 0           my string $compare = $self->{children}->[7];
328 0           my object $opnamed_or_subexp_scolon1 = $self->{children}->[8];
329 0           my object $subexpression_or_varmod = $self->{children}->[9];
330 0           my string $right_paren = $self->{children}->[10];
331 0           my object $codeblock = $self->{children}->[11];
332              
333 0 0         if ( $variable_symbol0 ne $variable_symbol1 ) {
334 0           die 'ERROR ECOGEASCP06, CODE GENERATOR, ABSTRACT SYNTAX TO C++: C-style for() loop header variable mismatch, initial-condition variable ' . q{'}
335             . $variable_symbol0 . q{'}
336             . ' is different than exit-condition variable ' . q{'}
337             . $variable_symbol1 . q{'}
338             . ' , dying' . "\n";
339             }
340              
341 0           substr $variable_symbol0, 0, 1, q{}; # remove leading $ sigil
342 0           substr $variable_symbol1, 0, 1, q{}; # remove leading $ sigil
343              
344             # CREATE SYMBOL TABLE ENTRY
345 0 0 0       if (( exists $modes->{_symbol_table}->{ $modes->{_symbol_table}->{_namespace} }->{ $modes->{_symbol_table}->{_subroutine} }->{$variable_symbol0} )
346             and ( $modes->{_symbol_table}->{ $modes->{_symbol_table}->{_namespace} }->{ $modes->{_symbol_table}->{_subroutine} }->{$variable_symbol0}->{isa} ne
347             'RPerl::Operation::Expression::SubExpression::Variable::LoopIterator' )
348             )
349             {
350             die 'ERROR ECOGEASCP12, CODE GENERATOR, ABSTRACT SYNTAX TO C++: variable '
351             . $variable_symbol0
352             . ' already declared in this scope, namespace '
353             . q{'} . $modes->{_symbol_table}->{_namespace} . q{'}
354             . ', subroutine/method '
355 0           . q{'} . $modes->{_symbol_table}->{_subroutine} . q{()'}
356             . ', dying' . "\n";
357             }
358 0           $modes->{_symbol_table}->{ $modes->{_symbol_table}->{_namespace} }->{ $modes->{_symbol_table}->{_subroutine} }->{$variable_symbol0}
359             = { isa => 'RPerl::Operation::Expression::SubExpression::Variable::LoopIterator', type => $type_integer };
360              
361             # COMPILE-TIME OPTIMIZATION #02: save loop iterators for declaration at the top of the subroutine/method
362 0 0 0       if ( ( not exists $modes->{_loop_iterators} ) or ( not defined $modes->{_loop_iterators} ) ) {
363 0           $modes->{_loop_iterators} = { $variable_symbol0 => $type_integer };
364             }
365             else {
366 0 0 0       if ( ( exists $modes->{_loop_iterators}->{$variable_symbol0} ) and ( $modes->{_loop_iterators}->{$variable_symbol0} ne $type_integer ) ) {
367             die 'ERROR ECOGEASCPxa, CODE GENERATOR, ABSTRACT SYNTAX TO C++: Compile-time optimization, loop iterator '
368             . $variable_symbol0
369             . ' declared as non-integer type '
370 0           . $modes->{_loop_iterators}->{$variable_symbol0}
371             . ', dying' . "\n";
372             }
373 0           $modes->{_loop_iterators}->{$variable_symbol0} = $type_integer;
374             }
375             # RPerl::diag( 'in Loop::For->ast_to_cpp__generate__CPPOPS_CPPTYPES(), C-style for() loop, have $modes->{_loop_iterators} = ' . "\n" . Dumper($modes->{_loop_iterators}) . "\n" );
376             # RPerl::diag( 'in Loop::For->ast_to_cpp__generate__CPPOPS_CPPTYPES(), C-style for() loop, before #pragma scop, have $modes->{_current_parallel_loop} = ' . "\n" . Dumper($modes->{_current_parallel_loop}) . "\n" );
377              
378 0 0         if ($modes->{_current_parallel_loop}->[-1]) {
379 0 0         if ($modes->{parallel} eq 'OPENMP') {
380 0           $cpp_source_group->{CPP} .= '#pragma scop' . "\n";
381             }
382             }
383 0           $cpp_source_group->{CPP} .= $for . q{ ( } . $variable_symbol0 . q{ } . $assign . q{ };
384              
385 0           my string $opnamed_or_subexp_scolon0_type = ref $opnamed_or_subexp_scolon0;
386             # RPerl::diag( 'in Loop::For->ast_to_cpp__generate__CPPOPS_CPPTYPES(), have $opnamed_or_subexp_scolon0_type = ' . "\n" . RPerl::Parser::rperl_ast__dump($opnamed_or_subexp_scolon0_type) . "\n" );
387              
388 0 0 0       if ( ( $opnamed_or_subexp_scolon0_type eq 'OpNamedScolonOrSubExp_250' )
    0          
389             or ( $opnamed_or_subexp_scolon0_type eq 'OpNamedScolonOrSubExp_251' ) )
390             {
391             # OpNamedScolonOrSubExp -> OP01_NAMED_SCOLON
392             # OpNamedScolonOrSubExp -> OP10_NAMED_UNARY_SCOLON
393 0           $cpp_source_group->{CPP} .= $opnamed_or_subexp_scolon0->{children}->[0];
394             }
395             elsif ( $opnamed_or_subexp_scolon0_type eq 'OpNamedScolonOrSubExp_252' ) { # OpNamedScolonOrSubExp -> SubExpression ';'
396 0           $cpp_source_subgroup = $opnamed_or_subexp_scolon0->{children}->[0]->ast_to_cpp__generate__CPPOPS_CPPTYPES($modes); # subexpression
397 0           RPerl::Generator::source_group_append( $cpp_source_group, $cpp_source_subgroup );
398 0           $cpp_source_group->{CPP} .= $opnamed_or_subexp_scolon0->{children}->[1]; # semicolon
399             }
400             else {
401 0           die RPerl::Parser::rperl_rule__replace( 'ERROR ECOGEASRP00, CODE GENERATOR, ABSTRACT SYNTAX TO RPERL: Grammar rule '
402             . $opnamed_or_subexp_scolon0_type
403             . ' found where OpNamedScolonOrSubExp_250, OpNamedScolonOrSubExp_251, or OpNamedScolonOrSubExp_252 expected, dying' )
404             . "\n";
405             }
406              
407 0           $cpp_source_group->{CPP} .= q{ } . $variable_symbol1 . q{ } . $compare . q{ };
408              
409 0           my string $opnamed_or_subexp_scolon1_type = ref $opnamed_or_subexp_scolon1;
410             # RPerl::diag( 'in Loop::For->ast_to_cpp__generate__CPPOPS_CPPTYPES(), have $opnamed_or_subexp_scolon1_type = ' . "\n" . RPerl::Parser::rperl_ast__dump($opnamed_or_subexp_scolon1_type) . "\n" );
411              
412 0 0 0       if ( ( $opnamed_or_subexp_scolon1_type eq 'OpNamedScolonOrSubExp_250' )
    0          
413             or ( $opnamed_or_subexp_scolon1_type eq 'OpNamedScolonOrSubExp_251' ) )
414             {
415             # OpNamedScolonOrSubExp -> OP01_NAMED_SCOLON
416             # OpNamedScolonOrSubExp -> OP10_NAMED_UNARY_SCOLON
417 0           $cpp_source_group->{CPP} .= $opnamed_or_subexp_scolon1->{children}->[0];
418             }
419             elsif ( $opnamed_or_subexp_scolon1_type eq 'OpNamedScolonOrSubExp_252' ) { # OpNamedScolonOrSubExp -> SubExpression ';'
420 0           $cpp_source_subgroup = $opnamed_or_subexp_scolon1->{children}->[0]->ast_to_cpp__generate__CPPOPS_CPPTYPES($modes); # subexpression
421 0           RPerl::Generator::source_group_append( $cpp_source_group, $cpp_source_subgroup );
422 0           $cpp_source_group->{CPP} .= $opnamed_or_subexp_scolon1->{children}->[1]; # semicolon
423             }
424             else {
425 0           die RPerl::Parser::rperl_rule__replace( 'ERROR ECOGEASRP00, CODE GENERATOR, ABSTRACT SYNTAX TO RPERL: Grammar rule '
426             . $opnamed_or_subexp_scolon1_type
427             . ' found where OpNamedScolonOrSubExp_250, OpNamedScolonOrSubExp_251, or OpNamedScolonOrSubExp_252 expected, dying' )
428             . "\n";
429             }
430              
431 0           $cpp_source_group->{CPP} .= q{ };
432 0           $cpp_source_subgroup = $subexpression_or_varmod->ast_to_cpp__generate__CPPOPS_CPPTYPES($modes);
433 0           RPerl::Generator::source_group_append( $cpp_source_group, $cpp_source_subgroup );
434 0           $cpp_source_group->{CPP} .= q{ } . $right_paren . q{ };
435 0           $cpp_source_subgroup = $codeblock->ast_to_cpp__generate__CPPOPS_CPPTYPES($loop_label, $modes);
436 0           RPerl::Generator::source_group_append( $cpp_source_group, $cpp_source_subgroup );
437              
438             # RPerl::diag( 'in Loop::For->ast_to_cpp__generate__CPPOPS_CPPTYPES(), C-style for() loop, before #pragma endscop, have $modes->{_current_parallel_loop} = ' . "\n" . Dumper($modes->{_current_parallel_loop}) . "\n" );
439 0 0         if ($modes->{_current_parallel_loop}->[-1]) {
440 0 0         if ($modes->{parallel} eq 'OPENMP') {
441 0           $cpp_source_group->{CPP} .= '#pragma endscop' . "\n";
442             }
443 0           $modes->{_inside_parallel_loop} = 0;
444             }
445 0           pop @{$modes->{_current_parallel_loop}};
  0            
446             }
447             else {
448 0           die RPerl::Parser::rperl_rule__replace( 'ERROR ECOGEASCP00, CODE GENERATOR, ABSTRACT SYNTAX TO C++: Grammar rule '
449             . $self_class
450             . ' found where Loop_178, LoopFor_181, or LoopFor_182 expected, dying' )
451             . "\n";
452             }
453             # RPerl::diag( 'in Loop::For->ast_to_cpp__generate__CPPOPS_CPPTYPES(), bottom of subroutine, have $modes->{_loop_iterators} = ' . "\n" . Dumper($modes->{_loop_iterators}) . "\n" );
454 0           return $cpp_source_group;
455             }
456              
457             1; # end of class