comparison interps/clc-intercal/CLC-INTERCAL-Base-1.-94.-2/INTERCAL/ArrayIO.pm @ 996:859f9b4339e6

<Gregor> tar xf egobot.tar.xz
author HackBot
date Sun, 09 Dec 2012 19:30:08 +0000
parents
children
comparison
equal deleted inserted replaced
995:6883f5911eb7 996:859f9b4339e6
1 package Language::INTERCAL::ArrayIO;
2
3 # Write/read arrays
4
5 # This file is part of CLC-INTERCAL
6
7 # Copyright (c) 2006-2008 Claudio Calvelli, all rights reserved.
8
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.
12
13 use strict;
14 use vars qw($VERSION $PERVERSION);
15 ($VERSION) = ($PERVERSION = "CLC-INTERCAL/Base INTERCAL/ArrayIO.pm 1.-94.-2") =~ /\s(\S+)$/;
16
17 use Carp;
18 use Language::INTERCAL::Exporter '1.-94.-2';
19 use Language::INTERCAL::Splats '1.-94.-2', qw(:SP);
20 use Language::INTERCAL::Charset::Baudot '1.-94.-2',
21 qw(baudot2ascii ascii2baudot);
22 use vars qw(@EXPORT @EXPORT_OK %EXPORT_TAGS);
23 @EXPORT = ();
24 @EXPORT_OK = qw(iotype_default iotype iotype_name
25 write_array_16 read_array_16
26 write_array_32 read_array_32);
27 %EXPORT_TAGS = ();
28
29 my @iotypes;
30 my %iotypes;
31
32 BEGIN {
33 @iotypes = (
34 [CLC => \&_ra_clc_16, \&_ra_clc_32, \&_wa_clc_16, \&_wa_clc_32],
35 [C => \&_ra_c, \&_ra_c, \&_wa_c, \&_wa_c],
36 [1972 => \&_no_io, \&_no_io, \&_no_io, \&_no_io],
37 );
38 %iotypes = map { ($iotypes[$_ - 1][0] => $_) } (1..@iotypes);
39 }
40
41 use constant iotype_default => $iotypes{CLC};
42
43 sub iotype {
44 @_ == 1 or croak "Usage: iotype(IOTYPE)";
45 my ($iotype) = @_;
46 $iotype =~ s/\s+//g;
47 if ($iotype =~ /^\d+$/ && $iotype != 1972) {
48 return iotype_default if $iotype == 0;
49 return undef if $iotype < 1 || $iotype > @iotypes;
50 return $iotype;
51 } else {
52 $iotype = uc($iotype);
53 return undef if ! exists $iotypes{$iotype};
54 return $iotypes{$iotype};
55 }
56 }
57
58 sub iotype_name {
59 @_ == 1 or croak "Usage: iotype_name(IOTYPE)";
60 my ($iotype) = @_;
61 $iotype = iotype_default if $iotype < 1;
62 return undef if $iotype < 1 || $iotype > @iotypes;
63 return $iotypes[$iotype - 1][0];
64 }
65
66 sub read_array_16 {
67 @_ == 5 or croak
68 'Usage: read_array_16(IOTYPE, \$IOVALUE, FILEHANDLE, \@VALUES, NL';
69 my ($iotype, $iovalue, $fh, $values, $nl) = @_;
70 my $iocode = iotype($iotype) or faint(SP_IOTYPE, $iotype);
71 &{$iotypes[$iocode - 1][1]}($iovalue, $values, $fh, $nl);
72 }
73
74 sub read_array_32 {
75 @_ == 5 or croak
76 'Usage: read_array_32(IOTYPE, \$IOVALUE, FILEHANDLE, \@VALUES, NL';
77 my ($iotype, $iovalue, $fh, $values, $nl) = @_;
78 my $iocode = iotype($iotype) or faint(SP_IOTYPE, $iotype);
79 &{$iotypes[$iocode - 1][2]}($iovalue, $values, $fh, $nl);
80 }
81
82 sub _no_io {
83 faint(SP_FORBIDDEN, 'Array I/O');
84 }
85
86 sub _ra_c {
87 my ($iovalue, $values, $fh, $nl) = @_;
88 my $tape_pos = $$iovalue;
89 my @v = ();
90 for my $value (@$values) {
91 $tape_pos = ($tape_pos + 256 - ($value & 0xff)) & 0xff;
92 my $v = $tape_pos;
93 $v = (($v & 0x0f) << 4) | (($v & 0xf0) >> 4);
94 $v = (($v & 0x33) << 2) | (($v & 0xcc) >> 2);
95 $v = (($v & 0x55) << 1) | (($v & 0xaa) >> 1);
96 push @v, $v;
97 }
98 $$iovalue = $tape_pos;
99 $fh->read_binary(pack("C*", @v));
100 }
101
102 sub _ra_clc_16 {
103 my ($iovalue, $values, $fh, $nl) = @_;
104 my $value = pack("C*", grep { $_ > 0 } @$values);
105 $fh->read_text(baudot2ascii($value) . ($nl ? "\n" : ''));
106 }
107
108 sub _ra_clc_32 {
109 my ($iovalue, $values, $fh, $nl) = @_;
110 my $line = '';
111 my $io = 172;
112 for my $value (@$values) {
113 next if ! $value;
114 my $val0 = $value;
115 my $bits0 = 0;
116 my $bits1 = 0;
117 my $i;
118 for ($i = 0; $i < 8; $i++) {
119 $bits0 >>= 1;
120 $bits1 >>= 1;
121 $bits0 |= 0x80 if $val0 & 2;
122 $bits1 |= 0x80 if $val0 & 1;
123 $val0 >>= 2;
124 }
125 $val0 = 0;
126 for ($i = 0; $i < 8; $i++) {
127 $val0 >>= 1;
128 if ($io & 1) {
129 $val0 |= 0x80 if $bits0 & 1;
130 $bits0 >>= 1;
131 } else {
132 $val0 |= 0x80 if ! ($bits1 & 1);
133 $bits1 >>= 1;
134 }
135 $io >>= 1;
136 }
137 $line .= chr($val0);
138 $io = $val0;
139 }
140 $fh->read_binary($line);
141 }
142
143 sub write_array_16 {
144 @_ == 4
145 or croak 'Usage: write_array_16(IOTYPE, \$IOVALUE, FILEHANDLE, SIZE';
146 my ($iotype, $iovalue, $fh, $size) = @_;
147 my $iocode = iotype($iotype) or faint(SP_IOTYPE, $iotype);
148 &{$iotypes[$iocode - 1][3]}($iovalue, $fh, $size);
149 }
150
151 sub write_array_32 {
152 @_ == 4
153 or croak 'Usage: write_array_32(IOTYPE, \$IOVALUE, FILEHANDLE, SIZE';
154 my ($iotype, $iovalue, $fh, $size) = @_;
155 my $iocode = iotype($iotype) or faint(SP_IOTYPE, $iotype);
156 &{$iotypes[$iocode - 1][4]}($iovalue, $fh, $size);
157 }
158
159 sub _wa_c {
160 my ($iovalue, $fh, $size) = @_;
161 my $line = $fh->write_binary($size);
162 my @values = unpack("C*", $line);
163 my $tape_pos = $$iovalue;
164 for my $chr (@values) {
165 my $c = $chr;
166 $chr = (256 + $chr - $tape_pos) & 0xff;
167 $tape_pos = $c;
168 }
169 push @values, 256 while @values < $size;
170 $$iovalue = $tape_pos;
171 @values;
172 }
173
174 sub _wa_clc_16 {
175 my ($iovalue, $fh, $size) = @_;
176 my $line = $fh->write_text();
177 defined $line or return ();
178 chomp $line;
179 $line = ascii2baudot($line);
180 unpack("C*", $line);
181 }
182
183 sub _wa_clc_32 {
184 my ($iovalue, $fh, $size) = @_;
185 my $line = $fh->write_binary($size);
186 my @values = unpack("C*", $line);
187 my $ptr = 0;
188 my @val = ();
189 my $io = 172;
190 for my $datum (@values) {
191 my $chr = $datum;
192 my $chr0 = $chr;
193 my $bits0 = 0;
194 my $bits1 = 0;
195 for (my $i = 0; $i < 8; $i++) {
196 if ($io & 0x80) {
197 $bits0 <<= 1;
198 $bits0 |= 1 if $chr & 0x80;
199 } else {
200 $bits1 <<= 1;
201 $bits1 |= 1 if ! ($chr & 0x80);
202 }
203 $chr <<= 1;
204 $io <<= 1;
205 }
206 $chr = int(rand 0xffff) + 1;
207 for (my $i = 0; $i < 8; $i++) {
208 $chr <<= 2;
209 $chr |= 2 if $bits0 & 0x80;
210 $chr |= 1 if $bits1 & 0x80;
211 $bits0 <<= 1;
212 $bits1 <<= 1;
213 }
214 $datum = $chr;
215 $io = $chr0;
216 }
217 @values;
218 }
219
220 1;