File Coverage

blib/lib/RPerl/Operation/Statement/OperatorVoid/Named/Return.pm
Criterion Covered Total %
statement 30 30 100.0
branch n/a
condition n/a
subroutine 10 10 100.0
pod n/a
total 40 40 100.0


line stmt bran cond sub pod time code
1             # [[[ DOCUMENTATION ]]]
2             # http://perldoc.perl.org/functions/return.html
3             # SUPPORTED: return EXPR
4             # SUPPORTED: return
5              
6             # [[[ HEADER ]]]
7             package RPerl::Operation::Statement::OperatorVoid::Named::Return;
8 5     5   35 use strict;
  5         15  
  5         143  
9 5     5   30 use warnings;
  5         13  
  5         137  
10 5     5   30 use RPerl::AfterSubclass;
  5         13  
  5         788  
11             our $VERSION = 0.002_010;
12              
13             # [[[ OO INHERITANCE ]]]
14             # NEED FIX: is not a Grammar Rule so should not inherit from OperatorVoid, need create Grammar Production class
15 5     5   39 use parent qw(RPerl::Operation::Statement::OperatorVoid::Named);
  5         14  
  5         43  
16 5     5   211 use RPerl::Operation::Statement::OperatorVoid::Named;
  5         12  
  5         167  
17              
18             # [[[ CRITICS ]]]
19             ## no critic qw(ProhibitUselessNoCritic ProhibitMagicNumbers RequireCheckedSyscalls) # USER DEFAULT 1: allow numeric values & print operator
20             ## no critic qw(RequireInterpolationOfMetachars) # USER DEFAULT 2: allow single-quoted control characters & sigils
21             ## no critic qw(ProhibitConstantPragma ProhibitMagicNumbers) # USER DEFAULT 3: allow constants
22              
23             # [[[ CONSTANTS ]]]
24 5     5   30 use constant NAME_PERLOPS_PERLTYPES => my string $TYPED_NAME_PERLOPS_PERLTYPES = 'return';
  5         15  
  5         419  
25 5     5   35 use constant NAME_CPPOPS_PERLTYPES => my string $TYPED_NAME_CPPOPS_PERLTYPES = 'return';
  5         14  
  5         366  
26 5     5   35 use constant NAME_CPPOPS_CPPTYPES => my string $TYPED_NAME_CPPOPS_CPPTYPES = 'return';
  5         16  
  5         263  
27             # DEV NOTE: ARGUMENTS_MIN of 0 can be ignored, no such thing as negative number of args!
28 5     5   31 use constant ARGUMENTS_MIN => my integer $TYPED_ARGUMENTS_MIN = 0; # call 'return;' for all subroutines which return void
  5         15  
  5         302  
29 5     5   32 use constant ARGUMENTS_MAX => my integer $TYPED_ARGUMENTS_MAX = 1; # call 'return @{[ELEM0, ELEM1, ...]};' for all subroutines which return an array; disallow return(ELEM0, ELEM1, ...) multiple return values
  5         15  
  5         5493  
