-
Notifications
You must be signed in to change notification settings - Fork 138
/
uniq.pir
163 lines (117 loc) · 2.55 KB
/
uniq.pir
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# Copyright (C) 2001-2008, Parrot Foundation.
=head1 NAME
examples/pir/uniq.pir - Remove duplicate lines from a sorted file
=head1 SYNOPSIS
% ./parrot examples/pir/uniq.pir -o uniq.pbc
=head1 DESCRIPTION
Parrot implementation of C<uniq>. Removes duplicate lines from a sorted
file. You'll have to create a suitable file to "de-dup".
=head2 Command-line Options
=over 4
=item C<-c>
Precede each output line with the count of the number of times the
line occurred in the input, followed by a single space
=item C<-d>
Don't output lines that are not repeated in the input
=item C<-u>
Don't output lines that are repeated in the input
=back
=head1 HISTORY
By Leon Brocard <acme@astray.com>.
Converted to PIR by Bernhard Schmalhofer.
=cut
.loadlib 'io_ops' # convenient I/O dynamic opcodes
.sub "uniq" :main
.param pmc argv
.local string program
program = shift argv
.local int num_args
num_args = argv
if num_args > 0 goto SOURCE
print "usage: parrot "
print program
print " [-c] [-d] [-u] filename\n"
goto END
SOURCE:
# set up flag registers
$I10 = 0
$I11 = 0
$I12 = 0
# do some simple option parsing
.local string option
option = shift argv
ne option, "-c", NOTC
$I10 = 1 # count mode
option = shift argv
NOTC:
ne option, "-d", NOTD
$I11 = 1 # duplicate mode
option = shift argv
NOTD:
ne option, "-u", GO
$I12 = 1 # unique mode
option = shift argv
GO:
.local string file_name
file_name = option
$I1 = 1 # count
.local pmc in_fh
in_fh = open file_name, 'r'
unless in_fh, ERR
.local string prev_line, curr_line
prev_line = readline in_fh
SOURCE_LOOP:
unless in_fh, END
curr_line = readline in_fh
if curr_line == prev_line goto MATCH
# different line
unless $I10, NOTC2
# count mode
# we go to some lengths to make the count pretty
set $S3, $I1
length $I2, $S3
sub $I2, 7, $I2
set $S3, " "
repeat $S3, $S3, $I2
print $S3
print $I1
print " "
print prev_line
branch RESET
NOTC2:
unless $I11, NOTD2
# show duplicates mode
eq 1, $I1, RESET
print prev_line
branch RESET
ERR:
print "Couldn't read "
print $S0
exit 1
NOTD2:
unless $I12, NOTU2
# don't show lines that are duplicated mode
ne 1, $I1, RESET
print prev_line
branch RESET
NOTU2:
# default mode
print prev_line
branch RESET
RESET:
set $I1, 1
branch LOOP
MATCH:
inc $I1
# fall through
LOOP:
set prev_line, curr_line
if curr_line, SOURCE_LOOP
close in_fh
END:
.end
# Local Variables:
# mode: pir
# fill-column: 100
# End:
# vim: expandtab shiftwidth=4 ft=pir: