File Coverage

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