30              
31             # [[[ OO PROPERTIES ]]]
32             our hashref $properties = {};
33              
34             # [[[ SUBROUTINES & OO METHODS ]]]
35              
36             our string_hashref::method $ast_to_rperl__generate = sub {
37             ( my object $self,
38             my string_hashref $modes,
39             my object $operator_void_named)
40             = @_;
41             my string_hashref $rperl_source_group = { PMC => q{} };
42              
43             # RPerl::diag( 'in OperatorVoid::Named::Return->ast_to_rperl__generate(), received $self = ' . "\n" . RPerl::Parser::rperl_ast__dump($self) . "\n" );
44             # RPerl::diag( 'in OperatorVoid::Named::Return->ast_to_rperl__generate(), received $operator_void_named = ' . "\n" . RPerl::Parser::rperl_ast__dump($operator_void_named) . "\n" );
45              
46             if ( ref $operator_void_named eq 'OperatorVoid_119' ) { # OperatorVoid -> OP01_NAMED_VOID_SCOLON
47             $rperl_source_group->{PMC} .= $operator_void_named->{children}->[0]; # name semicolon
48             }
49             elsif ( ref $operator_void_named eq 'OperatorVoid_120' ) { # OperatorVoid -> OP01_NAMED_VOID_LPAREN OPTIONAL-32 ')' ';'
50              
51             # DEV NOTE: if $arguments_optional is empty, will generate 'return();' which perltidy will change to 'return ();', both return undef, not empty array, so it's okay
52             $rperl_source_group->{PMC}
53             .= $operator_void_named->{children}->[0]; # name lparen
54             my object $arguments_optional = $operator_void_named->{children}->[1];
55             if ( exists $arguments_optional->{children}->[0] ) {
56             my object $arguments = $arguments_optional->{children}->[0];
57             my integer $argument_count = $arguments->length();
58             if ( $argument_count > ARGUMENTS_MAX() ) {
59             die
60             'ERROR ECOGEASRP03, CODE GENERATOR, ABSTRACT SYNTAX TO RPERL:'
61             . "\n"
62             . 'Argument count '
63             . $argument_count
64             . ' exceeds maximum argument limit '
65             . ARGUMENTS_MAX()
66             . ' for operator ' . q{'}
67             . NAME_PERLOPS_PERLTYPES() . q{'}
68             . ', dying' . "\n";
69             }
70             # RPerl::diag( 'in OperatorVoid::Named::Return->ast_to_rperl__generate(), have $arguments = ' . "\n" . RPerl::Parser::rperl_ast__dump($arguments) . "\n" );
71             if ((( ref $arguments->{children}->[0] ) eq 'ListElement_191' ) and ( exists $arguments->{children}->[0]->{children}->[0] ))
72             {
73             my object $arguments_subexpression = $arguments->{children}->[0]->{children}->[0];
74             # look inside nested parenthesis-as-subexpressions, always length 1 so no need to check length
75             while ((ref $arguments_subexpression) eq 'SubExpression_143') { # RPerl::Operation::Expression::SubExpression::Parenthesis
76             $arguments_subexpression = $arguments_subexpression->{children}->[1];
77             }
78             if (( ref $arguments_subexpression ) eq 'SubExpression_140' ) {
79             die 'ERROR ECOGEASRP04, CODE GENERATOR, ABSTRACT SYNTAX TO RPERL:' . "\n" . 'Attempt to return dereferenced array, please return arrayref instead, dying' . "\n";
80             }
81             elsif (( ref $arguments_subexpression ) eq 'SubExpression_142' ) {
82             die 'ERROR ECOGEASRP05, CODE GENERATOR, ABSTRACT SYNTAX TO RPERL:' . "\n" . 'Attempt to return dereferenced hash, please return hashref instead, dying' . "\n";
83             }
84             }
85             my string_hashref $rperl_source_subgroup
86             = $arguments->ast_to_rperl__generate( $modes, $self );
87             RPerl::Generator::source_group_append( $rperl_source_group,
88             $rperl_source_subgroup );
89             }
90             $rperl_source_group->{PMC} .= $operator_void_named->{children}->[2]
91             . $operator_void_named->{children}->[3]; # rparen semicolon
92             }
93             elsif ( ref $operator_void_named eq 'OperatorVoid_121' ) { # OperatorVoid -> OP01_NAMED_VOID ListElements ';'
94             $rperl_source_group->{PMC}
95             .= $operator_void_named->{children}->[0] . q{ }; # name
96             my object $arguments = $operator_void_named->{children}->[1];
97             my integer $argument_count = $arguments->length();
98             if ( $argument_count > ARGUMENTS_MAX() ) {
99             die
100             'ERROR ECOGEASRP03, CODE GENERATOR, ABSTRACT SYNTAX TO RPERL:'
101             . "\n"
102             . 'Argument count '
103             . $argument_count
104             . ' exceeds maximum argument limit '
105             . ARGUMENTS_MAX()
106             . ' for operator ' . q{'}
107             . NAME_PERLOPS_PERLTYPES() . q{'}
108             . ', dying' . "\n";
109             }
110             # RPerl::diag( 'in OperatorVoid::Named::Return->ast_to_rperl__generate(), have $arguments = ' . "\n" . RPerl::Parser::rperl_ast__dump($arguments) . "\n" );
111             if ((( ref $arguments->{children}->[0] ) eq 'ListElement_191' ) and ( exists $arguments->{children}->[0]->{children}->[0] ))
112             {
113             my object $arguments_subexpression = $arguments->{children}->[0]->{children}->[0];
114             # look inside nested parenthesis-as-subexpressions, always length 1 so no need to check length
115             while ((ref $arguments_subexpression) eq 'SubExpression_143') { # RPerl::Operation::Expression::SubExpression::Parenthesis
116             $arguments_subexpression = $arguments_subexpression->{children}->[1];
117             }
118             if (( ref $arguments_subexpression ) eq 'SubExpression_140' ) {
119             die 'ERROR ECOGEASRP04, CODE GENERATOR, ABSTRACT SYNTAX TO RPERL:' . "\n" . 'Attempt to return dereferenced array, please return arrayref instead, dying' . "\n";
120             }
121             elsif (( ref $arguments_subexpression ) eq 'SubExpression_142' ) {
122             die 'ERROR ECOGEASRP05, CODE GENERATOR, ABSTRACT SYNTAX TO RPERL:' . "\n" . 'Attempt to return dereferenced hash, please return hashref instead, dying' . "\n";
123             }
124             }
125             my string_hashref $rperl_source_subgroup
126             = $arguments->ast_to_rperl__generate( $modes, $self );
127             RPerl::Generator::source_group_append( $rperl_source_group,
128             $rperl_source_subgroup );
129             $rperl_source_group->{PMC} .= $operator_void_named->{children}->[2]; # semicolon
130             }
131             else {
132             die RPerl::Parser::rperl_rule__replace(
133             'ERROR ECOGEASRP00, CODE GENERATOR, ABSTRACT SYNTAX TO RPERL: Grammar rule '
134             . ( ref $operator_void_named )
135             . ' found where OperatorVoid_119, OperatorVoid_120, or OperatorVoid_121 expected, dying'
136             ) . "\n";
137             }
138              
139             $rperl_source_group->{PMC} .= "\n";
140             return $rperl_source_group;
141             };
142              
143             our string_hashref::method $ast_to_cpp__generate__CPPOPS_PERLTYPES = sub {
144             ( my object $self, my string_hashref $modes) = @_;
145             my string_hashref $cpp_source_group
146             = { CPP =>
147             q{// <<< RP::O::S::OV::N::R __DUMMY_SOURCE_CODE CPPOPS_PERLTYPES >>>}
148             . "\n" };
149              
150             #...
151             return $cpp_source_group;
152             };
153              
154             # DEV NOTE: PERLOPS_PERLTYPES & CPPOPS_CPPTYPES code generation are exactly equivalent
155             our string_hashref::method $ast_to_cpp__generate__CPPOPS_CPPTYPES = sub {
156             ( my object $self,
157             my string_hashref $modes,
158             my object $operator_void_named)
159             = @_;
160             my string_hashref $cpp_source_group = { CPP => q{} };
161              
162             # RPerl::diag( 'in OperatorVoid::Named::Return->ast_to_cpp__generate__CPPOPS_CPPTYPES(), received $self = ' . "\n" . RPerl::Parser::rperl_ast__dump($self) . "\n" );
163             # RPerl::diag( 'in OperatorVoid::Named::Return->ast_to_cpp__generate__CPPOPS_CPPTYPES(), received $operator_void_named = ' . "\n" . RPerl::Parser::rperl_ast__dump($operator_void_named) . "\n" );
164              
165             if ( ref $operator_void_named eq 'OperatorVoid_119' ) { # OperatorVoid -> OP01_NAMED_VOID_SCOLON
166             $cpp_source_group->{CPP} .= $operator_void_named->{children}->[0]; # name semicolon
167             }
168             elsif ( ref $operator_void_named eq 'OperatorVoid_120' ) { # OperatorVoid -> OP01_NAMED_VOID_LPAREN OPTIONAL-32 ')' ';'
169              
170             # DEV NOTE: if $arguments_optional is empty, will generate 'return();' which perltidy will change to 'return ();', both return undef, not empty array, so it's okay
171             $cpp_source_group->{CPP}
172             .= $operator_void_named->{children}->[0]; # name lparen
173             my object $arguments_optional = $operator_void_named->{children}->[1];
174             if ( exists $arguments_optional->{children}->[0] ) {
175             my object $arguments = $arguments_optional->{children}->[0];
176             my integer $argument_count = $arguments->length();
177             if ( $argument_count > ARGUMENTS_MAX() ) {
178             die
179             'ERROR ECOGEASCP03, CODE GENERATOR, ABSTRACT SYNTAX TO C++:'
180             . "\n"
181             . 'Argument count '
182             . $argument_count
183             . ' exceeds maximum argument limit '
184             . ARGUMENTS_MAX()
185             . ' for operator ' . q{'}
186             . NAME_PERLOPS_PERLTYPES() . q{'}
187             . ', dying' . "\n";
188             }
189             # RPerl::diag( 'in OperatorVoid::Named::Return->ast_to_cpp__generate__CPPOPS_CPPTYPES(), have $arguments = ' . "\n" . RPerl::Parser::rperl_ast__dump($arguments) . "\n" );
190             if ((( ref $arguments->{children}->[0] ) eq 'ListElement_191' ) and ( exists $arguments->{children}->[0]->{children}->[0] ))
191             {
192             my object $arguments_subexpression = $arguments->{children}->[0]->{children}->[0];
193             # look inside nested parenthesis-as-subexpressions, always length 1 so no need to check length
194             while ((ref $arguments_subexpression) eq 'SubExpression_143') { # RPerl::Operation::Expression::SubExpression::Parenthesis
195             $arguments_subexpression = $arguments_subexpression->{children}->[1];
196             }
197             if (( ref $arguments_subexpression ) eq 'SubExpression_140' ) {
198             die 'ERROR ECOGEASCP04, CODE GENERATOR, ABSTRACT SYNTAX TO C++:' . "\n" . 'Attempt to return dereferenced array, please return arrayref instead, dying' . "\n";
199             }
200             elsif (( ref $arguments_subexpression ) eq 'SubExpression_142' ) {
201             die 'ERROR ECOGEASCP05, CODE GENERATOR, ABSTRACT SYNTAX TO C++:' . "\n" . 'Attempt to return dereferenced hash, please return hashref instead, dying' . "\n";
202             }
203             }
204             my string_hashref $cpp_source_subgroup
205             = $arguments->ast_to_cpp__generate__CPPOPS_CPPTYPES( $modes, $self );
206             # RPerl::diag( 'in OperatorVoid::Named::Return->ast_to_cpp__generate__CPPOPS_CPPTYPES(), have $cpp_source_subgroup = ' . "\n" . RPerl::Parser::rperl_ast__dump($cpp_source_subgroup) . "\n" );
207             RPerl::Generator::source_group_append( $cpp_source_group,
208             $cpp_source_subgroup );
209             }
210             $cpp_source_group->{CPP} .= $operator_void_named->{children}->[2]
211             . $operator_void_named->{children}->[3]; # rparen semicolon
212             }
213             elsif ( ref $operator_void_named eq 'OperatorVoid_121' ) { # OperatorVoid -> OP01_NAMED_VOID ListElements ';'
214             $cpp_source_group->{CPP}
215             .= $operator_void_named->{children}->[0] . q{ }; # name
216             my object $arguments = $operator_void_named->{children}->[1];
217             my integer $argument_count = $arguments->length();
218             if ( $argument_count > ARGUMENTS_MAX() ) {
219             die
220             'ERROR ECOGEASCP03, CODE GENERATOR, ABSTRACT SYNTAX TO C++:'
221             . "\n"
222             . 'Argument count '
223             . $argument_count
224             . ' exceeds maximum argument limit '
225             . ARGUMENTS_MAX()
226             . ' for operator ' . q{'}
227             . NAME_PERLOPS_PERLTYPES() . q{'}
228             . ', dying' . "\n";
229             }
230             # RPerl::diag( 'in OperatorVoid::Named::Return->ast_to_cpp__generate__CPPOPS_CPPTYPES(), have $arguments = ' . "\n" . RPerl::Parser::rperl_ast__dump($arguments) . "\n" );
231             if ((( ref $arguments->{children}->[0] ) eq 'ListElement_191' ) and ( exists $arguments->{children}->[0]->{children}->[0] ))
232             {
233             my object $arguments_subexpression = $arguments->{children}->[0]->{children}->[0];
234             # look inside nested parenthesis-as-subexpressions, always length 1 so no need to check length
235             while ((ref $arguments_subexpression) eq 'SubExpression_143') { # RPerl::Operation::Expression::SubExpression::Parenthesis
236             $arguments_subexpression = $arguments_subexpression->{children}->[1];
237             }
238             if (( ref $arguments_subexpression ) eq 'SubExpression_140' ) {
239             die 'ERROR ECOGEASCP04, CODE GENERATOR, ABSTRACT SYNTAX TO C++:' . "\n" . 'Attempt to return dereferenced array, please return arrayref instead, dying' . "\n";
240             }
241             elsif (( ref $arguments_subexpression ) eq 'SubExpression_142' ) {
242             die 'ERROR ECOGEASCP05, CODE GENERATOR, ABSTRACT SYNTAX TO C++:' . "\n" . 'Attempt to return dereferenced hash, please return hashref instead, dying' . "\n";
243             }
244             }
245             my string_hashref $cpp_source_subgroup
246             = $arguments->ast_to_cpp__generate__CPPOPS_CPPTYPES( $modes, $self );
247             # RPerl::diag( 'in OperatorVoid::Named::Return->ast_to_cpp__generate__CPPOPS_CPPTYPES(), have $cpp_source_subgroup = ' . "\n" . RPerl::Parser::rperl_ast__dump($cpp_source_subgroup) . "\n" );
248             RPerl::Generator::source_group_append( $cpp_source_group,
249             $cpp_source_subgroup );
250             $cpp_source_group->{CPP} .= $operator_void_named->{children}->[2]; # semicolon
251             }
252             else {
253             die RPerl::Parser::rperl_rule__replace(
254             'ERROR ECOGEASCP00, CODE GENERATOR, ABSTRACT SYNTAX TO C++: Grammar rule '
255             . ( ref $operator_void_named )
256             . ' found where OperatorVoid_119, OperatorVoid_120, or OperatorVoid_121 expected, dying'
257             ) . "\n";
258             }
259              
260             $cpp_source_group->{CPP} .= "\n";
261             return $cpp_source_group;
262             };
263              
264             1; # end of class