File Coverage

lib/Acme/Syntax/Python.pm
Criterion Covered Total %
statement 89 100 89.0
branch 40 42 95.2
condition 2 8 25.0
subroutine 9 11 81.8
pod 0 3 0.0
total 140 164 85.3


line stmt bran cond sub pod time code
1 5     5   12372 use strict;
  5         12  
  5         165  
2 5     5   58 use warnings;
  5         10  
  5         199  
3             package Acme::Syntax::Python;
4 5     5   5292 use Filter::Util::Call;
  5         14711  
  5         449  
5 5     5   36 use vars qw($VERSION);
  5         164  
  5         17737  
6              
7             $VERSION = "0.01";
8              
9             # ABSTRACT: Python like Syntax Module
10              
11             sub import {
12 5     5   53 my $class = shift; #We don't need Class Name.
13 5         19 my %params = @_;
14 5         51 my (%context) = (
15             _filename => (caller)[1],
16             _line_no => 0,
17             _last_begin => 0,
18             _in_block => 0,
19             _block_depth => 0,
20             _lambda_block => {},
21             _class_block => {},
22             _debug => $params{debug}
23             );
24 5         35 filter_add(bless \%context, $class);
25             }
26              
27             sub error {
28 0     0 0 0 my ($self) = shift;
29 0         0 my ($message) = shift;
30 0   0     0 my ($line_no) = shift || $self->{last_begin};
31 0         0 die "Error: $message at $self->{_filename} line $line_no.\n"
32             }
33              
34             sub warning {
35 0     0 0 0 my ($self) = shift;
36 0         0 my ($message) = shift;
37 0   0     0 my ($line_no) = shift || $self->{last_begin};
38 0         0 warn "Warning: $message at $self->{_filename} line $line_no.\n"
39             }
40              
41             sub filter {
42 85     85 0 151805 my ($self) = @_;
43 85         101 my ($status);
44 85         361 $status = filter_read();
45 85         162 ++ $self->{line_no};
46 85 100       288 if ($status <= 0) {
47 6 100       24 if($self->{_in_block}) {
48 1         1 $_ = "}\n";
49 1         2 ++ $status;
50 1         1 $self->{_in_block} = 0;
51             }
52 6         8897 return $status;
53             }
54              
55 79 100       204 if($self->{_in_block}) {
56 38         79 _handle_block($self, $_);
57             }
58              
59             s{^\s*import (.+);$}
60 79         203 {use $1;}gmx;
61 79         125 s{^\s*from (.+) import (.+);$}
62             {use $1 ($2);}gmx;
63              
64 79         105 s{True}{1}gmx;
65 79         138 s{False}{0}gmx;
66              
67 79 50       167 if(/class (.+) inherits (.+):/) {
68 0         0 s{class (.+) inherits (.+):}{\{\npackage $1;\nuse $2; our \@ISA = qw($2);\n}gmx;
69 0         0 _start_block($self);
70             }
71              
72 79 100       175 if(/class (.+):/) {
73 2         30 s{class (.+):}{\{\npackage $1;\n}gmx;
74 2         10 _start_block($self);
75             }
76              
77             #Handle def with Params
78 79 100       169 if(/lambda\((.+)\):/) {
79 1         10 s{lambda\((.+)\):}{sub \{ my($1) = \@_;}gmx;
80 1         3 _start_block($self, "_lambda_block");
81             }
82              
83             #Handle def with no Params
84 79 100       168 if(/lambda:/) {
85 1         6 s{lambda:}{sub \{};
86 1         9 _start_block($self, "_lambda_block");
87             }
88              
89             #Handle def with Params
90 79 100       181 if(/def (.+)\((.+)\):/) {
91 7 100       54 if($1 eq "__init__") {
92 1         10 s{def (.+)\((.+)\):}{sub $1 \{ my(\$class, $2) = \@_; my \$self = \{\};}gmx;
93 1         6 $self->{_class_block}->{($self->{_block_depth} + 1)} = 1;
94             } else {
95 6         55 s{def (.+)\((.+)\):}{sub $1 \{ my($2) = \@_;}gmx;
96             }
97 7         21 _start_block($self);
98             }
99              
100             #Handle def with no Params
101 79 100       183 if(/def (.+):/) {
102 3 100       16 if($1 eq "__init__") {
103 1         8 s{def (.+):}{sub $1 \{ my (\$class) = shift; my \$self = \{\};}gmx;
104 1         6 $self->{_class_block}->{($self->{_block_depth} + 1)} = 1;
105             } else {
106 2         16 s{def (.+):}{sub $1 \{}gmx;
107             }
108 3         11 _start_block($self);
109             }
110              
111 79         111 s{__init__}{new}gmx;
112              
113 79 100       261 if(/elif (.+)/) {
    100          
114 2         12 s{elif (.+)}{elsif $1}gmx;
115             }
116             elsif(/if (.*)/) {
117 4         28 s{if (.*)}{if $1}gmx;
118             }
119 79 100       157 if(/\):$/) {
120 4         16 s{:$}{ \{}gmx;
121 4         9 _start_block($self);
122             }
123 79 100       163 if(/else:/) {
124 2         9 s{:$}{\{}gmx;
125 2         7 _start_block($self);
126             }
127              
128 79 50       171 if($self->{_debug}) {
129 0         0 print "$self->{line_no} $_";
130             }
131 79         1446 return $status;
132             }
133              
134             sub _handle_spacing {
135 21     21   33 my $depth = shift;
136 21   100     114 my $modifier = shift // 1;
137 21         89 return (' ') x (4 * ($depth - $modifier));
138             }
139              
140             sub _start_block {
141 20     20   33 my ($self, $type) = @_;
142 20         37 $self->{_in_block} = 1;
143 20         29 ++ $self->{_block_depth};
144 20 100       59 if(defined($type)) {
145 2         12 $self->{$type}->{$self->{_block_depth}} = 1;
146             }
147             }
148              
149             sub _handle_block {
150 38     38   48 my ($self) = @_;
151 38         103 /^(\s*)/;
152 38         71 my $depth = length ( $1 );
153 38 100       123 if($depth < (4 * $self->{_block_depth})) {
154 19         45 my $spaces = _handle_spacing($self->{_block_depth});
155 19 100       97 if($self->{_lambda_block}->{$self->{_block_depth}}) {
    100          
156 2         6 $self->{_lambda_block}->{$self->{_block_depth}} = 0;
157 2         13 s/^/$spaces\};\n/;
158             } elsif ($self->{_class_block}->{$self->{_block_depth}}){
159 2         7 my $spaces_front = _handle_spacing($self->{_block_depth}, 0);
160 2         4 $self->{_class_block}->{$self->{_block_depth}} = 0;
161 2         21 s/^/$spaces_front return bless \$self, \$class;\n$spaces\}\n/;
162             } else {
163 15         72 s/^/$spaces\}\n/;
164             }
165 19         41 -- $self->{_block_depth};
166             }
167 38 100       102 if($self->{_block_depth} == 0) {
168 8         19 $self->{_in_block} = 0;
169             }
170             }
171              
172             1;
173              
174             __END__