File Coverage

blib/lib/RPerl/Operation/Expression/Operator/Named.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::Operator::Named;
3 5     5   29 use strict;
  5         10  
  5         132  
4 5     5   23 use warnings;
  5         10  
  5         104  
5 5     5   27 use RPerl::AfterSubclass;
  5         12  
  5         617  
6             our $VERSION = 0.001_500;
7              
8             # [[[ OO INHERITANCE ]]]
9 5     5   33 use parent qw(RPerl::Operation::Expression::Operator);
  5         11  
  5         29  
10 5     5   280 use RPerl::Operation::Expression::Operator;
  5         10  
  5         3301  
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             our string_hashref::method $ast_to_rperl__generate = sub {
42             ( my object $self, my string_hashref $modes) = @_;
43             my string_hashref $rperl_source_group = { PMC => q{} };
44             my string_hashref $rperl_source_subgroup;
45              
46             # RPerl::diag( 'in Operator::Named->ast_to_rperl__generate(), received $self = ' . "\n" . RPerl::Parser::rperl_ast__dump($self) . "\n" );
47              
48             my string $self_class = ref $self;
49             my string $operator_name;
50             if ( $self_class eq 'Operation_79' ) { # Statement -> OP01_NAMED_SCOLON
51             $operator_name = substr $self->{children}->[0], 0, -1;
52             }
53             elsif (( $self_class eq 'Operator_83' ) # Operator -> OP01_NAMED SubExpression
54             or ( $self_class eq 'OperatorVoid_122' )
55             ) # OperatorVoid -> OP01_NAMED ListElement OP21_LIST_COMMA ListElements ';'
56             {
57             $operator_name = $self->{children}->[0];
58             }
59             elsif ( $self_class eq 'Operator_84' ) { # Operator -> LPAREN OP01_NAMED ListElement OP21_LIST_COMMA ListElements ')'
60             $operator_name = $self->{children}->[1];
61             }
62             else {
63             die RPerl::Parser::rperl_rule__replace( 'ERROR ECOGEASRP00, CODE GENERATOR, ABSTRACT SYNTAX TO RPERL: Grammar rule '
64             . $self_class
65             . ' found where Operation_79, Operator_83, Operator_84, or OperatorVoid_122 expected, dying' )
66             . "\n";
67             }
68            
69             # strip trailing whitespace, caused by the need to have the grammar match some tokens with a trailing whitespace, as with 'scalar ', etc.
70             $operator_name =~ s/^(\w+)\s*$/$1/gxms;
71              
72             # 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';
73             # can't figure out how to create test which gets past ECOPAPL02 to trigger ECOGEASRP13
74             if ( not exists $NAMES->{$operator_name} ) {
75             die q{ERROR ECOGEASRP13, CODE GENERATOR, ABSTRACT SYNTAX TO RPERL: unsupported or unrecognized named operator '}
76             . $operator_name
77             . q{' found where }
78             . ( join ', ', ( sort keys %{$NAMES} ) )
79             . ' expected, operator may not be properly listed in $RPerl::Operation::Expression::Operator::Named::NAMES, dying' . "\n";
80             }
81             my string $operator_class = $NAMES->{$operator_name};
82             my object $operator_object = $operator_class->new();
83              
84             $rperl_source_subgroup = $operator_object->ast_to_rperl__generate( $self, $modes );
85             RPerl::Generator::source_group_append( $rperl_source_group, $rperl_source_subgroup );
86              
87             return $rperl_source_group;
88             };
89              
90             our string_hashref::method $ast_to_cpp__generate__CPPOPS_PERLTYPES = sub {
91             ( my object $self, my string_hashref $modes) = @_;
92             my string_hashref $cpp_source_group = { CPP => q{// <<< RP::O::E::O::N __DUMMY_SOURCE_CODE CPPOPS_PERLTYPES >>>} . "\n" };
93              
94             #...
95             return $cpp_source_group;
96             };
97              
98             our string_hashref::method $ast_to_cpp__generate__CPPOPS_CPPTYPES = sub {
99             ( my object $self, my string_hashref $modes) = @_;
100             my string_hashref $cpp_source_group = { CPP => q{} };
101             my string_hashref $cpp_source_subgroup;
102              
103             # RPerl::diag( 'in Operator::Named->ast_to_cpp__generate(), received $self = ' . "\n" . RPerl::Parser::rperl_ast__dump($self) . "\n" );
104              
105             my string $self_class = ref $self;
106             my string $operator_name;
107             if ( $self_class eq 'Operation_79' ) { # Statement -> OP01_NAMED_SCOLON
108             $operator_name = substr $self->{children}->[0], 0, -1;
109             }
110             elsif (( $self_class eq 'Operator_83' ) # Operator -> OP01_NAMED SubExpression
111             or ( $self_class eq 'OperatorVoid_122' )
112             ) # OperatorVoid -> OP01_NAMED ListElement OP21_LIST_COMMA ListElements ';'
113             {
114             $operator_name = $self->{children}->[0];
115             }
116             elsif ( $self_class eq 'Operator_84' ) { # Operator -> LPAREN OP01_NAMED ListElement OP21_LIST_COMMA ListElements ')'
117             $operator_name = $self->{children}->[1];
118             }
119             else {
120             die RPerl::Parser::rperl_rule__replace( 'ERROR ECOGEASRP00, CODE GENERATOR, ABSTRACT SYNTAX TO RPERL: Grammar rule '
121             . $self_class
122             . ' found where Operation_79, Operator_83, Operator_84, or OperatorVoid_122 expected, dying' )
123             . "\n";
124             }
125            
126             # strip trailing whitespace, caused by the need to have the grammar match some tokens with a trailing whitespace, as with 'scalar ', etc.
127             $operator_name =~ s/^(\w+)\s*$/$1/gxms;
128              
129             # 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';
130             # can't figure out how to create test which gets past ECOPAPL02 to trigger ECOGEASCP14
131             if ( not exists $NAMES->{$operator_name} ) {
132             die q{ERROR ECOGEASCP14, CODE GENERATOR, ABSTRACT SYNTAX TO C++: unsupported or unrecognized named operator '}
133             . $operator_name
134             . q{' found where }
135             . ( join ', ', ( sort keys %{$NAMES} ) )
136             . ' expected, operator may not be properly listed in $RPerl::Operation::Expression::Operator::Named::NAMES, dying' . "\n";
137             }
138             my string $operator_class = $NAMES->{$operator_name};
139             my object $operator_object = $operator_class->new();
140              
141             $cpp_source_subgroup = $operator_object->ast_to_cpp__generate__CPPOPS_CPPTYPES( $self, $modes );
142             RPerl::Generator::source_group_append( $cpp_source_group, $cpp_source_subgroup );
143              
144             return $cpp_source_group;
145             };
146              
147             1; # end of class