File Coverage

blib/lib/RPerl/Operation/Expression/SubExpression/Variable.pm
Criterion Covered Total %
statement 58 109 53.2
branch 10 46 21.7
condition 10 30 33.3
subroutine 7 8 87.5
pod n/a
total 85 193 44.0


line stmt bran cond sub pod time code
1             # [[[ HEADER ]]]
2             package RPerl::Operation::Expression::SubExpression::Variable;
3 3     3   17 use strict;
  3         5  
  3         71  
4 3     3   15 use warnings;
  3         5  
  3         60  
5 3     3   16 use RPerl::AfterSubclass;
  3         3  
  3         383  
6             our $VERSION = 0.009_000;
7              
8             # [[[ OO INHERITANCE ]]]
9 3     3   20 use parent qw(RPerl::Operation::Expression::SubExpression);
  3         7  
  3         14  
10 3     3   136 use RPerl::Operation::Expression::SubExpression;
  3         8  
  3         4024  
11              
12             # [[[ OO PROPERTIES ]]]
13             our hashref $properties = {};
14              
15             # [[[ SUBROUTINES & OO METHODS ]]]
16              
17             sub ast_to_rperl__generate {
18 1711     1711   3201 { my string_hashref::method $RETURN_TYPE };
  1711         2730  
19 1711         3899 ( my object $self, my string_hashref $modes) = @ARG;
20 1711         4534 my string_hashref $rperl_source_group = { PMC => q{} };
21              
22             # RPerl::diag( 'in Variable->ast_to_rperl__generate(), received $self = ' . "\n" . RPerl::Parser::rperl_ast__dump($self) . "\n" );
23              
24 1711         4195 my string $self_class = ref $self;
25              
26             # unwrap Variable_191 from SubExpression_152, VariableOrLiteral_241, or VarOrLitOrOpStrOrWord_243
27 1711 100 100     8389 if ( ( $self_class eq 'SubExpression_152' ) or ( $self_class eq 'VariableOrLiteral_241' ) or ( $self_class eq 'VarOrLitOrOpStrOrWord_243' ) ) {
      100        
28 1254         4001 $self = $self->{children}->[0];
29             }
30              
31 1711         3561 $self_class = ref $self;
32 1711 50       4111 if ( $self_class eq 'Variable_191' ) {
33              
34             # Variable -> VariableSymbolOrSelf VariableRetrieval*
35 1711         6111 my string $symbol_or_self = $self->{children}->[0]->{children}->[0];
36 1711         4292 $rperl_source_group->{PMC} .= $symbol_or_self;
37              
38 1711         2843 foreach my object $variable_retrieval ( @{ $self->{children}->[1]->{children} } ) {
  1711         6457  
39 158         3196 my string_hashref $rperl_source_subgroup = $variable_retrieval->ast_to_rperl__generate($modes);
40 158         2981 RPerl::Generator::source_group_append( $rperl_source_group, $rperl_source_subgroup );
41             }
42             }
43             else {
44 0         0 die RPerl::Parser::rperl_rule__replace( 'ERROR ECOGEASRP00, CODE GENERATOR, ABSTRACT SYNTAX TO RPERL: Grammar rule '
45             . ($self_class)
46             . ' found where SubExpression_152, VariableOrLiteral_241, VarOrLitOrOpStrOrWord_243, or Variable_191 expected, dying' )
47             . "\n";
48             }
49 1711         8155 return $rperl_source_group;
50             }
51              
52             sub ast_to_cpp__generate__CPPOPS_PERLTYPES {
53 0     0   0 { my string_hashref::method $RETURN_TYPE };
  0         0  
54 0         0 ( my object $self, my string_hashref $modes) = @ARG;
55 0         0 my string_hashref $cpp_source_group = { CPP => q{// <<< RP::O::E::SE::V __DUMMY_SOURCE_CODE CPPOPS_PERLTYPES >>>} . "\n" };
56              
57             #...
58 0         0 return $cpp_source_group;
59             }
60              
61             sub ast_to_cpp__generate__CPPOPS_CPPTYPES {
62 127     127   199 { my string_hashref::method $RETURN_TYPE };
  127         233  
63 127         265 ( my object $self, my string_hashref $modes) = @ARG;
64 127         317 my string_hashref $cpp_source_group = { CPP => q{} };
65              
66             # RPerl::diag( 'in Variable->ast_to_cpp__generate__CPPOPS_CPPTYPES(), received $self = ' . "\n" . RPerl::Parser::rperl_ast__dump($self) . "\n" );
67             # RPerl::diag( 'in Variable->ast_to_cpp__generate__CPPOPS_CPPTYPES(), received $modes = ' . Dumper($modes) . "\n" );
68              
69 127         270 my string $self_class = ref $self;
70              
71             # unwrap Variable_191 from SubExpression_152, VariableOrLiteral_241, or VarOrLitOrOpStrOrWord_243
72 127 50 66     500 if ( ( $self_class eq 'SubExpression_152' ) or ( $self_class eq 'VariableOrLiteral_241' ) or ( $self_class eq 'VarOrLitOrOpStrOrWord_243' ) ) {
      66        
73 92         245 $self = $self->{children}->[0];
74             }
75              
76 127         253 $self_class = ref $self;
77 127 50       298 if ( $self_class eq 'Variable_191' ) {
78              
79             # Variable -> VariableSymbolOrSelf VariableRetrieval*
80 127         449 my string $symbol_or_self = $self->{children}->[0]->{children}->[0];
81 127         225 my string_arrayref $types = [];
82              
83             # RPerl::diag( 'in Variable->ast_to_cpp__generate__CPPOPS_CPPTYPES(), have pre-modification $symbol_or_self = ' . $symbol_or_self . "\n" );
84              
85 127         306 substr $symbol_or_self, 0, 1, q{}; # remove leading $ sigil
86              
87             # determine first type
88 127 100       269 if ( $symbol_or_self eq 'self' ) {
89 20         37 $symbol_or_self = 'this'; # Perl OO $self becomes C++ OO this
90 20         58 $types->[0] = $modes->{_symbol_table}->{_namespace};
91             }
92             else {
93             # variable retrieval (individual or multiple chained) can only be initiated from a variable, which must be in the symtab, in a namespace, in a subroutine
94             $types->[0]
95 107         438 = $modes->{_symbol_table}->{ $modes->{_symbol_table}->{_namespace} }->{ $modes->{_symbol_table}->{_subroutine} }->{$symbol_or_self}->{type};
96             }
97              
98             # RPerl::diag( 'in Variable->ast_to_cpp__generate__CPPOPS_CPPTYPES(), have post-modification $symbol_or_self = ' . $symbol_or_self . "\n" );
99              
100 127         286 $cpp_source_group->{CPP} = $symbol_or_self;
101 127         213 my integer $i_max = ( scalar @{ $self->{children}->[1]->{children} } ) - 1;
  127         362  
102 127         404 for my integer $i ( 0 .. $i_max ) {
103 32         68 my object $variable_retrieval = $self->{children}->[1]->{children}->[$i];
104             # RPerl::diag( 'in Variable->ast_to_cpp__generate__CPPOPS_CPPTYPES(), for loop $i = ' . $i . ', have $types->[$i] = ' . $types->[$i] . "\n" );
105             # RPerl::diag( 'in Variable->ast_to_cpp__generate__CPPOPS_CPPTYPES(), for loop $i = ' . $i . ', have $variable_retrieval = ' . "\n" . RPerl::Parser::rperl_ast__dump($variable_retrieval) . "\n" );
106              
107 32         667 my string_hashref $cpp_source_subgroup = $variable_retrieval->ast_to_cpp__generate__CPPOPS_CPPTYPES( $symbol_or_self, $types->[$i], $modes );
108 32         648 RPerl::Generator::source_group_append( $cpp_source_group, $cpp_source_subgroup );
109              
110             # determine next type
111 32 100       138 if ( $i < $i_max ) {
112 3 50       18 if ( $types->[$i] =~ /_arrayref$/ ) { # array
    0          
    0          
    0          
113 3         18 $types->[ $i + 1 ] = substr $types->[$i], 0, ( ( length $types->[$i] ) - 9 ); # strip trailing '_arrayref'
114             }
115             elsif ( $types->[$i] =~ /_hashref$/ ) { # hash
116 0         0 $types->[ $i + 1 ] = substr $types->[$i], 0, ( ( length $types->[$i] ) - 8 ); # strip trailing '_hashref'
117             }
118             elsif ( $types->[$i] =~ /sse_number_pair$/xms ) { # SSE number pair
119 0         0 $types->[ $i + 1 ] = 'number';
120             }
121             elsif ( exists $rperlnamespaces_generated::RPERL->{ $types->[$i] . '::' } ) { # scalar
122 0         0 die 'ERROR ECOGEASCP30, CODE GENERATOR, ABSTRACT SYNTAX TO C++: Variable retrieval, can not retrieve data subcomponent from scalar type ' . $types->[$i] . ', dying' . "\n";
123             }
124             else { # user-defined type AKA class
125 0 0       0 if ( ( ref $variable_retrieval ) eq 'VariableRetrieval_193' ) { # VariableRetrieval -> OP02_HASH_THINARROW SubExpression '}'
    0          
126 0         0 my object $subexpression = $variable_retrieval->{children}->[1];
127 0 0 0     0 if (( ( ref $subexpression ) eq 'SubExpression_151' ) # SubExpression -> Literal
      0        
128             or ( ( ref $subexpression ) eq 'VariableOrLiteral_242' ) # VariableOrLiteral -> Literal
129             or ( ( ref $subexpression ) eq 'VarOrLitOrOpStrOrWord_244' ) # VarOrLitOrOpStrOrWord -> Literal
130             )
131             {
132 0         0 my string $number_or_string_literal = $subexpression->{children}->[0]->{children}->[0];
133 0         0 $number_or_string_literal = eval "return $number_or_string_literal"; # strip quotations from string and underscores from number, etc.
134              
135 0 0       0 if ((substr $types->[$i], -2, 2) ne '::') { $types->[$i] .= '::'; } # _properties in _symbol_table are keyed by class/package names ending in ::
  0         0  
136             # RPerl::diag( 'in Variable->ast_to_cpp__generate__CPPOPS_CPPTYPES() #0, for loop $i = ' . $i . ', have $modes->{_symbol_table}->{ $types->[$i] }->{_properties} = ' . $modes->{_symbol_table}->{ $types->[$i] }->{_properties} . "\n" );
137              
138             # check if OO property exists in self class or parent class
139 0 0       0 if ( exists $modes->{_symbol_table}->{ $types->[$i] }->{_properties}->{$number_or_string_literal} ) {
140 0         0 $types->[ $i + 1 ] = $modes->{_symbol_table}->{ $types->[$i] }->{_properties}->{$number_or_string_literal}->{type};
141             }
142             else {
143 0         0 my $parent_package_names = RPerl::CompileUnit::Module::Class::parent_and_grandparent_package_names(substr $types->[$i], 0, -2);
144 0         0 my boolean $property_found = 0;
145 0         0 foreach my $parent_package_name (@{$parent_package_names}) {
  0         0  
146 0 0       0 if (exists $modes->{_symbol_table}->{ $parent_package_name . q{::} }->{_properties}->{$number_or_string_literal}) {
147 0         0 $types->[ $i + 1 ] = $modes->{_symbol_table}->{ $parent_package_name . q{::} }->{_properties}->{$number_or_string_literal}->{type};
148 0         0 $property_found = 1;
149 0         0 last;
150             }
151             }
152 0 0       0 if (not $property_found) {
153 0 0 0     0 if ((not exists $modes->{dependencies}) or
      0        
154             (not defined $modes->{dependencies}) or
155             ($modes->{dependencies} ne 'ON')) {
156 0         0 die 'ERROR ECOGEASCP31 #0, CODE GENERATOR, ABSTRACT SYNTAX TO C++: Variable retrieval, dependencies disabled, can not verify validity of OO property ' . $number_or_string_literal . ' in user-defined class ' . $types->[$i] . ', dying' . "\n";
157             }
158             else {
159 0         0 die 'ERROR ECOGEASCP32 #0, CODE GENERATOR, ABSTRACT SYNTAX TO C++: Variable retrieval, can not retrieve invalid OO property ' . $number_or_string_literal . ' in user-defined class ' . $types->[$i] . ', dying' . "\n";
160             }
161             }
162             }
163             }
164             else {
165 0         0 my string $subexpression_generated = ($subexpression->ast_to_cpp__generate__CPPOPS_CPPTYPES( $modes ))->{CPP};
166 0         0 die 'ERROR ECOGEASCP33, CODE GENERATOR, ABSTRACT SYNTAX TO C++: Variable retrieval, can not determine OO property name (and thus type) from non-literal subexpression...' . "\n" . $subexpression_generated . "\n" . '...in user-defined class ' . $types->[$i] . ', dying' . "\n";
167             }
168             }
169             elsif ( ( ref $variable_retrieval ) eq 'VariableRetrieval_194' ) { # VariableRetrieval -> OP02_HASH_THINARROW WORD '}'
170 0 0       0 if ((substr $types->[$i], -2, 2) ne '::') { $types->[$i] .= '::'; } # _properties in _symbol_table are keyed by class/package names ending in ::
  0         0  
171 0         0 my string $word = $variable_retrieval->{children}->[1];
172             # RPerl::diag( 'in Variable->ast_to_cpp__generate__CPPOPS_CPPTYPES() #1, for loop $i = ' . $i . ', have $word = ' . $word . "\n" );
173             # RPerl::diag( 'in Variable->ast_to_cpp__generate__CPPOPS_CPPTYPES() #1, for loop $i = ' . $i . ', have $types->[$i] = ' . $types->[$i] . "\n" );
174             # RPerl::diag( 'in Variable->ast_to_cpp__generate__CPPOPS_CPPTYPES() #1, for loop $i = ' . $i . ', have $modes->{_symbol_table} = ' . Dumper($modes->{_symbol_table}) . "\n" );
175             # RPerl::diag( 'in Variable->ast_to_cpp__generate__CPPOPS_CPPTYPES() #1, for loop $i = ' . $i . ', have $modes->{_symbol_table}->{ $types->[$i] } = ' . $modes->{_symbol_table}->{ $types->[$i] } . "\n" );
176             # RPerl::diag( 'in Variable->ast_to_cpp__generate__CPPOPS_CPPTYPES() #1, for loop $i = ' . $i . ', have $modes->{_symbol_table}->{ $types->[$i] }->{_properties} = ' . $modes->{_symbol_table}->{ $types->[$i] }->{_properties} . "\n" );
177              
178             # check if OO property exists in self class or parent class
179 0 0       0 if ( exists $modes->{_symbol_table}->{ $types->[$i] }->{_properties}->{$word} ) {
180 0         0 $types->[ $i + 1 ] = $modes->{_symbol_table}->{ $types->[$i] }->{_properties}->{$word}->{type};
181             }
182             else {
183 0         0 my $parent_package_names = RPerl::CompileUnit::Module::Class::parent_and_grandparent_package_names(substr $types->[$i], 0, -2);
184             # RPerl::diag( 'in Variable->ast_to_cpp__generate__CPPOPS_CPPTYPES(), for loop $i = ' . $i . ', have $parent_package_names = ' . Dumper($parent_package_names) . "\n" );
185 0         0 my boolean $property_found = 0;
186 0         0 foreach my $parent_package_name (@{$parent_package_names}) {
  0         0  
187             # RPerl::diag( 'in Variable->ast_to_cpp__generate__CPPOPS_CPPTYPES(), for loop $i = ' . $i . ', have $parent_package_name = ' . $parent_package_name . "\n" );
188             # RPerl::diag( 'in Variable->ast_to_cpp__generate__CPPOPS_CPPTYPES(), for loop $i = ' . $i . ', have $modes->{_symbol_table} = ' . Dumper($modes->{_symbol_table}) . "\n" );
189 0 0       0 if (exists $modes->{_symbol_table}->{ $parent_package_name . q{::} }->{_properties}->{$word}) {
190 0         0 $types->[ $i + 1 ] = $modes->{_symbol_table}->{ $parent_package_name . q{::} }->{_properties}->{$word}->{type};
191 0         0 $property_found = 1;
192 0         0 last;
193             }
194             }
195 0 0       0 if (not $property_found) {
196 0 0 0     0 if ((not exists $modes->{dependencies}) or
      0        
197             (not defined $modes->{dependencies}) or
198             ($modes->{dependencies} ne 'ON')) {
199 0         0 die 'ERROR ECOGEASCP31 #1, CODE GENERATOR, ABSTRACT SYNTAX TO C++: Variable retrieval, dependencies disabled, can not verify validity of OO property ' . $word . ' in user-defined class ' . $types->[$i] . ', dying' . "\n";
200             }
201             else {
202 0         0 die 'ERROR ECOGEASCP31 #2, CODE GENERATOR, ABSTRACT SYNTAX TO C++: Variable retrieval, can not retrieve invalid OO property ' . $word . ' in user-defined class ' . $types->[$i] . ', dying' . "\n";
203             }
204             }
205             }
206             }
207             else {
208 0         0 die 'ERROR ECOGEASCP34, CODE GENERATOR, ABSTRACT SYNTAX TO C++: Variable retrieval, can not use arrayref retrieval on object of user-defined class ' . $types->[$i] . ', dying' . "\n";
209             }
210             }
211             }
212             }
213             }
214             else {
215 0         0 die RPerl::Parser::rperl_rule__replace( 'ERROR ECOGEASCP00, CODE GENERATOR, ABSTRACT SYNTAX TO C++: Grammar rule '
216             . ($self_class)
217             . ' found where SubExpression_152, VariableOrLiteral_241, VarOrLitOrOpStrOrWord_243, or Variable_191 expected, dying' )
218             . "\n";
219             }
220 127         628 return $cpp_source_group;
221             }
222              
223             1; # end of class