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