comparison interps/clc-intercal/CLC-INTERCAL-Base-1.-94.-2/INTERCAL/DoubleOhSeven.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::DoubleOhSeven;
2
3 # Special version of Language::INTERCAL::Numbers used for "double-oh-seven"
4 # registers
5
6 # This file is part of CLC-INTERCAL
7
8 # Copyright (c) 2006-2008 Claudio Calvelli, all rights reserved.
9
10 # CLC-INTERCAL is copyrighted software. However, permission to use, modify,
11 # and distribute it is granted provided that the conditions set out in the
12 # licence agreement are met. See files README and COPYING in the distribution.
13
14 use strict;
15 use vars qw($VERSION $PERVERSION);
16 ($VERSION) = ($PERVERSION = "CLC-INTERCAL/Base INTERCAL/DoubleOhSeven.pm 1.-94.-2") =~ /\s(\S+)$/;
17
18 use Carp;
19 use Language::INTERCAL::Exporter '1.-94.-2';
20 use Language::INTERCAL::Splats '1.-94.-2', qw(:SP splatname);
21 use Language::INTERCAL::Numbers '1.-94.-2';
22 use Language::INTERCAL::ReadNumbers '1.-94.-2', qw(roman_type roman_name);
23 use Language::INTERCAL::Charset '1.-94.-2', qw(charset charset_name);
24 use Language::INTERCAL::ArrayIO '1.-94.-2', qw(iotype iotype_name);
25 use vars qw(@ISA);
26 @ISA = qw(Language::INTERCAL::Numbers::Spot);
27
28 my %types = (
29 base => [2, \&_code_base, undef],
30 charset => [0, \&_code_charset, \&_decode_charset],
31 comefrom => [0, \&_code_comefrom, undef],
32 crawlhorror => [1, \&_code_crawlhorror, undef],
33 iotype => [0, \&_code_iotype, \&_decode_iotype],
34 roman => [0, \&_code_roman, \&_decode_roman],
35 splat => [1000, \&_code_splat, \&_decode_splat],
36 spot => [0, undef, undef],
37 symbol => [0, \&_code_symbol, \&_decode_symbol],
38 zeroone => [0, \&_code_zeroone, undef],
39 );
40
41 sub new {
42 @_ == 3 || @_ == 4
43 or croak "Usage: Language::INTERCAL::DoubleOhSeven" .
44 "->new(TYPE, OBJECT [,VALUE])";
45 my ($class, $type, $object, @value) = @_;
46 exists $types{$type} or faint(SP_SPECIAL, "(type $type)");
47 @value = ($types{$type}[0]) unless @value;
48 return Language::INTERCAL::Numbers::Spot->new(@value)
49 if ! defined $types{$type}[1];
50 @value = &{$types{$type}[1]}($object, @value);
51 # note, we don't use SUPER here, rather we rebless later
52 my $num = Language::INTERCAL::Numbers::Spot->new(@value);
53 $num->{doubleohseven} = {
54 object => $object,
55 type => $types{$type}[1],
56 typename => $type,
57 decode => $types{$type}[2],
58 };
59 bless $num, $class;
60 }
61
62 sub type {
63 @_ == 1 or croak "Usage: DOUBLEOHSEVEN->type";
64 my ($num) = @_;
65 $num->{doubleohseven}{typename};
66 }
67
68 sub print {
69 @_ == 1 or croak "Usage: DOUBLEOHSEVEN->print";
70 my ($num) = @_;
71 my $d = $num->{doubleohseven};
72 $d->{decode} or return $num->SUPER::print;
73 &{$d->{decode}}($d->{object}, $num->number);
74 }
75
76 sub _assign {
77 @_ == 2 or croak "Usage: DOUBLEOHSEVEN->assign(VALUE)";
78 my ($num, $value) = @_;
79 exists $num->{doubleohseven} or faint(SP_NOSPECIAL);
80 $num->{doubleohseven}{type} or faint(SP_NOSPECIAL);
81 $value =
82 &{$num->{doubleohseven}{type}}($num->{doubleohseven}{object}, $value);
83 $num->SUPER::_assign($value);
84 $num;
85 }
86
87 sub _get_number {
88 my ($value, $translate, $splat) = @_;
89 faint(SP_NOASSIGN, '(undef)', 'Not a number') if ! defined $value;
90 return $value->spot->number
91 if ref $value && UNIVERSAL::isa($value, 'Language::INTERCAL::Numbers');
92 return $value
93 if ! ref $value && defined $value && $value =~ /^\d+$/;
94 if ($translate) {
95 if (ref $value) {
96 my @num = ();
97 if (ref $value eq 'ARRAY') {
98 @num = map { _get_number($_, $translate) } @$value;
99 } elsif (UNIVERSAL::isa($value, 'Language::INTERCAL::Arrays')) {
100 @num = map { $_->spot->number } $value->as_list;
101 } else {
102 faint(SP_NOASSIGN, $value, 'Not a number');
103 }
104 $value = pack('C*', @num);
105 }
106 my $t = &{$translate}($value);
107 defined $t or faint($splat, $value);
108 return $t;
109 }
110 faint(SP_NOASSIGN, $value, 'Not a number');
111 }
112
113 sub _decode {
114 my ($value, $code) = @_;
115 my $nv = $code->($value);
116 return "?$nv" if defined $nv && $nv ne '';
117 "#$value";
118 }
119
120 sub _code_base {
121 my ($object, $value) = @_;
122 $value = _get_number($value);
123 $value < 2 || $value > 7
124 and faint(SP_BASE, $value);
125 $value;
126 }
127
128 sub _code_charset {
129 my ($object, $value) = @_;
130 _get_number($value, \&charset, SP_CHARSET);
131 }
132
133 sub _decode_charset {
134 my ($object, $value) = @_;
135 _decode($value, \&charset_name);
136 }
137
138 sub _code_comefrom {
139 my ($object, $value) = @_;
140 $value = _get_number($value);
141 $value < 0 || $value > 3
142 and faint(SP_NOASSIGN, $value,
143 'come from value must be between 0 and 3');
144 $value;
145 }
146
147 sub _code_crawlhorror {
148 my ($object, $value) = @_;
149 $object or faint(SP_CONTEXT, 'missing grammar');
150 my $c = _get_number($value);
151 $c < 1 || $c > $object->num_parsers
152 and faint(SP_NOASSIGN, $value, 'grammar number out of range');
153 $c;
154 }
155
156 sub _code_iotype {
157 my ($object, $value) = @_;
158 _get_number($value, \&iotype, SP_IOTYPE);
159 }
160
161 sub _decode_iotype {
162 my ($object, $value) = @_;
163 _decode($value, \&iotype_name);
164 }
165
166 sub _code_roman {
167 my ($object, $value) = @_;
168 _get_number($value, \&roman_type, SP_ROMAN);
169 }
170
171 sub _decode_roman {
172 my ($object, $value) = @_;
173 _decode($value, \&roman_name);
174 }
175
176 sub _code_splat {
177 my ($object, $value) = @_;
178 _get_number($value, \&_splat_type, SP_INVSPLAT);
179 }
180
181 sub _splat_type {
182 my ($code) = @_;
183 defined splatname($code) ? $code : 1000;
184 }
185
186 sub _decode_splat {
187 my ($object, $value) = @_;
188 $value < 1000 ? $value : undef;
189 }
190
191 sub _code_symbol {
192 my ($object, $value) = @_;
193 $object or faint(SP_CONTEXT, 'symbol without grammar');
194 _get_number($value, sub { $object->symboltable->find(@_) }, SP_SYMBOL);
195 }
196
197 sub _decode_symbol {
198 my ($object, $value) = @_;
199 _decode($value, sub { $object->symboltable->symbol(@_) } );
200 }
201
202 sub _code_zeroone {
203 my ($object, $value) = @_;
204 $value = _get_number($value);
205 $value < 0 || $value > 1
206 and faint(SP_NOASSIGN, $value, 'value must be 0 or 1');
207 $value;
208 }
209
210 1;