File Coverage

blib/lib/RPerl/Operation/Statement/VariableDeclaration.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::VariableDeclaration;
3 4     4   24 use strict;
  4         9  
  4         105  
4 4     4   20 use warnings;
  4         9  
  4         88  
5 4     4   21 use RPerl::AfterSubclass;
  4         11  
  4         501  
6             our $VERSION = 0.008_000;
7              
8             # [[[ OO INHERITANCE ]]]
9 4     4   28 use parent qw(RPerl::Operation::Statement);
  4         10  
  4         25  
10              
11             # [[[ CRITICS ]]]
12             ## no critic qw(ProhibitUselessNoCritic ProhibitMagicNumbers RequireCheckedSyscalls) # USER DEFAULT 1: allow numeric values & print operator
13             ## no critic qw(RequireInterpolationOfMetachars) # USER DEFAULT 2: allow single-quoted control characters & sigils
14              
15             # [[[ INCLUDES ]]]
16 4     4   255 use Scalar::Util 'blessed';
  4         10  
  4         11701  
17              
18             # [[[ OO PROPERTIES ]]]
19             our hashref $properties = {};
20              
21             # [[[ SUBROUTINES & OO METHODS ]]]
22              
23             our string_hashref::method $ast_to_rperl__generate = sub {
24             ( my object $self, my string_hashref $modes) = @_;
25             my string_hashref $rperl_source_group = { PMC => q{} };
26             my string_hashref $rperl_source_subgroup;
27             my string $self_class = ref $self;
28              
29             # RPerl::diag( 'in VariableDeclaration->ast_to_rperl__generate(), received $self = ' . "\n" . RPerl::Parser::rperl_ast__dump($self) . "\n" );
30             # die 'TMP DEBUG, dying';
31              
32             # unwrap VariableDeclaration_181, VariableDeclaration_182, VariableDeclaration_183, and VariableDeclaration_184 from Statement_155
33             if ( $self_class eq 'Statement_155' ) { # Statement -> VariableDeclaration
34             $self = $self->{children}->[0];
35             $self_class = ref $self;
36             }
37              
38             if ( $self_class eq 'VariableDeclaration_181' ) { # VariableDeclaration -> MY Type VARIABLE_SYMBOL ';'
39             my string $my = $self->{children}->[0];
40             my string $type = $self->{children}->[1]->{children}->[0];
41             my string $symbol = $self->{children}->[2];
42             my string $semicolon = $self->{children}->[3];
43             $rperl_source_group->{PMC} .= $my . q{ } . $type . q{ } . $symbol . $semicolon . "\n";
44              
45             # RPerl::diag( 'in VariableDeclaration->ast_to_rperl__generate(), have $modes->{_symbol_table} = ' . "\n" . Dumper($modes->{_symbol_table}) . "\n" );
46             # RPerl::diag( 'in VariableDeclaration->ast_to_rperl__generate(), have $modes->{_symbol_table}->{_namespace} = ' . "\n" . Dumper($modes->{_symbol_table}->{_namespace}) . "\n" );
47             # RPerl::diag( 'in VariableDeclaration->ast_to_rperl__generate(), have $modes->{_symbol_table}->{_subroutine} = ' . "\n" . Dumper($modes->{_symbol_table}->{_subroutine}) . "\n" );
48              
49             # CREATE SYMBOL TABLE ENTRY
50             if ( exists $modes->{_symbol_table}->{ $modes->{_symbol_table}->{_namespace} }->{ $modes->{_symbol_table}->{_subroutine} }->{$symbol} ) {
51             die 'ERROR ECOGEASRP12, CODE GENERATOR, ABSTRACT SYNTAX TO RPERL: variable '
52             . $symbol
53             . ' already declared in this scope, namespace '
54             . q{'} . $modes->{_symbol_table}->{_namespace} . q{'}
55             . ', subroutine/method '
56             . q{'} . $modes->{_symbol_table}->{_subroutine} . q{()'}
57             . ', dying' . "\n";
58             }
59             $modes->{_symbol_table}->{ $modes->{_symbol_table}->{_namespace} }->{ $modes->{_symbol_table}->{_subroutine} }->{$symbol}
60             = { isa => 'RPerl::Operation::Expression::SubExpression::Variable', type => $type };
61             }
62             elsif ( $self_class eq 'VariableDeclaration_182' ) { # VariableDeclaration -> MY Type VARIABLE_SYMBOL OP19_VARIABLE_ASSIGN OpNamedScolonOrSubExpIn
63             my string $my = $self->{children}->[0];
64             my string $type = $self->{children}->[1]->{children}->[0];
65             my string $symbol = $self->{children}->[2];
66             my string $assign = $self->{children}->[3];
67             my object $opnamed_or_subexp_or_input_scolon = $self->{children}->[4];
68              
69             # RPerl::diag( 'in VariableDeclaration->ast_to_rperl__generate(), have $opnamed_or_subexp_or_input_scolon = ' . "\n" . RPerl::Parser::rperl_ast__dump($opnamed_or_subexp_or_input_scolon) . "\n" );
70              
71             $rperl_source_group->{PMC} .= $my . q{ } . $type . q{ } . $symbol . q{ } . $assign . q{ };
72              
73             my string $opnamed_or_subexp_or_input_scolon_type = ref $opnamed_or_subexp_or_input_scolon;
74              
75             # RPerl::diag( 'in VariableDeclaration->ast_to_rperl__generate(), have $opnamed_or_subexp_or_input_scolon_type = ' . "\n" . RPerl::Parser::rperl_ast__dump($opnamed_or_subexp_or_input_scolon_type) . "\n" );
76              
77             if ( ( $opnamed_or_subexp_or_input_scolon_type eq 'OpNamedScolonOrSubExpIn_239' )
78             or ( $opnamed_or_subexp_or_input_scolon_type eq 'OpNamedScolonOrSubExpIn_240' ) )
79             {
80             # OpNamedScolonOrSubExpIn -> OP01_NAMED_SCOLON
81             # OpNamedScolonOrSubExpIn -> OP10_NAMED_UNARY_SCOLON
82             $rperl_source_group->{PMC} .= $opnamed_or_subexp_or_input_scolon->{children}->[0];
83             }
84             elsif ( $opnamed_or_subexp_or_input_scolon_type eq 'OpNamedScolonOrSubExpIn_241' ) { # OpNamedScolonOrSubExpIn -> SubExpressionOrInput ';'
85              
86             # RPerl::diag( 'in VariableDeclaration->ast_to_rperl__generate(), have (ref $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children}->[0]->{children}->[0]) = ' . "\n" . RPerl::Parser::rperl_ast__dump((ref $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children}->[0]->{children}->[0])) . "\n" );
87              
88             if ( ( exists $opnamed_or_subexp_or_input_scolon->{children} )
89             and ( exists $opnamed_or_subexp_or_input_scolon->{children}->[0] )
90             and ( blessed( $opnamed_or_subexp_or_input_scolon->{children}->[0] ) )
91             and ( exists $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children} )
92             and ( exists $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children}->[0] )
93             and ( blessed( $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children}->[0] ) )
94             and ( exists $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children}->[0]->{children} )
95             and ( exists $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children}->[0]->{children}->[0] )
96             and ( blessed( $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children}->[0]->{children}->[0] ) )
97             and ( $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children}->[0]->{children}->[0]
98             ->isa('RPerl::Operation::Expression::SubroutineCall::MethodCall::ConstructorCall') )
99             )
100             {
101             my string $constructor_type
102             = $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children}->[0]->{children}->[0]->{children}->[0]->{children}->[0];
103              
104             # RPerl::diag( 'in VariableDeclaration->ast_to_rperl__generate(), have $constructor_type = ' . "\n" . RPerl::Parser::rperl_ast__dump($constructor_type) . "\n" );
105              
106             if ( $type ne $constructor_type ) {
107             die RPerl::Parser::rperl_rule__replace( 'ERROR ECOGEASRP20, CODE GENERATOR, ABSTRACT SYNTAX TO RPERL: data type mismatch, ' . q{'}
108             . $type . q{'}
109             . ' type is different than ' . q{'}
110             . $constructor_type . q{'}
111             . ' constructor type, dying' )
112             . "\n";
113             }
114             }
115             elsif (
116             ( exists $opnamed_or_subexp_or_input_scolon->{children} )
117             and ( exists $opnamed_or_subexp_or_input_scolon->{children}->[0] )
118             and ( blessed( $opnamed_or_subexp_or_input_scolon->{children}->[0] ) )
119             and ( exists $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children} )
120             and ( exists $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children}->[0] )
121             and ( blessed( $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children}->[0] ) )
122             and ( exists $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children}->[0]->{children} )
123             and ( exists $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children}->[0]->{children}->[0] )
124             and ( blessed( $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children}->[0]->{children}->[0] ) )
125             and ( $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children}->[0]->{children}->[0]->isa('RPerl::Operation::Expression::SubroutineCall') ) )
126             {
127             my string $constructor_name
128             = $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children}->[0]->{children}->[0]->{children}->[0]->{children}->[0];
129             if ( $constructor_name =~ m/::new$/xms ) {
130             # RPerl::diag( 'in VariableDeclaration->ast_to_cpp__generate__CPPOPS_CPPTYPES(), have $constructor_name = ' . $constructor_name . "\n" );
131             my string $constructor_type = substr $constructor_name, 0, ( ( length $constructor_name ) - 5 );
132             # RPerl::diag( 'in VariableDeclaration->ast_to_cpp__generate__CPPOPS_CPPTYPES(), have $constructor_type = ' . $constructor_type . "\n" );
133              
134             if ( $type ne $constructor_type ) {
135             die RPerl::Parser::rperl_rule__replace( 'ERROR ECOGEASRP20, CODE GENERATOR, ABSTRACT SYNTAX TO RPERL: data type mismatch, ' . q{'}
136             . $type . q{'}
137             . ' type is different than ' . q{'}
138             . $constructor_type . q{'}
139             . ' constructor type, dying' )
140             . "\n";
141             }
142             }
143             }
144              
145             # CREATE SYMBOL TABLE ENTRY
146             # in a *.pl program, you can have variables declared outside of any namespace, which means they are in the default 'main::' namespace AKA '::' using Perl rules
147             if ((not exists $modes->{_symbol_table}->{_namespace}) or (not defined $modes->{_symbol_table}->{_namespace})) {
148             $modes->{_symbol_table}->{_namespace} = 'main::';
149             }
150              
151             # in a *.pl program, you can have variables declared outside of any subroutine, which means they are in the default 'main()' subroutine using C++ rules
152             if ((not exists $modes->{_symbol_table}->{_subroutine}) or (not defined $modes->{_symbol_table}->{_subroutine})) {
153             $modes->{_symbol_table}->{_subroutine} = 'main';
154             }
155              
156             # RPerl::diag('in VariableDeclaration->ast_to_rperl__generate(), have $symbol = ' . $symbol . "\n");
157             # RPerl::diag('in VariableDeclaration->ast_to_rperl__generate(), have $modes->{_symbol_table} = ' . Dumper($modes->{_symbol_table}) . "\n");
158             # RPerl::diag('in VariableDeclaration->ast_to_rperl__generate(), have $modes->{_symbol_table}->{_namespace} = ' . $modes->{_symbol_table}->{_namespace} . "\n");
159             # RPerl::diag('in VariableDeclaration->ast_to_rperl__generate(), have $modes->{_symbol_table}->{_subroutine} = ' . $modes->{_symbol_table}->{_subroutine} . "\n");
160              
161             if ( exists $modes->{_symbol_table}->{ $modes->{_symbol_table}->{_namespace} }->{ $modes->{_symbol_table}->{_subroutine} }->{$symbol} ) {
162             die 'ERROR ECOGEASRP12, CODE GENERATOR, ABSTRACT SYNTAX TO RPERL: variable '
163             . $symbol
164             . ' already declared in this scope, namespace '
165             . q{'} . $modes->{_symbol_table}->{_namespace} . q{'}
166             . ', subroutine/method '
167             . q{'} . $modes->{_symbol_table}->{_subroutine} . q{()'}
168             . ', dying' . "\n";
169             }
170             $modes->{_symbol_table}->{ $modes->{_symbol_table}->{_namespace} }->{ $modes->{_symbol_table}->{_subroutine} }->{$symbol}
171             = { isa => 'RPerl::Operation::Expression::SubExpression::Variable', type => $type };
172              
173             $rperl_source_subgroup = $opnamed_or_subexp_or_input_scolon->{children}->[0]->ast_to_rperl__generate($modes); # subexpression
174             RPerl::Generator::source_group_append( $rperl_source_group, $rperl_source_subgroup );
175             $rperl_source_group->{PMC} .= $opnamed_or_subexp_or_input_scolon->{children}->[1]; # semicolon
176             }
177             else {
178             die RPerl::Parser::rperl_rule__replace( 'ERROR ECOGEASRP00, CODE GENERATOR, ABSTRACT SYNTAX TO RPERL: Grammar rule '
179             . $opnamed_or_subexp_or_input_scolon_type
180             . ' found where OpNamedScolonOrSubExpIn_239, OpNamedScolonOrSubExpIn_240, or OpNamedScolonOrSubExpIn_241 expected, dying' )
181             . "\n";
182             }
183              
184             $rperl_source_group->{PMC} .= "\n";
185             }
186             elsif ( $self_class eq 'VariableDeclaration_183' ) { # VariableDeclaration -> MY Type VARIABLE_SYMBOL OP02_ARRAY_THINARROW SubExpression ']' OP19_VARIABLE_ASSIGN 'undef' ';'
187             my string $my = $self->{children}->[0];
188             my string $type = $self->{children}->[1]->{children}->[0];
189             my string $symbol = $self->{children}->[2];
190             my string $arrow_left_bracket = $self->{children}->[3];
191             my object $subexpression = $self->{children}->[4];
192             my string $right_bracket = $self->{children}->[5];
193             my string $assign = $self->{children}->[6];
194             my string $undef = $self->{children}->[7];
195             my string $semicolon = $self->{children}->[8];
196              
197             # CREATE SYMBOL TABLE ENTRY
198             if ( exists $modes->{_symbol_table}->{ $modes->{_symbol_table}->{_namespace} }->{ $modes->{_symbol_table}->{_subroutine} }->{$symbol} ) {
199             die 'ERROR ECOGEASRP12, CODE GENERATOR, ABSTRACT SYNTAX TO RPERL: variable '
200             . $symbol
201             . ' already declared in this scope, namespace '
202             . q{'} . $modes->{_symbol_table}->{_namespace} . q{'}
203             . ', subroutine/method '
204             . q{'} . $modes->{_symbol_table}->{_subroutine} . q{()'}
205             . ', dying' . "\n";
206             }
207             $modes->{_symbol_table}->{ $modes->{_symbol_table}->{_namespace} }->{ $modes->{_symbol_table}->{_subroutine} }->{$symbol}
208             = { isa => 'RPerl::Operation::Expression::SubExpression::Variable', type => $type };
209              
210             $rperl_source_group->{PMC} .= $my . q{ } . $type . q{ } . $symbol . $arrow_left_bracket . q{ };
211             $rperl_source_subgroup = $subexpression->ast_to_rperl__generate($modes);
212             RPerl::Generator::source_group_append( $rperl_source_group, $rperl_source_subgroup );
213             $rperl_source_group->{PMC} .= q{ } . $right_bracket . q{ } . $assign . q{ } . $undef . $semicolon . "\n";
214             }
215             elsif ( $self_class eq 'VariableDeclaration_184' ) { # VariableDeclaration -> MY TYPE_FHREF FHREF_SYMBOL ';'
216             my string $my = $self->{children}->[0];
217             my string $type_fhref = $self->{children}->[1];
218             my string $symbol_fhref = $self->{children}->[2];
219             my string $semicolon = $self->{children}->[3];
220              
221             # CREATE SYMBOL TABLE ENTRY
222             if ( exists $modes->{_symbol_table}->{ $modes->{_symbol_table}->{_namespace} }->{ $modes->{_symbol_table}->{_subroutine} }->{$symbol_fhref} ) {
223             die 'ERROR ECOGEASRP12, CODE GENERATOR, ABSTRACT SYNTAX TO RPERL: variable '
224             . $symbol_fhref
225             . ' already declared in this scope, namespace '
226             . q{'} . $modes->{_symbol_table}->{_namespace} . q{'}
227             . ', subroutine/method '
228             . q{'} . $modes->{_symbol_table}->{_subroutine} . q{()'}
229             . ', dying' . "\n";
230             }
231             $modes->{_symbol_table}->{ $modes->{_symbol_table}->{_namespace} }->{ $modes->{_symbol_table}->{_subroutine} }->{$symbol_fhref}
232             = { isa => 'RPerl::Operation::Expression::SubExpression::Variable', type => $type_fhref };
233              
234             $rperl_source_group->{PMC} .= $my . q{ } . $type_fhref . q{ } . $symbol_fhref . $semicolon . "\n";
235             }
236             else {
237             die RPerl::Parser::rperl_rule__replace( 'ERROR ECOGEASRP00, CODE GENERATOR, ABSTRACT SYNTAX TO RPERL: Grammar rule '
238             . $self_class
239             . ' found where VariableDeclaration_181, VariableDeclaration_182, VariableDeclaration_183, or VariableDeclaration_184 expected, dying' )
240             . "\n";
241             }
242              
243             return $rperl_source_group;
244             };
245              
246             our string_hashref::method $ast_to_cpp__generate__CPPOPS_PERLTYPES = sub {
247             ( my object $self, my string_hashref $modes) = @_;
248             my string_hashref $cpp_source_group = { CPP => q{// <<< RP::O::S::VD __DUMMY_SOURCE_CODE CPPOPS_PERLTYPES >>>} . "\n" };
249              
250             #...
251             return $cpp_source_group;
252             };
253              
254             our string_hashref::method $ast_to_cpp__generate__CPPOPS_CPPTYPES = sub {
255             ( my object $self, my string_hashref $modes) = @_;
256             my string_hashref $cpp_source_group = { CPP => q{} };
257             my string_hashref $cpp_source_subgroup;
258             my string $self_class = ref $self;
259              
260             # RPerl::diag( 'in VariableDeclaration->ast_to_cpp__generate__CPPOPS_CPPTYPES(), received $self = ' . "\n" . RPerl::Parser::rperl_ast__dump($self) . "\n" );
261              
262             # unwrap VariableDeclaration_181, VariableDeclaration_182, VariableDeclaration_183, and VariableDeclaration_184 from Statement_155
263             if ( $self_class eq 'Statement_155' ) { # Statement -> VariableDeclaration
264             $self = $self->{children}->[0];
265             $self_class = ref $self;
266             }
267              
268             if ( $self_class eq 'VariableDeclaration_181' ) { # VariableDeclaration -> MY Type VARIABLE_SYMBOL ';'
269             my string $type = $self->{children}->[1]->{children}->[0];
270             my string $symbol = $self->{children}->[2];
271             substr $symbol, 0, 1, q{}; # remove leading $ sigil
272              
273             # CREATE SYMBOL TABLE ENTRY
274             if ( exists $modes->{_symbol_table}->{ $modes->{_symbol_table}->{_namespace} }->{ $modes->{_symbol_table}->{_subroutine} }->{$symbol} ) {
275             die 'ERROR ECOGEASCP12, CODE GENERATOR, ABSTRACT SYNTAX TO C++: variable '
276             . $symbol
277             . ' already declared in this scope, namespace '
278             . q{'} . $modes->{_symbol_table}->{_namespace} . q{'}
279             . ', subroutine/method '
280             . q{'} . $modes->{_symbol_table}->{_subroutine} . q{()'}
281             . ', dying' . "\n";
282             }
283             $modes->{_symbol_table}->{ $modes->{_symbol_table}->{_namespace} }->{ $modes->{_symbol_table}->{_subroutine} }->{$symbol}
284             = { isa => 'RPerl::Operation::Expression::SubExpression::Variable', type => $type };
285              
286             $type = RPerl::Generator::type_convert_perl_to_cpp( $type, 1 ); # $pointerify_classes = 1
287             $modes->{_symbol_table}->{ $modes->{_symbol_table}->{_namespace} }->{ $modes->{_symbol_table}->{_subroutine} }->{$symbol}->{type_cpp} = $type; # add converted C++ type to symtab entry
288              
289             $cpp_source_group->{CPP} .= $type . q{ } . $symbol . ';' . "\n";
290             }
291             elsif ( $self_class eq 'VariableDeclaration_182' ) { # VariableDeclaration -> MY Type VARIABLE_SYMBOL OP19_VARIABLE_ASSIGN OpNamedScolonOrSubExpIn
292             my string $type = $self->{children}->[1]->{children}->[0];
293             my string $symbol = $self->{children}->[2];
294             my string $assign = $self->{children}->[3];
295             my object $opnamed_or_subexp_or_input_scolon = $self->{children}->[4];
296              
297             # RPerl::diag( 'in VariableDeclaration->ast_to_cpp__generate__CPPOPS_CPPTYPES(), have $opnamed_or_subexp_or_input_scolon = ' . "\n" . RPerl::Parser::rperl_ast__dump($opnamed_or_subexp_or_input_scolon) . "\n" );
298              
299             substr $symbol, 0, 1, q{}; # remove leading $ sigil
300             my boolean $is_constructor_call_normal = 0;
301             my boolean $is_constructor_call_special = 0;
302              
303             my string $opnamed_or_subexp_or_input_scolon_type = ref $opnamed_or_subexp_or_input_scolon;
304              
305             # RPerl::diag( 'in VariableDeclaration->ast_to_cpp__generate__CPPOPS_CPPTYPES(), have $opnamed_or_subexp_or_input_scolon_type = ' . "\n" . RPerl::Parser::rperl_ast__dump($opnamed_or_subexp_or_input_scolon_type) . "\n" );
306              
307             if ( ( $opnamed_or_subexp_or_input_scolon_type eq 'OpNamedScolonOrSubExpIn_239' )
308             or ( $opnamed_or_subexp_or_input_scolon_type eq 'OpNamedScolonOrSubExpIn_240' ) )
309             {
310             # OpNamedScolonOrSubExpIn -> OP01_NAMED_SCOLON
311             # OpNamedScolonOrSubExpIn -> OP10_NAMED_UNARY_SCOLON
312             $cpp_source_group->{CPP} .= $opnamed_or_subexp_or_input_scolon->{children}->[0];
313             }
314             elsif ( $opnamed_or_subexp_or_input_scolon_type eq 'OpNamedScolonOrSubExpIn_241' ) { # OpNamedScolonOrSubExpIn -> SubExpressionOrInput ';'
315             if ( ( exists $opnamed_or_subexp_or_input_scolon->{children} )
316             and ( exists $opnamed_or_subexp_or_input_scolon->{children}->[0] )
317             and ( blessed( $opnamed_or_subexp_or_input_scolon->{children}->[0] ) )
318             and ( exists $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children} )
319             and ( exists $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children}->[0] )
320             and ( blessed( $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children}->[0] ) )
321             and ( exists $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children}->[0]->{children} )
322             and ( exists $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children}->[0]->{children}->[0] )
323             and ( blessed( $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children}->[0]->{children}->[0] ) )
324             and ( $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children}->[0]->{children}->[0]
325             ->isa('RPerl::Operation::Expression::SubroutineCall::MethodCall::ConstructorCall') )
326             )
327             {
328             $is_constructor_call_normal = 1;
329             my string $constructor_type
330             = $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children}->[0]->{children}->[0]->{children}->[0]->{children}->[0];
331              
332             # RPerl::diag( 'in VariableDeclaration->ast_to_cpp__generate__CPPOPS_CPPTYPES(), have $constructor_type = ' . "\n" . RPerl::Parser::rperl_ast__dump($constructor_type) . "\n" );
333              
334             if ( $type ne $constructor_type ) {
335             die RPerl::Parser::rperl_rule__replace( 'ERROR ECOGEASCP20, CODE GENERATOR, ABSTRACT SYNTAX TO C++: data type mismatch, ' . q{'}
336             . $type . q{'}
337             . ' type is different than ' . q{'}
338             . $constructor_type . q{'}
339             . ' constructor type, dying' )
340             . "\n";
341             }
342             }
343             elsif (
344             ( exists $opnamed_or_subexp_or_input_scolon->{children} )
345             and ( exists $opnamed_or_subexp_or_input_scolon->{children}->[0] )
346             and ( blessed( $opnamed_or_subexp_or_input_scolon->{children}->[0] ) )
347             and ( exists $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children} )
348             and ( exists $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children}->[0] )
349             and ( blessed( $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children}->[0] ) )
350             and ( exists $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children}->[0]->{children} )
351             and ( exists $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children}->[0]->{children}->[0] )
352             and ( blessed( $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children}->[0]->{children}->[0] ) )
353             and ( $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children}->[0]->{children}->[0]->isa('RPerl::Operation::Expression::SubroutineCall') ) )
354             {
355             my string $constructor_name
356             = $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children}->[0]->{children}->[0]->{children}->[0]->{children}->[0];
357             if ( $constructor_name =~ m/::new$/xms ) {
358             $is_constructor_call_special = 1;
359             # RPerl::diag( 'in VariableDeclaration->ast_to_cpp__generate__CPPOPS_CPPTYPES(), have $constructor_name = ' . $constructor_name . "\n" );
360             my string $constructor_type = substr $constructor_name, 0, ( ( length $constructor_name ) - 5 );
361             # RPerl::diag( 'in VariableDeclaration->ast_to_cpp__generate__CPPOPS_CPPTYPES(), have $constructor_type = ' . $constructor_type . "\n" );
362              
363             if ( $type ne $constructor_type ) {
364             die RPerl::Parser::rperl_rule__replace( 'ERROR ECOGEASCP20, CODE GENERATOR, ABSTRACT SYNTAX TO C++: data type mismatch, ' . q{'}
365             . $type . q{'}
366             . ' type is different than ' . q{'}
367             . $constructor_type . q{'}
368             . ' constructor type, dying' )
369             . "\n";
370             }
371             }
372             }
373              
374             # CREATE SYMBOL TABLE ENTRY
375             # in a *.pl program, you can have variables declared outside of any namespace, which means they are in the default 'main::' namespace AKA '::' using Perl rules
376             if ((not exists $modes->{_symbol_table}->{_namespace}) or (not defined $modes->{_symbol_table}->{_namespace})) {
377             $modes->{_symbol_table}->{_namespace} = 'main::';
378             }
379              
380             # in a *.pl program, you can have variables declared outside of any subroutine, which means they are in the default 'main()' subroutine using C++ rules
381             if ((not exists $modes->{_symbol_table}->{_subroutine}) or (not defined $modes->{_symbol_table}->{_subroutine})) {
382             $modes->{_symbol_table}->{_subroutine} = 'main';
383             }
384              
385             # RPerl::diag('in VariableDeclaration->ast_to_cpp__generate__CPPOPS_CPPTYPES(), have $symbol = ' . $symbol . "\n");
386             # RPerl::diag('in VariableDeclaration->ast_to_cpp__generate__CPPOPS_CPPTYPES(), have $modes->{_symbol_table} = ' . Dumper($modes->{_symbol_table}) . "\n");
387             # RPerl::diag('in VariableDeclaration->ast_to_cpp__generate__CPPOPS_CPPTYPES(), have $modes->{_symbol_table}->{_namespace} = ' . $modes->{_symbol_table}->{_namespace} . "\n");
388             # RPerl::diag('in VariableDeclaration->ast_to_cpp__generate__CPPOPS_CPPTYPES(), have $modes->{_symbol_table}->{_subroutine} = ' . $modes->{_symbol_table}->{_subroutine} . "\n");
389              
390             if ( exists $modes->{_symbol_table}->{ $modes->{_symbol_table}->{_namespace} }->{ $modes->{_symbol_table}->{_subroutine} }->{$symbol} ) {
391             die 'ERROR ECOGEASCP12, CODE GENERATOR, ABSTRACT SYNTAX TO C++: variable '
392             . $symbol
393             . ' already declared in this scope, namespace '
394             . q{'} . $modes->{_symbol_table}->{_namespace} . q{'}
395             . ', subroutine/method '
396             . q{'} . $modes->{_symbol_table}->{_subroutine} . q{()'}
397             . ', dying' . "\n";
398             }
399             $modes->{_symbol_table}->{ $modes->{_symbol_table}->{_namespace} }->{ $modes->{_symbol_table}->{_subroutine} }->{$symbol}
400             = { isa => 'RPerl::Operation::Expression::SubExpression::Variable', type => $type };
401              
402             $type = RPerl::Generator::type_convert_perl_to_cpp( $type, 1 ); # $pointerify_classes = 1
403             $modes->{_symbol_table}->{ $modes->{_symbol_table}->{_namespace} }->{ $modes->{_symbol_table}->{_subroutine} }->{$symbol}->{type_cpp} = $type; # add converted C++ type to symtab entry
404              
405             $cpp_source_group->{CPP} .= $type . q{ } . $symbol;
406              
407             if ($is_constructor_call_normal) {
408             if ( not exists $rperlnamespaces_generated::RPERL->{ $type . '::' } ) { # not scalar or SSE number pair
409             $cpp_source_group->{CPP} .= '(';
410             $cpp_source_subgroup = $opnamed_or_subexp_or_input_scolon->{children}->[0]->ast_to_cpp__generate__CPPOPS_CPPTYPES($modes); # subexpression
411             RPerl::Generator::source_group_append( $cpp_source_group, $cpp_source_subgroup );
412             $cpp_source_group->{CPP} .= ')';
413             }
414             # purposefully do nothing here, no code needed
415             }
416             elsif ($is_constructor_call_special) {
417             if ( exists $rperlnamespaces_generated::RPERL->{ $type . '::' } ) {
418             if (($type eq 'integer_arrayref_arrayref') or ($type eq 'number_arrayref_arrayref') or ($type eq 'string_arrayref_arrayref')) {
419             my string $base_type = (split /_/, $type)[0];
420             # RPerl::diag( 'in VariableDeclaration->ast_to_cpp__generate__CPPOPS_CPPTYPES(), have $base_type = ' . $base_type . "\n" );
421             $cpp_source_group->{CPP} .= '(';
422             if (not exists $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children}->[0]->{children}->[0]->{children}->[2]->{children}->[0]->{children}->[0]->{children}->[0]->{children}->[0]->{children}->[0]->{children}->[0]) {
423             die 'ERROR ECOGEASCP60, CODE GENERATOR, ABSTRACT SYNTAX TO C++: first argument missing, constructor for type ' . $type . ', dying' . "\n";
424             }
425             elsif (not exists $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children}->[0]->{children}->[0]->{children}->[2]->{children}->[0]->{children}->[1]->{children}->[1]->{children}->[0]->{children}->[0]->{children}->[0]->{children}->[0]) {
426             die 'ERROR ECOGEASCP61, CODE GENERATOR, ABSTRACT SYNTAX TO C++: second argument missing, constructor for type ' . $type . ', dying' . "\n";
427             }
428             my string $row_count_argument = $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children}->[0]->{children}->[0]->{children}->[2]->{children}->[0]->{children}->[0]->{children}->[0]->{children}->[0]->{children}->[0]->{children}->[0];
429             substr $row_count_argument, 0, 1, q{}; # remove leading '$' sigil
430             $cpp_source_group->{CPP} .= $row_count_argument . ', ' . $base_type . '_arrayref(';
431             # RPerl::diag( 'in VariableDeclaration->ast_to_cpp__generate__CPPOPS_CPPTYPES(), have $opnamed_or_subexp_or_input_scolon->... = ' . "\n" . RPerl::Parser::rperl_ast__dump($opnamed_or_subexp_or_input_scolon->{children}->[0]->{children}->[0]->{children}->[0]->{children}->[2]->{children}->[0]->{children}->[1]->{children}->[1]->{children}->[0]->{children}->[0]->{children}->[0]->{children}->[0]) . "\n" );
432             my string $column_count_argument = $opnamed_or_subexp_or_input_scolon->{children}->[0]->{children}->[0]->{children}->[0]->{children}->[2]->{children}->[0]->{children}->[1]->{children}->[1]->{children}->[0]->{children}->[0]->{children}->[0]->{children}->[0];
433             substr $column_count_argument, 0, 1, q{}; # remove leading '$' sigil
434             $cpp_source_group->{CPP} .= $column_count_argument . '))';
435             }
436             else {
437             die 'ERROR ECOGEASCP62, CODE GENERATOR, ABSTRACT SYNTAX TO C++: constructor called for recognized but currently unsupported type ' . $type . ', dying' . "\n";
438             }
439             }
440             else {
441             die 'ERROR ECOGEASCP63, CODE GENERATOR, ABSTRACT SYNTAX TO C++: constructor called for unrecognized type ' . $type . ', dying' . "\n";
442             }
443             }
444             else {
445              
446             my $subexpression = $opnamed_or_subexp_or_input_scolon->{children}->[0];
447             # RPerl::diag( 'in VariableDeclaration->ast_to_cpp__generate__CPPOPS_CPPTYPES(), have $subexpression = ' . "\n" . RPerl::Parser::rperl_ast__dump($subexpression) . "\n" );
448             # RPerl::diag( 'in VariableDeclaration->ast_to_cpp__generate__CPPOPS_CPPTYPES(), have (ref $subexpression) = ' . (ref $subexpression) . "\n" );
449             # RPerl::diag( 'in VariableDeclaration->ast_to_cpp__generate__CPPOPS_CPPTYPES(), have (ref $subexpression->{children}->[0]) = ' . (ref $subexpression->{children}->[0]) . "\n" );
450             # RPerl::diag( 'in VariableDeclaration->ast_to_cpp__generate__CPPOPS_CPPTYPES(), have (ref $subexpression->{children}->[0]->{children}->[0]) = ' . (ref $subexpression->{children}->[0]->{children}->[0]) . "\n" );
451             # RPerl::diag( 'in VariableDeclaration->ast_to_cpp__generate__CPPOPS_CPPTYPES(), have (ref $subexpression->{children}->[0]->{children}->[0]->{children}->[1]) = ' . (ref $subexpression->{children}->[0]->{children}->[0]->{children}->[1]) . "\n" );
452             # RPerl::diag( 'in VariableDeclaration->ast_to_cpp__generate__CPPOPS_CPPTYPES(), have $subexpression->{children}->[0]->{children}->[0]->{children}->[1]->{children} = ' . "\n" . $subexpression->{children}->[0]->{children}->[0]->{children}->[1]->{children} . "\n" );
453             # RPerl::diag( 'in VariableDeclaration->ast_to_cpp__generate__CPPOPS_CPPTYPES(), have $subexpression->{children}->[0]->{children}->[0]->{children}->[1]->{children} = ' . "\n" . Dumper($subexpression->{children}->[0]->{children}->[0]->{children}->[1]->{children}) . "\n" );
454             # RPerl::diag( 'in VariableDeclaration->ast_to_cpp__generate__CPPOPS_CPPTYPES(), have scalar @{$subexpression->{children}->[0]->{children}->[0]->{children}->[1]->{children}} = ' . "\n" . (scalar @{$subexpression->{children}->[0]->{children}->[0]->{children}->[1]->{children}}) . "\n" );
455              
456             # test for empty array ref as value for variable initialization, discard in C++
457             if (
458             (blessed $subexpression) and
459             ((ref $subexpression) eq 'SubExpressionOrInput_144') and
460             (exists $subexpression->{children}) and
461             (defined $subexpression->{children}) and
462             (defined $subexpression->{children}->[0]) and
463             (blessed $subexpression->{children}->[0]) and
464             ((ref $subexpression->{children}->[0]) eq 'SubExpression_139') and
465             (exists $subexpression->{children}->[0]->{children}) and
466             (defined $subexpression->{children}->[0]->{children}) and
467             (defined $subexpression->{children}->[0]->{children}->[0]) and
468             (blessed $subexpression->{children}->[0]->{children}->[0]) and
469             ((ref $subexpression->{children}->[0]->{children}->[0]) eq 'ArrayReference_197') and
470             (exists $subexpression->{children}->[0]->{children}->[0]->{children}) and
471             (defined $subexpression->{children}->[0]->{children}->[0]->{children}) and
472             (defined $subexpression->{children}->[0]->{children}->[0]->{children}->[0]) and
473             ( $subexpression->{children}->[0]->{children}->[0]->{children}->[0] eq '[') and
474             (defined $subexpression->{children}->[0]->{children}->[0]->{children}->[1]) and
475             (blessed $subexpression->{children}->[0]->{children}->[0]->{children}->[1]) and
476             ((ref $subexpression->{children}->[0]->{children}->[0]->{children}->[1]) eq '_OPTIONAL') and
477             (exists $subexpression->{children}->[0]->{children}->[0]->{children}->[1]->{children}) and
478             (defined $subexpression->{children}->[0]->{children}->[0]->{children}->[1]->{children}) and
479             ((scalar @{$subexpression->{children}->[0]->{children}->[0]->{children}->[1]->{children}}) == 0) and
480             (defined $subexpression->{children}->[0]->{children}->[0]->{children}->[2]) and
481             ( $subexpression->{children}->[0]->{children}->[0]->{children}->[2] eq ']')
482             ) {
483             # RPerl::diag( 'in VariableDeclaration->ast_to_cpp__generate__CPPOPS_CPPTYPES(), have empty array ref' . "\n");
484             1; # do nothing
485             }
486             else {
487             $cpp_source_group->{CPP} .= q{ } . $assign . q{ };
488             $cpp_source_subgroup = $opnamed_or_subexp_or_input_scolon->{children}->[0]->ast_to_cpp__generate__CPPOPS_CPPTYPES($modes); # subexpression
489             RPerl::Generator::source_group_append( $cpp_source_group, $cpp_source_subgroup );
490             }
491             }
492             $cpp_source_group->{CPP} .= $opnamed_or_subexp_or_input_scolon->{children}->[1]; # semicolon
493             }
494             else {
495             die RPerl::Parser::rperl_rule__replace( 'ERROR ECOGEASCP00, CODE GENERATOR, ABSTRACT SYNTAX TO C++: Grammar rule '
496             . $opnamed_or_subexp_or_input_scolon_type
497             . ' found where OpNamedScolonOrSubExpIn_239, OpNamedScolonOrSubExpIn_240, or OpNamedScolonOrSubExpIn_241 expected, dying' )
498             . "\n";
499             }
500              
501             $cpp_source_group->{CPP} .= "\n";
502             }
503             elsif ( $self_class eq 'VariableDeclaration_183' ) { # VariableDeclaration -> MY Type VARIABLE_SYMBOL OP02_ARRAY_THINARROW SubExpression ']' OP19_VARIABLE_ASSIGN 'undef' ';'
504             my string $type = $self->{children}->[1]->{children}->[0];
505             my string $symbol = $self->{children}->[2];
506             my object $subexpression = $self->{children}->[4];
507             my string $semicolon = $self->{children}->[8];
508              
509             substr $symbol, 0, 1, q{}; # remove leading $ sigil
510              
511             # RPerl::diag( 'in VariableDeclaration->ast_to_cpp__generate__CPPOPS_CPPTYPES(), have $subexpression = ' . RPerl::Parser::rperl_ast__dump($subexpression) . "\n" );
512              
513             # CREATE SYMBOL TABLE ENTRY
514             if ( exists $modes->{_symbol_table}->{ $modes->{_symbol_table}->{_namespace} }->{ $modes->{_symbol_table}->{_subroutine} }->{$symbol} ) {
515             die 'ERROR ECOGEASCP12, CODE GENERATOR, ABSTRACT SYNTAX TO C++: variable '
516             . $symbol
517             . ' already declared in this scope, namespace '
518             . q{'} . $modes->{_symbol_table}->{_namespace} . q{'}
519             . ', subroutine/method '
520             . q{'} . $modes->{_symbol_table}->{_subroutine} . q{()'}
521             . ', dying' . "\n";
522             }
523             $modes->{_symbol_table}->{ $modes->{_symbol_table}->{_namespace} }->{ $modes->{_symbol_table}->{_subroutine} }->{$symbol}
524             = { isa => 'RPerl::Operation::Expression::SubExpression::Variable', type => $type };
525              
526             $type = RPerl::Generator::type_convert_perl_to_cpp( $type, 1 ); # $pointerify_classes = 1
527             $modes->{_symbol_table}->{ $modes->{_symbol_table}->{_namespace} }->{ $modes->{_symbol_table}->{_subroutine} }->{$symbol}->{type_cpp} = $type; # add converted C++ type to symtab entry
528              
529             my string $subexpression_address = "$subexpression";
530              
531             # POSSIBLE COMPILE-TIME OPTIMIZATION #01: avoids compensation addition below
532             $subexpression = RPerl::Generator::arrayref_convert_index_max_to_size($subexpression);
533              
534             $cpp_source_group->{CPP} .= $type . q{ } . $symbol . $semicolon . "\n";
535             $cpp_source_group->{CPP} .= $symbol . q{.resize(};
536             $cpp_source_subgroup = $subexpression->ast_to_cpp__generate__CPPOPS_CPPTYPES($modes);
537             if ( $subexpression_address eq "$subexpression" ) { # not compensated automatically, must compensate manually
538             # 'foo() * $bar' becomes '(foo() * $bar) + 1'
539             $cpp_source_subgroup->{CPP} = q{(} . $cpp_source_subgroup->{CPP} . q{) + 1};
540             }
541             RPerl::Generator::source_group_append( $cpp_source_group, $cpp_source_subgroup );
542             $cpp_source_group->{CPP} .= q{)} . $semicolon . "\n";
543             }
544             elsif ( $self_class eq 'VariableDeclaration_184' ) { # VariableDeclaration -> MY TYPE_FHREF FHREF_SYMBOL ';'
545             my string $type_fhref = $self->{children}->[1];
546             my string $symbol_fhref = $self->{children}->[2];
547             substr $symbol_fhref, 0, 1, q{}; # remove leading $ sigil
548              
549             # CREATE SYMBOL TABLE ENTRY
550             if ( exists $modes->{_symbol_table}->{ $modes->{_symbol_table}->{_namespace} }->{ $modes->{_symbol_table}->{_subroutine} }->{$symbol_fhref} ) {
551             die 'ERROR ECOGEASCP12, CODE GENERATOR, ABSTRACT SYNTAX TO C++: variable '
552             . $symbol_fhref
553             . ' already declared in this scope, namespace '
554             . q{'} . $modes->{_symbol_table}->{_namespace} . q{'}
555             . ', subroutine/method '
556             . q{'} . $modes->{_symbol_table}->{_subroutine} . q{()'}
557             . ', dying' . "\n";
558             }
559             $modes->{_symbol_table}->{ $modes->{_symbol_table}->{_namespace} }->{ $modes->{_symbol_table}->{_subroutine} }->{$symbol_fhref}
560             = { isa => 'RPerl::Operation::Expression::SubExpression::Variable', type => $type_fhref };
561              
562             # NEED ANSWER: should we enable type_convert_perl_to_cpp() for future use of constant_filehandleref type?
563             # $type_fhref = RPerl::Generator::type_convert_perl_to_cpp($type_fhref, 1); # $pointerify_classes = 1
564             $modes->{_symbol_table}->{ $modes->{_symbol_table}->{_namespace} }->{ $modes->{_symbol_table}->{_subroutine} }->{$symbol_fhref}->{type_cpp}
565             = $type_fhref; # add converted C++ type to symtab entry
566              
567             $cpp_source_group->{CPP} .= $type_fhref . q{ } . $symbol_fhref . ';' . "\n";
568             }
569             else {
570             die RPerl::Parser::rperl_rule__replace( 'ERROR ECOGEASCP00, CODE GENERATOR, ABSTRACT SYNTAX TO C++: Grammar rule '
571             . $self_class
572             . ' found where VariableDeclaration_181, VariableDeclaration_182, VariableDeclaration_183, or VariableDeclaration_184 expected, dying' )
573             . "\n";
574             }
575              
576             return $cpp_source_group;
577             };
578              
579             1; # end of class