1 /*
2 This file is part of GNU APL, a free implementation of the
3 ISO/IEC Standard 13751, "Programming Language APL, Extended"
4
5 Copyright (C) 2008-2015 Dr. Jürgen Sauermann
6
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #ifndef __INTCELL_HH_DEFINED__
22 #define __INTCELL_HH_DEFINED__
23
24 #include "../config.h" // for RATIONAL_NUMBERS_WANTED
25 #include "RealCell.hh"
26
27 //-----------------------------------------------------------------------------
28 /*!
29 A cell containing a single APL integer. This class essentially
30 overloads certain functions in class Cell with integer specific
31 implementations.
32 */
33 /// A cell containing a single Integer value
34 class IntCell : public RealCell
35 {
36 public:
37 /// Construct an integer cell with value \b i
IntCell(APL_Integer i)38 IntCell(APL_Integer i)
39 { value.ival = i; }
40
41 /// overloaded Cell::init_other
init_other(void * other,Value & cell_owner,const char * loc) const42 virtual void init_other(void * other, Value & cell_owner, const char * loc)
43 const { new (other) IntCell(value.ival); }
44
45 /// overloaded Cell::is_integer_cell()
is_integer_cell() const46 virtual bool is_integer_cell() const
47 { return true; }
48
49 /// overloaded Cell::bif_near_int64_t()
bif_near_int64_t(Cell * Z) const50 virtual ErrorCode bif_near_int64_t(Cell * Z) const
51 { return zv(Z, value.ival); }
52
53 /// overloaded Cell::bif_within_quad_CT()
bif_within_quad_CT(Cell * Z) const54 virtual ErrorCode bif_within_quad_CT(Cell * Z) const
55 { return zv(Z, value.ival); }
56
57 /// overloaded Cell::greater()
58 virtual bool greater(const Cell & other) const;
59
60 /// overloaded Cell::equal()
61 virtual bool equal(const Cell & other, double qct) const;
62
63 /// overloaded Cell::bif_add()
64 virtual ErrorCode bif_add(Cell * Z, const Cell * A) const;
65
66 /// overloaded from the corresponding Cell:: function (see class Cell)
67 virtual ErrorCode bif_ceiling(Cell * Z) const;
68
69 /// overloaded from the corresponding Cell:: function (see class Cell)
70 virtual ErrorCode bif_conjugate(Cell * Z) const;
71
72 /// overloaded from the corresponding Cell:: function (see class Cell)
73 virtual ErrorCode bif_direction(Cell * Z) const;
74
75 /// overloaded Cell::bif_divide()
76 virtual ErrorCode bif_divide(Cell * Z, const Cell * A) const;
77
78 /// overloaded from the corresponding Cell:: function (see class Cell)
79 virtual ErrorCode bif_exponential(Cell * Z) const;
80
81 /// overloaded from the corresponding Cell:: function (see class Cell)
82 virtual ErrorCode bif_factorial(Cell * Z) const;
83
84 /// overloaded from the corresponding Cell:: function (see class Cell)
85 virtual ErrorCode bif_floor(Cell * Z) const;
86
87 /// overloaded from the corresponding Cell:: function (see class Cell)
88 virtual ErrorCode bif_magnitude(Cell * Z) const;
89
90 /// overloaded Cell::bif_multiply()
91 virtual ErrorCode bif_multiply(Cell * Z, const Cell * A) const;
92
93 /// overloaded Cell::bif_power()
94 virtual ErrorCode bif_power(Cell * Z, const Cell * A) const;
95
96 /// overloaded from the corresponding Cell:: function (see class Cell)
97 virtual ErrorCode bif_nat_log(Cell * Z) const;
98
99 /// overloaded from the corresponding Cell:: function (see class Cell)
100 virtual ErrorCode bif_negative(Cell * Z) const;
101
102 /// overloaded from the corresponding Cell:: function (see class Cell)
103 virtual ErrorCode bif_pi_times(Cell * Z) const;
104
105 /// overloaded from the corresponding Cell:: function (see class Cell)
106 virtual ErrorCode bif_pi_times_inverse(Cell * Z) const;
107
108 /// overloaded from the corresponding Cell:: function (see class Cell)
109 virtual ErrorCode bif_reciprocal(Cell * Z) const;
110
111 /// overloaded from the corresponding Cell:: function (see class Cell)
112 virtual ErrorCode bif_roll(Cell * Z) const;
113
114 /// overloaded Cell::bif_subtract()
115 virtual ErrorCode bif_subtract(Cell * Z, const Cell * A) const;
116
117 /// compare this with other, throw DOMAIN ERROR on illegal comparisons
118 virtual Comp_result compare(const Cell & other) const;
119
120 /// overloaded from the corresponding Cell:: function (see class Cell)
121 virtual ErrorCode bif_maximum(Cell * Z, const Cell * A) const;
122
123 /// overloaded from the corresponding Cell:: function (see class Cell)
124 virtual ErrorCode bif_minimum(Cell * Z, const Cell * A) const;
125
126 /// overloaded from the corresponding Cell:: function (see class Cell)
127 virtual ErrorCode bif_residue(Cell * Z, const Cell * A) const;
128
129 /// the Quad_CR representation of this cell
130 virtual PrintBuffer character_representation(const PrintContext &pctx) const;
131
132 /// return true iff this cell needs scaling (exponential format) in pctx
133 /// According to lrm p. 13, integer cells ignore ⎕PP an never use scaling
need_scaling(const PrintContext & pctx) const134 virtual bool need_scaling(const PrintContext &pctx) const
135 { return false; }
136
137 #ifdef RATIONAL_NUMBERS_WANTED
138 /// overloaded Cell::get_numerator()
get_numerator() const139 virtual APL_Integer get_numerator() const
140 { return value.ival; }
141
142 /// overloaded Cell::get_denominator()
get_denominator() const143 virtual APL_Integer get_denominator() const
144 { return 1; }
145 #endif
146
147 /// overloaded Cell::bif_add_inverse()
148 virtual ErrorCode bif_add_inverse(Cell * Z, const Cell * A) const;
149
150 /// overloaded Cell::bif_multiply_inverse()
151 virtual ErrorCode bif_multiply_inverse(Cell * Z, const Cell * A) const;
152
153 /// initialize Z to integer 0
z0(Cell * Z)154 static ErrorCode z0(Cell * Z)
155 { new (Z) IntCell(0); return E_NO_ERROR; }
156
157 /// initialize Z to integer 1
z1(Cell * Z)158 static ErrorCode z1(Cell * Z)
159 { new (Z) IntCell(1); return E_NO_ERROR; }
160
161 /// initialize Z to integer ¯1
z_1(Cell * Z)162 static ErrorCode z_1(Cell * Z)
163 { new (Z) IntCell(-1); return E_NO_ERROR; }
164
165 /// initialize Z to integer v
zv(Cell * Z,APL_Integer v)166 static ErrorCode zv(Cell * Z, APL_Integer v)
167 { new (Z) IntCell(v); return E_NO_ERROR; }
168
169 /// swap \b this Intcell and \b other (for Heapsort<IntCell> )
Hswap(IntCell & other)170 void Hswap(IntCell & other)
171 {
172 const APL_Integer tmp = value.ival;
173 value.ival = other.value.ival;
174 other.value.ival = tmp;
175 }
176
177 /// overloaded Cell::get_int_value()
get_int_value() const178 virtual APL_Integer get_int_value() const { return value.ival; }
179
180 /// overloaded Cell::get_byte_value()
181 virtual int get_byte_value() const;
182
183 /// downcast to const IntCell
cIntlCell() const184 virtual const IntCell & cIntlCell() const { return *this; }
185
186 /// downcast to IntCell
vIntCell()187 virtual IntCell & vIntCell() { return *this; }
188
189 protected:
190 /// overloaded Cell::get_cell_type()
get_cell_type() const191 virtual CellType get_cell_type() const
192 { return CT_INT; }
193
194 /// overloaded Cell::get_cell_subtype()
195 virtual CellType get_cell_subtype() const;
196
197 /// overloaded Cell::get_real_value()
get_real_value() const198 virtual APL_Float get_real_value() const { return APL_Float(value.ival); }
199
200 /// overloaded Cell::get_imag_value()
get_imag_value() const201 virtual APL_Float get_imag_value() const { return 0.0; }
202
203 /// overloaded Cell::get_complex_value()
get_complex_value() const204 virtual APL_Complex get_complex_value() const
205 { return APL_Complex(value.ival, 0.0); }
206
207 /// overloaded Cell::get_near_bool()
get_near_bool() const208 virtual bool get_near_bool() const
209 { if (value.ival == 0) return false;
210 if (value.ival == 1) return true;
211 DOMAIN_ERROR; }
212
213 /// overloaded Cell::get_near_int()
get_near_int() const214 virtual APL_Integer get_near_int() const
215 { return value.ival; }
216
217 /// overloaded Cell::get_checked_near_int()
get_checked_near_int() const218 virtual APL_Integer get_checked_near_int() const
219 { return value.ival; }
220
221 /// overloaded Cell::is_near_zero()
is_near_zero() const222 virtual bool is_near_zero() const
223 { return value.ival == 0; }
224
225 /// overloaded Cell::is_near_one()
is_near_one() const226 virtual bool is_near_one() const
227 { return value.ival == 1; }
228
229 /// overloaded Cell::is_near_int()
is_near_int() const230 virtual bool is_near_int() const
231 { return true; }
232
233 /// overloaded Cell::is_near_int64_t()
is_near_int64_t() const234 virtual bool is_near_int64_t() const
235 { return true; }
236
237 /// overloaded Cell::is_near_real()
is_near_real() const238 virtual bool is_near_real() const
239 { return true; }
240
241 /// overloaded Cell::get_classname()
get_classname() const242 virtual const char * get_classname() const { return "IntCell"; }
243
244 /// overloaded Cell::CDR_size()
245 virtual int CDR_size() const;
246
247 /// overloaded Cell::to_type()
to_type()248 virtual void to_type()
249 { value.ival = 0; }
250 };
251 //-----------------------------------------------------------------------------
252 inline void
Hswap(IntCell & c1,IntCell & c2)253 Hswap(IntCell & c1, IntCell & c2)
254 {
255 c1.Hswap(c2);
256 }
257 //-----------------------------------------------------------------------------
258
259 #endif // __INTCELL_HH_DEFINED__
260