File Coverage

blib/lib/RPerl/Operation/Statement/Loop/For.pm
Criterion Covered Total %
statement 15 15 100.0
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 20 20 100.0


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