File Coverage

blib/lib/RPerl/Operation/Expression/SubExpression/Literal/String.pm
Criterion Covered Total %
statement 47 56 83.9
branch 12 18 66.6
condition 9 18 50.0
subroutine 7 8 87.5
pod n/a
total 75 100 75.0


line stmt bran cond sub pod time code
1             # [[[ HEADER ]]]
2             package RPerl::Operation::Expression::SubExpression::Literal::String;
3 3     3   21 use strict;
  3         11  
  3         92  
4 3     3   18 use warnings;
  3         7  
  3         76  
5 3     3   18 use RPerl::AfterSubclass;
  3         8  
  3         487  
6             our $VERSION = 0.006_000;
7              
8             # [[[ OO INHERITANCE ]]]
9 3     3   25 use parent qw(RPerl::Operation::Expression::SubExpression::Literal);
  3         7  
  3         21  
10 3     3   213 use RPerl::Operation::Expression::SubExpression::Literal;
  3         8  
  3         1445  
11              
12             # [[[ OO PROPERTIES ]]]
13             our hashref $properties = {};
14              
15             # [[[ SUBROUTINES & OO METHODS ]]]
16              
17             sub ast_to_rperl__generate {
18 2362     2362   4073 { my string_hashref::method $RETURN_TYPE };
  2362         3720  
19 2362         4688 ( my object $self, my string_hashref $modes) = @ARG;
20 2362         6735 my string_hashref $rperl_source_group = { PMC => q{} };
21              
22             # RPerl::diag( 'in Literal::String->ast_to_rperl__generate(), received $self = ' . "\n" . RPerl::Parser::rperl_ast__dump($self) . "\n" );
23              
24 2362 50       7735 if ( ( ref $self ) ne 'Literal_249' ) {
25 0         0 die RPerl::Parser::rperl_rule__replace(
26             'ERROR ECOGEASRP00, CODE GENERATOR, ABSTRACT SYNTAX TO RPERL: Grammar rule '
27             . ( ref $self )
28             . ' found where Literal_249 expected, dying' )
29             . "\n";
30             }
31            
32             # Literal -> LITERAL_STRING
33 2362         6875 my string $value = $self->{children}->[0];
34 2362         5508 $rperl_source_group->{PMC} .= $value;
35 2362         8524 return $rperl_source_group;
36             }
37              
38             sub ast_to_cpp__generate__CPPOPS_PERLTYPES {
39 0     0   0 { my string_hashref::method $RETURN_TYPE };
  0         0  
40 0         0 ( my object $self, my string_hashref $modes) = @ARG;
41 0         0 my string_hashref $cpp_source_group
42             = { CPP => q{// <<< RP::O::E::SE::L::S __DUMMY_SOURCE_CODE CPPOPS_PERLTYPES >>>}
43             . "\n" };
44              
45             #...
46 0         0 return $cpp_source_group;
47             }
48              
49             sub ast_to_cpp__generate__CPPOPS_CPPTYPES {
50 165     165   250 { my string_hashref::method $RETURN_TYPE };
  165         250  
51 165         371 ( my object $self, my string_hashref $modes) = @ARG;
52 165         256 my string_hashref $cpp_source_group;
53              
54             # RPerl::diag( 'in Literal::String->ast_to_cpp__generate__CPPOPS_CPPTYPES(), received $self = ' . "\n" . RPerl::Parser::rperl_ast__dump($self) . "\n" );
55              
56 165 50       455 if ( ( ref $self ) ne 'Literal_249' ) {
57 0         0 die RPerl::Parser::rperl_rule__replace( 'ERROR ECOGEASCP00, CODE GENERATOR, ABSTRACT SYNTAX TO C++: Grammar rule ' . ( ref $self ) . ' found where Literal_249 expected, dying' ) . "\n";
58             }
59            
60 165         544 $cpp_source_group->{CPP} = $self->{children}->[0];
61            
62             # replace single-quoted Perl string with double-quoted C++ string, both non-interpolated
63 165 100       1059 if ((substr $cpp_source_group->{CPP}, 0, 1) eq q{'}) {
    100          
64 97 50       268 if ((substr $cpp_source_group->{CPP}, -1, 1) eq q{'}) {
65 97         268 $cpp_source_group->{CPP} =~ s/\"/\\\"/gxms; # backslash-escape all double-quotes contained w/in single-quoted strings, before wrapping in non-escaped double-quotes
66 97         236 substr $cpp_source_group->{CPP}, 0, 1, q{"};
67 97         192 substr $cpp_source_group->{CPP}, -1, 1, q{"};
68             }
69             else {
70 0         0 die RPerl::Parser::rperl_rule__replace( 'ERROR ECOGEASCP50, CODE GENERATOR, ABSTRACT SYNTAX TO C++: string literal started with single-quote but not terminated with single-quote, dying' ) . "\n";
71             }
72             }
73             elsif ((substr $cpp_source_group->{CPP}, 0, 2) eq 'q{') {
74 4 50       15 if ((substr $cpp_source_group->{CPP}, -1, 1) eq '}') {
75 4         20 $cpp_source_group->{CPP} =~ s/\"/\\\"/gxms; # backslash-escape all double-quotes contained w/in single-quoted strings, before wrapping in non-escaped double-quotes
76 4         13 substr $cpp_source_group->{CPP}, 0, 2, q{"};
77 4         10 substr $cpp_source_group->{CPP}, -1, 1, q{"};
78             }
79             else {
80 0         0 die RPerl::Parser::rperl_rule__replace( 'ERROR ECOGEASCP51, CODE GENERATOR, ABSTRACT SYNTAX TO C++: string literal started with q-left-brace single-quote but not terminated with right-brace, dying' ) . "\n";
81             }
82             }
83             # NEED ADD ERROR CHECKING: double-quoted strings are okay for non-sigils containing newline or tab, non-quoted strings are not okay?
84             # else {
85             # die RPerl::Parser::rperl_rule__replace( 'ERROR ECOGEASCP52, CODE GENERATOR, ABSTRACT SYNTAX TO C++: string literal not started with single-quote, dying' ) . "\n";
86             # }
87              
88             # RPerl::diag( 'in Literal::String->ast_to_cpp__generate__CPPOPS_CPPTYPES(), have $modes->{_inside_print_operator} = ' . $modes->{_inside_print_operator} . "\n" );
89             # RPerl::diag( 'in Literal::String->ast_to_cpp__generate__CPPOPS_CPPTYPES(), have $modes->{_inside_list_elements} = ' . $modes->{_inside_list_elements} . "\n" );
90             # RPerl::diag( 'in Literal::String->ast_to_cpp__generate__CPPOPS_CPPTYPES(), have $modes->{_inside_cat_operator} = ' . $modes->{_inside_cat_operator} . "\n" );
91              
92 165         311 my boolean $cast_literal = 0;
93 165 50 66     495 if ((exists $modes->{_inside_class_properties}) and (defined $modes->{_inside_class_properties}) and $modes->{_inside_class_properties}) {
      66        
94 3         8 $cast_literal = 1;
95             }
96              
97 165 50 66     1797 if ((
      33        
      33        
      33        
98             ((exists $modes->{_inside_print_operator}) and (defined $modes->{_inside_print_operator}) and $modes->{_inside_print_operator}) or
99             ((exists $modes->{_inside_die_operator}) and (defined $modes->{_inside_die_operator}) and $modes->{_inside_die_operator})
100             ) and
101             (exists $modes->{_inside_list_elements}) and (defined $modes->{_inside_list_elements}) and $modes->{_inside_list_elements}) { # and
102             # not ((exists $modes->{_inside_cat_operator}) and (defined $modes->{_inside_cat_operator}) and $modes->{_inside_cat_operator})) {
103             # if (1) {
104             # don't cast string literals when:
105             # inside OO class properties; OR
106             # inside print or die operator, and also inside list elements, and also NOT inside string concatenation operator;
107             # cout << will automatically detect type
108 131         270 $cast_literal = 1;
109             }
110              
111 165 100       365 if ($cast_literal) {
112 134         243 $cpp_source_group->{CPP} = $cpp_source_group->{CPP};
113             }
114             else {
115             # cast all string literals to the RPerl-defined C++ string type
116 31         96 $cpp_source_group->{CPP} = '(const string) ' . $cpp_source_group->{CPP};
117             }
118 165         649 return $cpp_source_group;
119             }
120              
121             1; # end of class