File Coverage

blib/lib/RPerl/Operation/Expression/Operator/Named.pm
Criterion Covered Total %
statement 50 62 80.6
branch 11 16 68.7
condition 5 6 83.3
subroutine 7 8 87.5
pod n/a
total 73 92 79.3


line stmt bran cond sub pod time code
1             # [[[ HEADER ]]]
2             package RPerl::Operation::Expression::Operator::Named;
3 4     4   24 use strict;
  4         9  
  4         93  
4 4     4   19 use warnings;
  4         9  
  4         79  
5 4     4   26 use RPerl::AfterSubclass;
  4         7  
  4         474  
6             our $VERSION = 0.001_500;
7              
8             # [[[ OO INHERITANCE ]]]
9 4     4   25 use parent qw(RPerl::Operation::Expression::Operator);
  4         7  
  4         19  
10 4     4   214 use RPerl::Operation::Expression::Operator;
  4         10  
  4         2414  
11              
12             # [[[ CRITICS ]]]
13             ## no critic qw(ProhibitUselessNoCritic ProhibitMagicNumbers RequireCheckedSyscalls) # USER DEFAULT 1: allow numeric values & print operator
14             ## no critic qw(RequireInterpolationOfMetachars) # USER DEFAULT 2: allow single-quoted control characters & sigils
15              
16             # [[[ OO PROPERTIES ]]]
17             our hashref $properties = {};
18              
19             # [[[ OO PROPERTIES, CLASS PROPERTY AKA PACKAGE VARIABLE ]]]
20             # DEV NOTE, CORRELATION #rp020: upon adding new named op file lib/RPerl/Operation/Expression/Operator/Named*/* also add in Named*.pm and rperloperations.*
21             our string_hashref $NAMES = {
22             'abs' => 'RPerl::Operation::Expression::Operator::Named::AbsoluteValue',
23             'atan2' => 'RPerl::Operation::Expression::Operator::Named::Atan2',
24             'chomp' => 'RPerl::Operation::Expression::Operator::Named::Chomp',
25             'exp' => 'RPerl::Operation::Expression::Operator::Named::Exp',
26             'join' => 'RPerl::Operation::Expression::Operator::Named::Join',
27             'keys' => 'RPerl::Operation::Expression::Operator::Named::Keys',
28             'pop' => 'RPerl::Operation::Expression::Operator::Named::Pop',
29             'push' => 'RPerl::Operation::Expression::Operator::Named::Push',
30             'reverse' => 'RPerl::Operation::Expression::Operator::Named::Reverse',
31             'shift' => 'RPerl::Operation::Expression::Operator::Named::Shift',
32             'sort' => 'RPerl::Operation::Expression::Operator::Named::Sort',
33             'split' => 'RPerl::Operation::Expression::Operator::Named::Split',
34             'unshift' => 'RPerl::Operation::Expression::Operator::Named::Unshift',
35             'values' => 'RPerl::Operation::Expression::Operator::Named::Values',
36             'wait' => 'RPerl::Operation::Expression::Operator::Named::Wait'
37             };
38              
39             # [[[ SUBROUTINES & OO METHODS ]]]
40              
41             sub ast_to_rperl__generate {
42 74     74   171 { my string_hashref::method $RETURN_TYPE };
  74         181  
43 74         210 ( my object $self, my string_hashref $modes) = @ARG;
44 74         263 my string_hashref $rperl_source_group = { PMC => q{} };
45 74         167 my string_hashref $rperl_source_subgroup;
46              
47             # RPerl::diag( 'in Operator::Named->ast_to_rperl__generate(), received $self = ' . "\n" . RPerl::Parser::rperl_ast__dump($self) . "\n" );
48              
49 74         176 my string $self_class = ref $self;
50 74         160 my string $operator_name;
51 74 100 100     521 if ( $self_class eq 'Operation_90' ) { # Statement -> OP01_NAMED_SCOLON
    100          
    50          
52 1         23 $operator_name = substr $self->{children}->[0], 0, -1;
53             }
54             elsif (( $self_class eq 'Operator_94' ) # Operator -> OP01_NAMED SubExpression
55             or ( $self_class eq 'OperatorVoid_134' )
56             ) # OperatorVoid -> OP01_NAMED ListElement OP21_LIST_COMMA ListElements ';'
57             {
58 60         234 $operator_name = $self->{children}->[0];
59             }
60             elsif ( $self_class eq 'Operator_95' ) { # Operator -> LPAREN OP01_NAMED ListElement OP21_LIST_COMMA ListElements ')'
61 13         47 $operator_name = $self->{children}->[1];
62             }
63             else {
64 0         0 die RPerl::Parser::rperl_rule__replace( 'ERROR ECOGEASRP00, CODE GENERATOR, ABSTRACT SYNTAX TO RPERL: Grammar rule '
65             . $self_class
66             . ' found where Operation_90, Operator_94, Operator_95, or OperatorVoid_134 expected, dying' )
67             . "\n";
68             }
69            
70             # strip trailing whitespace, caused by the need to have the grammar match some tokens with a trailing whitespace, as with 'scalar ', etc.
71 74         546 $operator_name =~ s/^(\w+)\s*$/$1/gxms;
72              
73             # DEV NOTE: compile-time operator name checking short-circuited first by Parse Phase 0 ERROR ECOPAPL02 'Bareword "FOO" not allowed while "strict subs" in use';
74             # can't figure out how to create test which gets past ECOPAPL02 to trigger ECOGEASRP13
75 74 50       409 if ( not exists $NAMES->{$operator_name} ) {
76             die q{ERROR ECOGEASRP13, CODE GENERATOR, ABSTRACT SYNTAX TO RPERL: unsupported or unrecognized named operator '}
77             . $operator_name
78             . q{' found where }
79 0         0 . ( join ', ', ( sort keys %{$NAMES} ) )
  0         0  
80             . ' expected, operator may not be properly listed in $RPerl::Operation::Expression::Operator::Named::NAMES, dying' . "\n";
81             }
82 74         227 my string $operator_class = $NAMES->{$operator_name};
83 74         1135 my object $operator_object = $operator_class->new();
84              
85 74         2010 $rperl_source_subgroup = $operator_object->ast_to_rperl__generate( $self, $modes );
86 74         1505 RPerl::Generator::source_group_append( $rperl_source_group, $rperl_source_subgroup );
87 74         1355 return $rperl_source_group;
88             }
89              
90             sub ast_to_cpp__generate__CPPOPS_PERLTYPES {
91 0     0   0 { my string_hashref::method $RETURN_TYPE };
  0         0  
92 0         0 ( my object $self, my string_hashref $modes) = @ARG;
93 0         0 my string_hashref $cpp_source_group = { CPP => q{// <<< RP::O::E::O::N __DUMMY_SOURCE_CODE CPPOPS_PERLTYPES >>>} . "\n" };
94              
95             #...
96 0         0 return $cpp_source_group;
97             }
98              
99             sub ast_to_cpp__generate__CPPOPS_CPPTYPES {
100 13     13   27 { my string_hashref::method $RETURN_TYPE };
  13         28  
101 13         25 ( my object $self, my string_hashref $modes) = @ARG;
102 13         44 my string_hashref $cpp_source_group = { CPP => q{} };
103 13         20 my string_hashref $cpp_source_subgroup;
104              
105             # RPerl::diag( 'in Operator::Named->ast_to_cpp__generate__CPPOPS_CPPTYPES(), received $self = ' . "\n" . RPerl::Parser::rperl_ast__dump($self) . "\n" );
106              
107 13         28 my string $self_class = ref $self;
108 13         25 my string $operator_name;
109 13 50 66     65 if ( $self_class eq 'Operation_90' ) { # Statement -> OP01_NAMED_SCOLON
    100          
    50          
110 0         0 $operator_name = substr $self->{children}->[0], 0, -1;
111             }
112             elsif (( $self_class eq 'Operator_94' ) # Operator -> OP01_NAMED SubExpression
113             or ( $self_class eq 'OperatorVoid_134' )
114             ) # OperatorVoid -> OP01_NAMED ListElement OP21_LIST_COMMA ListElements ';'
115             {
116 12         40 $operator_name = $self->{children}->[0];
117             }
118             elsif ( $self_class eq 'Operator_95' ) { # Operator -> LPAREN OP01_NAMED ListElement OP21_LIST_COMMA ListElements ')'
119 1         18 $operator_name = $self->{children}->[1];
120             }
121             else {
122 0         0 die RPerl::Parser::rperl_rule__replace( 'ERROR ECOGEASRP00, CODE GENERATOR, ABSTRACT SYNTAX TO RPERL: Grammar rule '
123             . $self_class
124             . ' found where Operation_90, Operator_94, Operator_95, or OperatorVoid_134 expected, dying' )
125             . "\n";
126             }
127            
128             # strip trailing whitespace, caused by the need to have the grammar match some tokens with a trailing whitespace, as with 'scalar ', etc.
129 13         83 $operator_name =~ s/^(\w+)\s*$/$1/gxms;
130              
131             # DEV NOTE: compile-time operator name checking short-circuited first by Parse Phase 0 ERROR ECOPAPL02 'Bareword "FOO" not allowed while "strict subs" in use';
132             # can't figure out how to create test which gets past ECOPAPL02 to trigger ECOGEASCP14
133 13 50       48 if ( not exists $NAMES->{$operator_name} ) {
134             die q{ERROR ECOGEASCP14, CODE GENERATOR, ABSTRACT SYNTAX TO C++: unsupported or unrecognized named operator '}
135             . $operator_name
136             . q{' found where }
137 0         0 . ( join ', ', ( sort keys %{$NAMES} ) )
  0         0  
138             . ' expected, operator may not be properly listed in $RPerl::Operation::Expression::Operator::Named::NAMES, dying' . "\n";
139             }
140 13         34 my string $operator_class = $NAMES->{$operator_name};
141 13         177 my object $operator_object = $operator_class->new();
142              
143 13         309 $cpp_source_subgroup = $operator_object->ast_to_cpp__generate__CPPOPS_CPPTYPES( $self, $modes );
144 13         289 RPerl::Generator::source_group_append( $cpp_source_group, $cpp_source_subgroup );
145 13         206 return $cpp_source_group;
146             }
147              
148             1; # end of class