1
package Language::INTERCAL::Charset::Hollerith;
3
# Convert between Hollerith and ASCII
5
# This file is part of CLC-INTERCAL.
7
# Copyright (C) 2000, 2002, 2006 Claudio Calvelli, all rights reserved
9
# CLC-INTERCAL is copyrighted software. However, permission to use, modify,
10
# and distribute it is granted provided that the conditions set out in the
11
# licence agreement are met. See files README and COPYING in the distribution.
13
use vars qw($PERVERSION);
14
$PERVERSION = "CLC-INTERCAL INTERCAL/Charset/Hollerith.pm 1.-94.-6";
19
use Language::INTERCAL::Exporter '1.-94.-4';
20
use vars qw(@EXPORT @EXPORT_OK);
22
@EXPORT_OK = qw(ascii2hollerith hollerith2ascii);
24
use Language::INTERCAL::Splats '1.-94.-4', qw(:SP);
26
my @bitmask = ("\001\000", "\000\001", "\002\000", "\000\002",
27
"\004\000", "\000\004", "\010\000", "\000\010",
28
"\020\000", "\000\020", '', "\040\000", "\000\040");
31
my ($ascii, @punch) = @_;
32
my $hollerith = "\000\000";
34
my $punch = shift @punch;
35
die "Internal error (punch=$punch)"
36
if $punch >= @bitmask || $bitmask[$punch] eq '';
37
$hollerith |= $bitmask[$punch];
39
$hollerith |= "\100\000" if "\000\000" eq ($hollerith & "\040\000");
40
$hollerith |= "\000\100" if "\000\000" eq ($hollerith & "\000\040");
44
my %ascii2hollerith = map { mk_hollerith(@$_) } (
81
["\"\b.", 12, 8, 3, 2],
118
# Punched cards do not have lowercase - we use uppercase with overpunch
145
# overline (tall worm?) is 11, 0
146
# the following codes do not exist in Hollerith - we use "Christmas lights"
147
["\n", 12, 9, 8, 7, 6, 5, 4, 3, 2, 1],
148
["\r", 11, 9, 8, 7, 6, 5, 4, 3, 2, 1],
149
["\t", 0, 9, 8, 7, 6, 5, 4, 3, 2, 1],
152
my %asciimultiple = map { (substr($_, 0, length($_) - 1) => 1) }
153
grep { length($_) > 1 }
154
keys %ascii2hollerith;
156
my %hollerith2ascii = reverse %ascii2hollerith;
158
#print join(' ', sort values %ascii2hollerith), "\n";
159
#print join(' ', sort keys %hollerith2ascii), "\n";
160
die "Internal error" if keys %ascii2hollerith != keys %hollerith2ascii;
162
sub hollerith2ascii {
163
@_ == 1 or croak "Usage: hollerith2ascii(STRING)";
166
while ($string ne '') {
167
my $char = substr($string, 0, 2);
168
$string = substr($string, 2);
169
$char .= "\000" if length($char) == 1;
171
$char |= "\100\000" if "\000\000" eq ($char & "\040\000");
172
$char |= "\000\100" if "\000\000" eq ($char & "\000\040");
173
if (! exists $hollerith2ascii{$char}) {
175
for (my $punch = 0; $punch < @bitmask; $punch++) {
176
push @punch, $punch if $bitmask[$punch] ne '' &&
177
($char & $bitmask[$punch]) ne "\000\000";
179
push @punch, '(empty' unless @punch;
180
my $punch = join('-', sort { $b <=> $a } @punch);
181
faint(SP_NOSUCHCHAR, $punch, "Hollerith")
183
$result .= $hollerith2ascii{$char};
188
sub ascii2hollerith {
189
@_ == 1 or croak "Usage: ascii2hollerith(STRING)";
192
while ($string ne '') {
193
my $char = substr($string, 0, 1);
194
$string = substr($string, 1);
195
while ($string ne '' && exists $asciimultiple{$char}) {
196
my $next = substr($string, 0, 1);
197
last if ! exists $asciimultiple{$char . $next} &&
198
! exists $ascii2hollerith{$char . $next};
200
$string = substr($string, 1);
202
$result .= $ascii2hollerith{$char} ||
203
faint(SP_NOSUCHCHAR, $char, "Hollerith")
214
Charset::Hollerith - allows to use Hollerith string constants in ASCII programs (and v.v.)
218
use Charset::Hollerith qw(hollerith2ascii);
220
my $a = hollerith2ascii "(Hollerith text)";
224
I<Charset::Hollerith> defines functions to convert between a subset of ASCII
225
and a subset of nonstandard Hollerith (since there isn't such a thing as a
227
Hollerith we defined our own variant which is guaranteed to be incompatible
228
with all versions of Hollerith used by IBM hardware - however, for each
229
character code we have used the code used by some (but not all) IBM card
230
reader, if the code exists in Hollerith at all, or we have made one up
231
in some logical way (such as overpunching) if no IBM hardware had that
232
particular character.
234
The two functions I<hollerith2ascii> and I<ascii2hollerith> are exportable
235
but not exported by default. They do the obvious thing to their argument.
237
=head1 HOLLERITH CHARACTER TABLE
239
A Hollerith string is a sequence of 12-bit characters; they are encoded as
240
two ASCII characters, containing 6 bits each: the first character contains
241
punches 12, 0, 2, 4, 6, 8 and the second character contains punches 11, 1,
242
3, 5, 7, 9; interleaving the two characters gives the original 12 bits.
243
To make the characters printable on ASCII terminals, bit 7 is always set to 0,
244
and bit 6 is set to the complement of bit 5. These two bits are ignored when
245
reading Hollerith cards.
247
Some Hollerith characters (produced by overpunching) can be converted
248
to sequences of ASCII characters; I<ascii2hollerith> will correctly
249
recognise the sequences.
251
The following punched cards document the encoding of characters (the last
252
three symbols at the end nongraphic symbols in ASCII; the previous two
253
symbols correspond to multicharacter sequences):
255
' !"#$%&()*+,-./:;<=>?@[\]^_`{|}~��0123456789
256
12 * * * * * * * * * * 12
257
11 * * * * ** ** * * * 11
258
0 * * * * **** * * *** 0
262
4 *** * * ** * * * * 4
266
8 * ******** * * ******* * * * * * 8
269
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrs
270
12 ********* ********* 12
271
11 ********* ********* 11
283
tuvwxyz [] ". NL CR HT
299
This module is part of CLC-INTERCAL.
301
Copyright (C) 2000, 2002, 2006 Claudio Calvelli, all rights reserved.
303
See the files README and COPYING in the distribution for information.
307
A qualified psychiatrist.