Skip to content

Commit ae51b65

Browse files
committed
added demoes and tests and cleaned up code
1 parent 38449e2 commit ae51b65

File tree

1 file changed

+249
-32
lines changed

1 file changed

+249
-32
lines changed

perl2python.pl

Lines changed: 249 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,272 @@
11
#!/usr/bin/perl -w
22

3-
use strict
3+
use strict;
44

5-
my @stateStack;
6-
my @whitespaceStack;
5+
my $whitespaceCounter = 0; #global variable? Its outside the loop...
76

8-
#things that are the same: arithmetic operators, comparisons e.g =, bitwise operators, break/continue
9-
10-
#read input
117
while (my $line = <>) {
128

13-
if ($line =~ /^#!/ && $. == 1) { # translate #! line
9+
#NOTE: Deal with semicolons on a line by line basis
10+
11+
# translate #! line
12+
if ($line =~ /^#!/ && $. == 1) {
1413
print "#!/usr/bin/python2.7 -u\n";
15-
} elsif ($line =~ /^\s*#/ || $line =~ /^\s*$/) { # Blank & comment lines (unchanged)
14+
15+
# Blank & comment lines (unchanged)
16+
} elsif ($line =~ /^\s*#/ || $line =~ /^\s*$/) {
1617
print $line;
17-
} elsif ($line =~ /^\s*print\s*"(.*)\\n"[\s;]*$/) { #print with newline
18-
if ($line =~ /$/ || $line =~ /@/ || line = /%/) { #variables are being used in the statement
19-
#I DONT EVEN KNOW WHAT I NEED TO DO HERE
18+
19+
#print statement with newline
20+
} elsif ($line =~ /^\s*print\s*"(.*)\\n"[\s;]*$/) {
21+
my $printInput = $1;
22+
if($printInput =~ /ARGV\[(.*)\]$/) { #that variable is ARGV[]
23+
&whitespacePrinter($whitespaceCounter);
24+
my $location = $1;
25+
$location =~ s/\$//;
26+
print "print sys.argv[$location + 1]\n"
27+
} elsif ($printInput =~ /^(.*)\s*\$(.*)*$/) { #there is ONE $variable
28+
$printInput =~ s/\$//; #removes variable signs
29+
&whitespacePrinter($whitespaceCounter);
30+
print "print $printInput\n";
31+
} elsif ($printInput =~ /^(.*)\s*\@(.*)*$/) { #there is ONE @variable
32+
$printInput =~ s/\@//;
33+
&whitespacePrinter($whitespaceCounter);
34+
print "print $printInput\n";
35+
} else { #there is no variable (or many, which currently kill everything)
36+
&whitespacePrinter($whitespaceCounter);
37+
print "print \"$printInput\"\n";
38+
}
39+
40+
#print statment with no newline
41+
} elsif ($line =~ /^\s*print\s*"(.*)"[\s;]*$/) {
42+
my $printInput = $1;
43+
if ($printInput =~ /^\s*print\s*\$\_\s*;$/) { #special case for $_ (IN THE CASE OF PRINTING FROM THE COMMAND LINE?
44+
&whitespacePrinter($whitespaceCounter);
45+
print "print line\n";
46+
} elsif ($printInput =~ /^(.*)\s*\$(.*)*$/) { #there is ONE variable
47+
&whitespacePrinter($whitespaceCounter);
48+
$printInput =~ s/\$//; #removes variable signs
49+
$printInput =~ s/\@//;
50+
print "sys.stdout.write($printInput)\n";
51+
} else { #there is no variable (or many, which currently kill everything)
52+
&whitespacePrinter($whitespaceCounter);
53+
print "sys.stdout.write(\"$printInput\")\n";
54+
}
55+
56+
#break/continue
57+
} elsif ($line =~ /^\s*last;$/) {
58+
&whitespacePrinter($whitespaceCounter);
59+
print "break\n";
60+
61+
} elsif ($line =~ /^\s*next;$/) {
62+
&whitespacePrinter($whitespaceCounter);
63+
print "continue\n";
64+
65+
#looping through every line in a FILE
66+
} elsif ($line =~ /^\s*while\s*(.*)\<\>(.*)\s*(.*)\s*$/) {
67+
&whitespacePrinter($whitespaceCounter);
68+
print "import fileinput\n";
69+
&whitespacePrinter($whitespaceCounter);
70+
print "for line in fileinput.input():\n"
71+
72+
#looping through STDIN (while loop)
73+
} elsif ($line =~ /^\s*while\s*(.*)\<STDIN\>(.*)\s*(.*)\s*$/) {
74+
&whitespacePrinter($whitespaceCounter);
75+
print "import sys\n";
76+
&whitespacePrinter($whitespaceCounter);
77+
print "for line in sys.stdin:\n";
78+
79+
#chomp from STDIN
80+
} elsif ($line =~ /^\s*chomp\s*\$(.*)\s*;$/) {
81+
&whitespacePrinter($whitespaceCounter);
82+
print "$1 = sys.stdin.readlines()\n"
83+
84+
#split
85+
} elsif ($line =~ /^\s*(.*)\s*=\s*split\(\/(.*)\/,\s*\$(.*)\)\s*;/) {
86+
my $string = $3;
87+
my $delineator = $2;
88+
my $assignmentVariable = $1;
89+
&whitespacePrinter($whitespaceCounter);
90+
print "$assignmentVariable = $string.split(\"$delineator\")\n";
91+
92+
#join
93+
} elsif ($line =~ /^\s*(.*)\s*=\s*join\(\'(.*)\'\,\s*(.*)\)\s*;$/) {
94+
my $assignmentVariable = $1;
95+
my $string = $3;
96+
my $delineator = $2;
97+
&whitespacePrinter($whitespaceCounter);
98+
print "$assignmentVariable = '$delineator'.join([$string])";
99+
100+
#arithmetic operations
101+
} elsif ($line =~ /^\s*[^\s]*\s*=(.*);$/) {
102+
if ($line =~ /^\s*\@(.*)\s*=\s*(.*);$/) {#arrays are dealt with seperately
103+
next;
104+
} else {
105+
&whitespacePrinter($whitespaceCounter);
106+
&arithmeticLines($line);
107+
}
108+
109+
# ++ and --
110+
} elsif ($line =~ /^\s*(.*)\s*\+\+(.*);$/) {
111+
# change ++ and -- to python equivalents
112+
&whitespacePrinter($whitespaceCounter);
113+
my $plusPlus = $1;
114+
$plusPlus =~ s/\$//;
115+
print "$plusPlus +=1\n";
116+
} elsif ($line =~ /^\s*(.*)\s*\-\-(.*);$/) {
117+
&whitespacePrinter($whitespaceCounter);
118+
my $minusMinus = $1;
119+
$minusMinus =~ s/\$//;
120+
print "$minusMinus -= 1\n";
121+
122+
#for loops (If in C style then no direct comparison)?
123+
#foreach (with ARGV) (super specific, could do with broadening in scope)
124+
} elsif ($line =~ /^\s*foreach\s*\$(.*)\s*\((.*)\)\s*{\s*$/) {
125+
#foreach $i (0..$#ARGV) becomes for i in xrange (len(sys.argv) - 1):
126+
my $variableName = $1;
127+
&whitespacePrinter($whitespaceCounter);
128+
print "for $variableName in xrange (len(sys.argv) - 1):\n";
129+
130+
#while loops
131+
} elsif ($line =~ /^\s*(.*)\s*while\s*\((.*)\)(.*)\s*$/) {
132+
if ($line =~ /^\s*(.*)\s*while\s*\((.*)\s*\<STDIN\>\s*\)(.*)\s*$/) { #stdin
133+
&whitespacePrinter($whitespaceCounter);
134+
print "for line in sys.stdin:";
20135
} else {
21-
#delete \n; automatic in python
22-
print "print ("$1")";
136+
my $whileCondition = $2;
137+
&whitespacePrinter($whitespaceCounter);
138+
print "while ";
139+
&arithmeticLines($whileCondition);
140+
print ":\n";
141+
$whitespaceCounter ++;
23142
}
24-
} elsif ($line =~ /^\s*print\s*"(.*)"[\s;]*$/) { #print without newline
25-
print "sys.stdout.write("$1")";
26-
} else { # Lines we can't translate are turned into comments
143+
144+
# elsif
145+
} elsif ($line =~ /^\s*(.*)\s*elsif\s*\((.*)\)(.*)\s*$/) {
146+
#remember to remove } if present
147+
#becomes elif
148+
my $elsifCondition = $2;
149+
&whitespacePrinter($whitespaceCounter-1);
150+
print "elif "; #so, so frustratingly messy :/
151+
&arithmeticLines($elsifCondition);
152+
print ":\n";
153+
154+
#if statements
155+
} elsif ($line =~ /^\s*(.*)\s*if\s*\((.*)\)(.*)\s*$/) {
156+
my $ifCondition = $2;
157+
&whitespacePrinter($whitespaceCounter);
158+
print "if "; #ugh this is messy :/
159+
&arithmeticLines($ifCondition);
160+
print ":\n";
161+
$whitespaceCounter ++;
162+
163+
#else
164+
} elsif ($line =~ /^\s*(.*)\s*else\s*(.*)\s*$/) {
165+
#remember to remove } if present
166+
&whitespacePrinter($whitespaceCounter-1);
167+
print "else:\n";;
168+
169+
#end curly brace needs removal
170+
} elsif ($line =~ /^\s*}\s*$/) {
171+
$line =~ s/\}/ /;
172+
$whitespaceCounter --;
173+
174+
175+
#ARRAY HANDLING
176+
#array conversion
177+
}elsif ($line =~ /^\s*(.*)\s*\@(.*)\s*(.*)\s*;$/) { #array in the line
178+
my $arrayName = $2;
179+
if (/^\s*(.*)\s*\@(.*)\s*=\s*((.*))\s*;$/) { #declaring the array
180+
$line =~ s/\@//;
181+
$line =~ s/\(/\[/;
182+
$line =~ s/\)/\]/;
183+
$line =~ s/\"/\'/g;
184+
$line =~ s/\;//;
185+
print "$line";
186+
} else { #accessing the array
187+
# $arrayName[0 or whatever];
188+
$line =~ s/\@//;
189+
$line =~ s/\;//;
190+
print "$line";
191+
}
192+
#push
193+
} elsif ($line =~ /^\s*push\s*\@(.*)\,\s*(.*)\s*;$/) {
194+
&whitespacePrinter($whitespaceCounter);
195+
print "$1.push($2)\n";
196+
197+
#pop
198+
} elsif ($line =~ /^\s*pop\s*\@(.*);$/) {
199+
&whitespacePrinter($whitespaceCounter);
200+
print "$1.pop\n";
201+
202+
#unshift
203+
} elsif ($line =~ /^\s*unshift\s*\@(.*)\,\s*(.*)\s*;$/) {
204+
&whitespacePrinter($whitespaceCounter);
205+
print "$1.unshift($2)\n";
206+
207+
#pop
208+
} elsif ($line =~ /^\s*shift\s*\@(.*);$/) {
209+
&whitespacePrinter($whitespaceCounter);
210+
print "$1.shift\n";
211+
212+
213+
#concatenation with . (both dont add spaces by default yay) (with + is the same)
214+
# } elsif ($line =~ /^\s*(.*)\s*\.\s*(.*)\s*;$/) { #untested match
215+
# $line =~ s/\./\+/;
216+
# print $line;
217+
218+
#substitution s/// (UNTESTED)
219+
# $line =~ s/[aeiou]//g; becomes line = re.sub(r'[aeiou]', '', line)
220+
# } elsif ($line =~ /^\s*\$(.*)\s*(.*)\s*s\/(.*)\/(.*)\/(.*);$/) {
221+
# my $variableName = $1;
222+
# my $replaced = $3;
223+
# my $replacedWith = $4;
224+
# print "$variableName = re.sub(r'$3', '$4', $variableName)"
225+
226+
# Lines we can't translate are turned into comments
227+
} else {
27228
print "#$line\n";
28229
}
29230

30-
#These ones dont really need if statements, they should happen on top of the other things and regardless
231+
}
232+
sub arithmeticLines {
233+
234+
# $#
235+
$_[0] =~ s/\$\#ARGV/len\(sys\.argv\)/;
31236

32237
#removes $ before variables
33-
$line =~ s/\$//g;
34-
# change ++ and -- to python equivalents
35-
$line =~ s/\+\+/\+\=1/g
36-
$line =~ s/\-\-/\-\=1/g
37-
}
238+
$_[0] =~ s/\$//g;
239+
$_[0] =~ s/\@//g;
38240

241+
#stdin
242+
$_[0] =~ s/\<STDIN\>/float\(sys\.stdin\.readline\(\)\)/;
39243

244+
#and/or/not
245+
$_[0] =~ s/\&\&/and /g;
246+
$_[0] =~ s/\|\|/or /g;
247+
$_[0] =~ s/!\s/not /g;
40248

249+
#comparison operators that dont exist in Python replaced with those that do
250+
$_[0] =~ s/ eq / == /g;
251+
$_[0] =~ s/ ne / != /g;
252+
$_[0] =~ s/ gt / > /g;
253+
$_[0] =~ s/ lt / < /g;
254+
$_[0] =~ s/ ge / >= /g;
255+
$_[0] =~ s/ le / <= /g;
41256

257+
#division
258+
$_[0] =~ s/\//\/\//g;
42259

43-
sub stateStack {
44-
#if, else, while, for (any loops etc) are pushed on
45-
# if ($line =~ )
46-
#they call another sub
47-
# if close } they are popped
48-
if ($line =~ /{/ == 1) { #there exists a close bracket
49-
pop @stack;
50-
}
260+
#remove that semicolon
261+
$_[0] =~ s/\;//;
262+
print $_[0];
51263
}
52264

53-
sub whitespaceStack {
54-
#how big is the array? this tells us how many indents to go with
265+
sub whitespacePrinter {
266+
my $whitespace = $_[0];
267+
for (my $x = 0; $x < $whitespace; $x ++) {
268+
print ' ';
269+
}
55270
}
271+
272+

0 commit comments

Comments
 (0)