~ubuntu-branches/ubuntu/wily/afnix/wily

« back to all changes in this revision

Viewing changes to src/lib/std/shl/Integer.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Anibal Monsalve Salazar
  • Date: 2011-03-16 21:31:18 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20110316213118-gk4k3ez3e5d2huna
Tags: 2.0.0-1
* QA upload.
* New upstream release
* Debian source format is 3.0 (quilt)
* Fix debhelper-but-no-misc-depends
* Fix ancient-standards-version
* Fix package-contains-linda-override
* debhelper compatibility is 7
* Fix dh-clean-k-is-deprecated

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// ---------------------------------------------------------------------------
 
2
// - Integer.cpp                                                             -
 
3
// - standard object library - integer class implementation                  -
 
4
// ---------------------------------------------------------------------------
 
5
// - This program is free software;  you can redistribute it  and/or  modify -
 
6
// - it provided that this copyright notice is kept intact.                  -
 
7
// -                                                                         -
 
8
// - This program  is  distributed in  the hope  that it will be useful, but -
 
9
// - without  any  warranty;  without  even   the   implied    warranty   of -
 
10
// - merchantability or fitness for a particular purpose.  In no event shall -
 
11
// - the copyright holder be liable for any  direct, indirect, incidental or -
 
12
// - special damages arising in any way out of the use of this software.     -
 
13
// ---------------------------------------------------------------------------
 
14
// - copyright (c) 1999-2011 amaury darsch                                   -
 
15
// ---------------------------------------------------------------------------
 
16
 
 
17
#include "Real.hpp"
 
18
#include "Stdsid.hxx"
 
19
#include "Vector.hpp"
 
20
#include "Utility.hpp"
 
21
#include "Boolean.hpp"
 
22
#include "Runnable.hpp"
 
23
#include "QuarkZone.hpp"
 
24
#include "Character.hpp"
 
25
#include "Exception.hpp"
 
26
#include "InputStream.hpp"
 
27
#include "OutputStream.hpp"
 
28
#include "ccnv.hpp"
 
29
 
 
30
namespace afnix {
 
31
 
 
32
  // -------------------------------------------------------------------------
 
33
  // - public section                                                        -
 
34
  // -------------------------------------------------------------------------
 
35
 
 
36
  // compute the opposite of the current integer
 
37
  
 
38
  Integer operator - (const Integer& x) {
 
39
    x.rdlock ();
 
40
    try {
 
41
      Integer result = -x.d_value;
 
42
      x.unlock ();
 
43
      return result;
 
44
    } catch (...) {
 
45
      x.unlock ();
 
46
      throw;
 
47
    }
 
48
  }
 
49
  
 
50
  // add two integers together from two integers
 
51
 
 
52
  Integer operator + (const Integer& x, const Integer& y) {
 
53
    x.rdlock ();
 
54
    y.rdlock ();
 
55
    try {
 
56
      Integer result = x.d_value + y.d_value;
 
57
      x.unlock ();
 
58
      y.unlock ();
 
59
      return result;
 
60
    } catch (...) {
 
61
      x.unlock ();
 
62
      y.unlock ();
 
63
      throw;
 
64
    }
 
65
  }
 
66
 
 
67
  // substract two integers together from two integers
 
68
  
 
69
  Integer operator - (const Integer& x, const Integer& y) {
 
70
    x.rdlock ();
 
71
    y.rdlock ();
 
72
    try {
 
73
      Integer result = x.d_value - y.d_value;
 
74
      x.unlock ();
 
75
      y.unlock ();
 
76
      return result;
 
77
    } catch (...) {
 
78
      x.unlock ();
 
79
      y.unlock ();
 
80
      throw;
 
81
    }
 
82
  }
 
83
  
 
84
  // multiply two integers together from two integers
 
85
  
 
86
  Integer operator * (const Integer& x, const Integer& y) {
 
87
    x.rdlock ();
 
88
    y.rdlock ();
 
89
    try {
 
90
      Integer result = x.d_value * y.d_value;
 
91
      x.unlock ();
 
92
      y.unlock ();
 
93
      return result;
 
94
    } catch (...) {
 
95
      x.unlock ();
 
96
      y.unlock ();
 
97
      throw;
 
98
    }
 
99
  }
 
100
    
 
101
  // divide two integers together from two integers
 
102
  
 
103
  Integer operator / (const Integer& x, const Integer& y) {
 
104
    x.rdlock ();
 
105
    y.rdlock ();
 
106
    try {
 
107
      if (y.d_value == 0) {
 
108
        throw Exception ("integer-error","division by zero");
 
109
      }
 
110
      Integer result = x.d_value / y.d_value;
 
111
      x.unlock ();
 
112
      y.unlock ();
 
113
      return result;
 
114
    } catch (...) {
 
115
      x.unlock ();
 
116
      y.unlock ();
 
117
      throw;
 
118
    }
 
119
  }
 
120
 
 
121
  // return the remainder of this number with its argument
 
122
 
 
123
  Integer operator % (const Integer& x, const Integer& y) {
 
124
    x.rdlock ();
 
125
    y.rdlock ();
 
126
    try {
 
127
      if (y.d_value == 0) {
 
128
        throw Exception ("integer-error","division by zero");
 
129
      }
 
130
      Integer result = x.d_value % y.d_value;
 
131
      x.unlock ();
 
132
      y.unlock ();
 
133
      return result;
 
134
    } catch (...) {
 
135
      x.unlock ();
 
136
      y.unlock ();
 
137
      throw;
 
138
    }
 
139
  }
 
140
 
 
141
  // bitwise negate an integer
 
142
  Integer operator ~ (const Integer& x) {
 
143
    x.rdlock ();
 
144
    try {
 
145
      Integer result = ~x.d_value;
 
146
      x.unlock ();
 
147
      return result;
 
148
    } catch (...) {
 
149
      x.unlock ();
 
150
      throw;
 
151
    }
 
152
  }
 
153
 
 
154
  // bitwise and an integer with another one
 
155
 
 
156
  Integer operator & (const Integer& x, const Integer& y) {
 
157
    x.rdlock ();
 
158
    y.rdlock ();
 
159
    try {
 
160
      Integer result = x.d_value & y.d_value;
 
161
      x.unlock ();
 
162
      y.unlock ();
 
163
      return result;
 
164
    } catch (...) {
 
165
      x.unlock ();
 
166
      y.unlock ();
 
167
      throw;
 
168
    }
 
169
  }
 
170
 
 
171
  // bitwise or an integer with another one
 
172
 
 
173
  Integer operator | (const Integer& x, const Integer& y) {
 
174
    x.rdlock ();
 
175
    y.rdlock ();
 
176
    try {
 
177
      Integer result = x.d_value | y.d_value;
 
178
      x.unlock ();
 
179
      y.unlock ();
 
180
      return result;
 
181
    } catch (...) {
 
182
      x.unlock ();
 
183
      y.unlock ();
 
184
      throw;
 
185
    }
 
186
  }
 
187
 
 
188
  // bitwise xor an integer with another one
 
189
 
 
190
  Integer operator ^ (const Integer& x, const Integer& y) {
 
191
    x.rdlock ();
 
192
    y.rdlock ();
 
193
    try {
 
194
      Integer result = x.d_value ^ y.d_value;
 
195
      x.unlock ();
 
196
      y.unlock ();
 
197
      return result;
 
198
    } catch (...) {
 
199
      x.unlock ();
 
200
      y.unlock ();
 
201
      throw;
 
202
    }
 
203
  }
 
204
 
 
205
  // -------------------------------------------------------------------------
 
206
  // - class section                                                         -
 
207
  // -------------------------------------------------------------------------
 
208
 
 
209
  // create a new default integer
 
210
  
 
211
  Integer::Integer (void) {
 
212
    d_value = 0;
 
213
  }
 
214
 
 
215
  // create a new integer from a long integer
 
216
 
 
217
  Integer::Integer (const t_long value) {
 
218
    d_value = value;
 
219
  }
 
220
 
 
221
  // create a new integer from a string
 
222
 
 
223
  Integer::Integer (const String& value) {
 
224
    d_value = Utility::tolong (value);
 
225
  }
 
226
  
 
227
  // copy constructor for this integer
 
228
 
 
229
  Integer::Integer (const Integer& that) {
 
230
    that.rdlock ();
 
231
    try {
 
232
      d_value = that.d_value;
 
233
      that.unlock ();
 
234
    } catch (...) {
 
235
      that.unlock ();
 
236
      throw;
 
237
    }
 
238
  }
 
239
 
 
240
  // return the class name
 
241
 
 
242
  String Integer::repr (void) const {
 
243
    return "Integer";
 
244
  }
 
245
 
 
246
  // return a clone of this object
 
247
 
 
248
  Object* Integer::clone (void) const {
 
249
    return new Integer (*this);
 
250
  }
 
251
 
 
252
  // return a literal representation of this integer
 
253
 
 
254
  String Integer::toliteral (void) const {
 
255
    rdlock ();
 
256
    try {
 
257
      String result = tostring ();
 
258
      unlock ();
 
259
      return result;
 
260
    } catch (...) {
 
261
      unlock ();
 
262
      throw;
 
263
    }
 
264
  }
 
265
 
 
266
  // get a string representation on this integer
 
267
 
 
268
  String Integer::tostring (void) const {
 
269
    rdlock ();
 
270
    try {
 
271
      String result = Utility::tostring (d_value);
 
272
      unlock ();
 
273
      return result;
 
274
    } catch (...) {
 
275
      unlock ();
 
276
      throw;
 
277
    }
 
278
  }
 
279
 
 
280
  // return the integer serial code
 
281
 
 
282
  t_byte Integer::serialid (void) const {
 
283
    return SERIAL_INTG_ID;
 
284
  }
 
285
 
 
286
  // serialize this integer
 
287
 
 
288
  void Integer::wrstream (OutputStream& os) const {
 
289
    rdlock ();
 
290
    try {
 
291
      t_byte data[8];
 
292
      c_ohton (d_value, data);
 
293
      os.write ((char*) data, 8);
 
294
      unlock ();
 
295
    } catch (...) {
 
296
      unlock ();
 
297
      throw;
 
298
    }
 
299
  }
 
300
 
 
301
  // deserialize this integer
 
302
 
 
303
  void Integer::rdstream (InputStream& is) {
 
304
    wrlock ();
 
305
    try {
 
306
      t_byte data[8];
 
307
      for (long i = 0; i < 8; i++) data[i] = (t_byte) is.read ();
 
308
      d_value = c_ontoh (data);
 
309
      unlock ();
 
310
    } catch (...) {
 
311
      unlock ();
 
312
      throw;
 
313
    }
 
314
  }
 
315
  
 
316
  // set an integer with a value
 
317
 
 
318
  Integer& Integer::operator = (const t_long value) {
 
319
    wrlock ();
 
320
    try {
 
321
      d_value = value;
 
322
      unlock ();
 
323
      return *this;
 
324
    } catch (...) {
 
325
      unlock ();
 
326
      throw;
 
327
    }
 
328
  }
 
329
 
 
330
  // set an integer with a value
 
331
 
 
332
  Integer& Integer::operator = (const Integer& that) {
 
333
   // check for self assignation
 
334
    if (this == &that) return *this;
 
335
    // lock and assign
 
336
    wrlock ();
 
337
    that.rdlock ();
 
338
    try {
 
339
      d_value = that.d_value;
 
340
      unlock ();
 
341
      that.unlock ();
 
342
      return *this;
 
343
    } catch (...) {
 
344
      unlock ();
 
345
      that.unlock ();
 
346
      throw;
 
347
    }
 
348
  }
 
349
 
 
350
  // add an integer to this one
 
351
 
 
352
  Integer& Integer::operator += (const Integer& x) {
 
353
    wrlock   ();
 
354
    x.rdlock ();
 
355
    try {
 
356
      d_value += x.d_value;
 
357
      unlock   ();
 
358
      x.unlock ();
 
359
      return *this;
 
360
    } catch (...) {
 
361
      unlock   ();
 
362
      x.unlock ();
 
363
      throw;
 
364
    }
 
365
  }
 
366
 
 
367
  // substract an integer to this one
 
368
  
 
369
  Integer& Integer::operator -= (const Integer& x) {
 
370
    wrlock   ();
 
371
    x.rdlock ();
 
372
    try {
 
373
      d_value -= x.d_value;
 
374
      unlock ();
 
375
      x.unlock   ();
 
376
      return *this;
 
377
    } catch (...) {
 
378
      unlock   ();
 
379
      x.unlock ();
 
380
      throw;
 
381
    }
 
382
  }
 
383
 
 
384
  // multiply an integer with this one
 
385
  
 
386
  Integer& Integer::operator *= (const Integer& x) {
 
387
    wrlock   ();
 
388
    x.rdlock ();
 
389
    try {
 
390
      d_value *= x.d_value;
 
391
      unlock ();
 
392
      x.unlock   ();
 
393
      return *this;
 
394
    } catch (...) {
 
395
      unlock   ();
 
396
      x.unlock ();
 
397
      throw;
 
398
    }
 
399
  }
 
400
 
 
401
  // divide an integer with this one
 
402
  
 
403
  Integer& Integer::operator /= (const Integer& x) {
 
404
    wrlock   ();
 
405
    x.rdlock ();
 
406
    try {
 
407
      if (x.d_value == 0) {
 
408
        throw Exception ("integer-error","division by zero");
 
409
      }
 
410
      d_value /= x.d_value;
 
411
      unlock ();
 
412
      x.unlock   ();
 
413
      return *this;
 
414
    } catch (...) {
 
415
      unlock   ();
 
416
      x.unlock ();
 
417
      throw;
 
418
    }
 
419
  }
 
420
 
 
421
  // prefix add one to the integer
 
422
 
 
423
  Integer& Integer::operator ++ (void) {
 
424
    wrlock ();
 
425
    try {
 
426
      ++d_value;
 
427
      unlock ();
 
428
      return *this;
 
429
    } catch (...) {
 
430
      unlock ();
 
431
      throw;
 
432
    }
 
433
  }
 
434
 
 
435
  // postfix add one to the integer
 
436
 
 
437
  Integer Integer::operator ++ (int) {
 
438
    wrlock ();
 
439
    try {
 
440
      Integer result = *this;
 
441
      d_value++;
 
442
      unlock ();
 
443
      return result;
 
444
    } catch (...) {
 
445
      unlock ();
 
446
      throw;
 
447
    }
 
448
  }
 
449
 
 
450
  // prefix sub one to the integer
 
451
 
 
452
  Integer& Integer::operator -- (void) {
 
453
    wrlock ();
 
454
    try {
 
455
      --d_value;
 
456
      unlock ();
 
457
      return *this;
 
458
    } catch (...) {
 
459
      unlock ();
 
460
      throw;
 
461
    }
 
462
  }
 
463
 
 
464
  // postfix sub one to the integer
 
465
 
 
466
  Integer Integer::operator -- (int) {
 
467
    wrlock ();
 
468
    try {
 
469
      Integer result = *this;
 
470
      d_value--;
 
471
      unlock ();
 
472
      return result;
 
473
    } catch (...) {
 
474
      unlock ();
 
475
      throw;
 
476
    }
 
477
  }
 
478
 
 
479
  // shift left this integer
 
480
 
 
481
  Integer Integer::operator << (const long asl) const {
 
482
    rdlock ();
 
483
    try {
 
484
      Integer result = d_value << (asl % 64);
 
485
      unlock ();
 
486
      return result;
 
487
    } catch (...) {
 
488
      unlock ();
 
489
      throw;
 
490
    }
 
491
  }
 
492
 
 
493
  // shift right this integer
 
494
 
 
495
  Integer Integer::operator >> (const long asr) const {
 
496
    rdlock ();
 
497
    try {
 
498
      Integer result = d_value >> (asr % 64);
 
499
      unlock ();
 
500
      return result;
 
501
    } catch (...) {
 
502
      unlock ();
 
503
      throw;
 
504
    }
 
505
  }
 
506
 
 
507
  // compare an integer with a native value
 
508
 
 
509
  bool Integer::operator == (const t_long value) const {
 
510
    rdlock ();
 
511
    try {
 
512
      bool result = (d_value == value);
 
513
      unlock ();
 
514
      return result;
 
515
    } catch (...) {
 
516
      unlock ();
 
517
      throw;
 
518
    }
 
519
  }
 
520
 
 
521
  bool Integer::operator != (const t_long value) const {
 
522
    rdlock ();
 
523
    try {
 
524
      bool result = (d_value != value);
 
525
      unlock ();
 
526
      return result;
 
527
    } catch (...) {
 
528
      unlock ();
 
529
      throw;
 
530
    }
 
531
  }
 
532
 
 
533
  // compare two integers
 
534
 
 
535
  bool Integer::operator == (const Integer& value) const {
 
536
    rdlock ();
 
537
    value.rdlock ();
 
538
    try {
 
539
      bool result = (d_value == value.d_value);
 
540
      unlock ();
 
541
      value.unlock ();
 
542
      return result;
 
543
    } catch (...) {
 
544
      unlock ();
 
545
      value.unlock ();
 
546
      throw;
 
547
    }
 
548
  }
 
549
 
 
550
  // compare two integers
 
551
 
 
552
  bool Integer::operator != (const Integer& value) const {
 
553
    rdlock ();
 
554
    value.rdlock ();
 
555
    try {
 
556
      bool result = (d_value != value.d_value);
 
557
      unlock ();
 
558
      value.unlock ();
 
559
      return result;
 
560
    } catch (...) {
 
561
      unlock ();
 
562
      value.unlock ();
 
563
      throw;
 
564
    }
 
565
  }
 
566
 
 
567
  // compare two integers
 
568
 
 
569
  bool Integer::operator < (const Integer& value) const {
 
570
    rdlock ();
 
571
    value.rdlock ();
 
572
    try {
 
573
      bool result = (d_value <  value.d_value);
 
574
      unlock ();
 
575
      value.unlock ();
 
576
      return result;
 
577
    } catch (...) {
 
578
      unlock ();
 
579
      value.unlock ();
 
580
      throw;
 
581
    }
 
582
  }
 
583
 
 
584
  // compare two integers
 
585
 
 
586
  bool Integer::operator <= (const Integer& value) const {
 
587
    rdlock ();
 
588
    value.rdlock ();
 
589
    try {
 
590
      bool result = (d_value <= value.d_value);
 
591
      unlock ();
 
592
      value.unlock ();
 
593
      return result;
 
594
    } catch (...) {
 
595
      unlock ();
 
596
      value.unlock ();
 
597
      throw;
 
598
    }
 
599
  }
 
600
  
 
601
  // compare two integers
 
602
 
 
603
  bool Integer::operator > (const Integer& value) const {
 
604
    rdlock ();
 
605
    value.rdlock ();
 
606
    try {
 
607
      bool result = (d_value > value.d_value);
 
608
      unlock ();
 
609
      value.unlock ();
 
610
      return result;
 
611
    } catch (...) {
 
612
      unlock ();
 
613
      value.unlock ();
 
614
      throw;
 
615
    }
 
616
  }
 
617
 
 
618
  // compare two integers
 
619
 
 
620
  bool Integer::operator >= (const Integer& value) const {
 
621
    rdlock ();
 
622
    value.rdlock ();
 
623
    try {
 
624
      bool result = (d_value >= value.d_value);
 
625
      unlock ();
 
626
      value.unlock ();
 
627
      return result;
 
628
    } catch (...) {
 
629
      unlock ();
 
630
      value.unlock ();
 
631
      throw;
 
632
    }
 
633
  }
 
634
 
 
635
  // return true if the integer is zero
 
636
 
 
637
  bool Integer::iszero (void) const {
 
638
    rdlock ();
 
639
    try {
 
640
      bool result = (d_value == 0);
 
641
      unlock ();
 
642
      return result;
 
643
    } catch (...) {
 
644
      unlock ();
 
645
      throw;
 
646
    }
 
647
  }
 
648
 
 
649
  // return true if the integer is even
 
650
 
 
651
  bool Integer::iseven (void) const {
 
652
    rdlock ();
 
653
    try {
 
654
      bool result = ((d_value & 1) == 0);
 
655
      unlock ();
 
656
      return result;
 
657
    } catch (...) {
 
658
      unlock ();
 
659
      throw;
 
660
    }
 
661
  }
 
662
 
 
663
  // return true if the integer is odd
 
664
 
 
665
  bool Integer::isodd (void) const {
 
666
    rdlock ();
 
667
    try {
 
668
      bool result = ((d_value & 1) == 1);
 
669
      unlock ();
 
670
      return result;
 
671
    } catch (...) {
 
672
      unlock ();
 
673
      throw;
 
674
    }
 
675
  }
 
676
 
 
677
  // return the absolute value of this number
 
678
 
 
679
  Integer Integer::abs (void) const {
 
680
    rdlock ();
 
681
    try {
 
682
      Integer result = (d_value < 0) ? -d_value : d_value;
 
683
      unlock ();
 
684
      return result;
 
685
    } catch (...) {
 
686
      unlock ();
 
687
      throw;
 
688
    }
 
689
  }
 
690
 
 
691
  // convert this integer into a hexadecimal representation
 
692
 
 
693
  String Integer::tohexa (void) const {
 
694
    rdlock ();
 
695
    try {
 
696
      // prepare result string
 
697
      String result = (d_value < 0) ? "-0x" : "0x";
 
698
      // bind the integer value
 
699
      t_octa data = d_value < 0 ? -d_value : d_value;
 
700
      result += Utility::tohexa (data);
 
701
      // unlock and return
 
702
      unlock ();
 
703
      return result;
 
704
    } catch (...) {
 
705
      unlock ();
 
706
      throw;
 
707
    }
 
708
  }
 
709
 
 
710
  // convert this integer into a hexadecimal string
 
711
 
 
712
  String Integer::tohstr (void) const {
 
713
    rdlock ();
 
714
    try {
 
715
      // bind the integer value
 
716
      t_octa data = d_value < 0 ? -d_value : d_value;
 
717
      String result = Utility::tohexa (data);
 
718
      // unlock and return
 
719
      unlock ();
 
720
      return result;
 
721
    } catch (...) {
 
722
      unlock ();
 
723
      throw;
 
724
    }
 
725
  }
 
726
 
 
727
  // return a native integer value
 
728
 
 
729
  t_long Integer::tolong (void) const {
 
730
    rdlock ();
 
731
    try {
 
732
      t_long result = d_value;
 
733
      unlock ();
 
734
      return result;
 
735
    } catch (...) {
 
736
      unlock ();
 
737
      throw;
 
738
    }
 
739
  }
 
740
 
 
741
  // -------------------------------------------------------------------------
 
742
  // - object section                                                        -
 
743
  // -------------------------------------------------------------------------
 
744
 
 
745
  // the quark zone
 
746
  static const long QUARK_ZONE_LENGTH = 27;
 
747
  static QuarkZone  zone (QUARK_ZONE_LENGTH);
 
748
 
 
749
  // the object supported quarks
 
750
  static const long QUARK_OR    = zone.intern ("or");
 
751
  static const long QUARK_OPP   = zone.intern ("++");
 
752
  static const long QUARK_OMM   = zone.intern ("--");
 
753
  static const long QUARK_ADD   = zone.intern ("+");
 
754
  static const long QUARK_SUB   = zone.intern ("-");
 
755
  static const long QUARK_MUL   = zone.intern ("*");
 
756
  static const long QUARK_DIV   = zone.intern ("/");
 
757
  static const long QUARK_EQL   = zone.intern ("==");
 
758
  static const long QUARK_NEQ   = zone.intern ("!=");
 
759
  static const long QUARK_LTH   = zone.intern ("<");
 
760
  static const long QUARK_LEQ   = zone.intern ("<=");
 
761
  static const long QUARK_GTH   = zone.intern (">");
 
762
  static const long QUARK_GEQ   = zone.intern (">=");
 
763
  static const long QUARK_AEQ   = zone.intern ("+=");
 
764
  static const long QUARK_SEQ   = zone.intern ("-=");
 
765
  static const long QUARK_MEQ   = zone.intern ("*=");
 
766
  static const long QUARK_DEQ   = zone.intern ("/=");
 
767
  static const long QUARK_ABS   = zone.intern ("abs");
 
768
  static const long QUARK_AND   = zone.intern ("and");
 
769
  static const long QUARK_SHL   = zone.intern ("shl");
 
770
  static const long QUARK_SHR   = zone.intern ("shr");
 
771
  static const long QUARK_XOR   = zone.intern ("xor");
 
772
  static const long QUARK_MOD   = zone.intern ("mod");
 
773
  static const long QUARK_NOT   = zone.intern ("not");
 
774
  static const long QUARK_ODDP  = zone.intern ("odd-p");
 
775
  static const long QUARK_EVENP = zone.intern ("even-p");
 
776
  static const long QUARK_ZEROP = zone.intern ("zero-p");
 
777
 
 
778
  // evaluate an object to a native value
 
779
 
 
780
  t_long Integer::evalto (Runnable* robj, Nameset* nset, Object* object) {
 
781
    Object* obj = (object == nilp) ? nilp : object->eval (robj, nset);
 
782
    Integer* val = dynamic_cast <Integer*> (obj);
 
783
    if (val == nilp) throw Exception ("type-error", "nil object to evaluate");
 
784
    return val->tolong ();
 
785
  }
 
786
 
 
787
  // create a new object in a generic way
 
788
 
 
789
  Object* Integer::mknew (Vector* argv) {
 
790
    if ((argv == nilp) || (argv->length () == 0)) return new Integer;
 
791
    if (argv->length () != 1) 
 
792
      throw Exception ("argument-error", 
 
793
                       "too many argument with integer constructor");
 
794
    // try to map the integer argument
 
795
    Object* obj = argv->get (0);
 
796
    if (obj == nilp) return new Integer;
 
797
 
 
798
    // try an integer object
 
799
    Integer* ival = dynamic_cast <Integer*> (obj);
 
800
    if (ival != nilp) return new Integer (*ival);
 
801
 
 
802
    // try a real object
 
803
    Real* rval = dynamic_cast <Real*> (obj);
 
804
    if (rval != nilp) return new Integer (rval->tolong ());
 
805
 
 
806
    // try a character object
 
807
    Character* cval = dynamic_cast <Character*> (obj);
 
808
    if (cval != nilp) return new Integer (cval->toquad ());
 
809
 
 
810
    // try a string object
 
811
    String* sval = dynamic_cast <String*> (obj);
 
812
    if (sval != nilp) return new Integer (*sval);
 
813
 
 
814
    // illegal object
 
815
    throw Exception ("type-error", "illegal object with integer constructor",
 
816
                     obj->repr ());
 
817
  }
 
818
 
 
819
  // return true if the given quark is defined
 
820
 
 
821
  bool Integer::isquark (const long quark, const bool hflg) const {
 
822
    rdlock ();
 
823
    if (zone.exists (quark) == true) {
 
824
      unlock ();
 
825
      return true;
 
826
    }
 
827
    bool result = hflg ? Number::isquark (quark, hflg) : false;
 
828
    unlock ();
 
829
    return result;
 
830
  }
 
831
 
 
832
  // operate this object with another object
 
833
 
 
834
  Object* Integer::oper (t_oper type, Object* object) {
 
835
    Integer* iobj = dynamic_cast <Integer*> (object);
 
836
    Real*    dobj = dynamic_cast <Real*>    (object);
 
837
    switch (type) {
 
838
    case Object::ADD:
 
839
      if (iobj != nilp) return new Integer (*this + *iobj);
 
840
      if (dobj != nilp) return new Integer (*this + dobj->tolong ());
 
841
      break;
 
842
    case Object::SUB:
 
843
      if (iobj != nilp) return new Integer (*this - *iobj);
 
844
      if (dobj != nilp) return new Integer (*this - dobj->tolong ());
 
845
      break;
 
846
    case Object::MUL:
 
847
      if (iobj != nilp) return new Integer (*this * *iobj);
 
848
      if (dobj != nilp) return new Integer (*this * dobj->tolong ());
 
849
      break;
 
850
    case Object::DIV:
 
851
      if (iobj != nilp) return new Integer (*this / *iobj);
 
852
      if (dobj != nilp) return new Integer (*this / dobj->tolong ());
 
853
      break;
 
854
    case Object::UMN:
 
855
      return new Integer (-(*this));
 
856
      break;
 
857
    case Object::EQL:
 
858
      if (iobj != nilp) return new Boolean (*this == *iobj);
 
859
      if (dobj != nilp) return new Boolean (*this == dobj->tolong ());
 
860
      break;
 
861
    case Object::NEQ:
 
862
      if (iobj != nilp) return new Boolean (*this != *iobj);
 
863
      if (dobj != nilp) return new Boolean (*this != dobj->tolong ());
 
864
      break;
 
865
    case Object::GEQ:
 
866
      if (iobj != nilp) return new Boolean (*this >= *iobj);
 
867
      if (dobj != nilp) return new Boolean (*this >= dobj->tolong ());
 
868
      break;
 
869
    case Object::GTH:
 
870
      if (iobj != nilp) return new Boolean (*this > *iobj);
 
871
      if (dobj != nilp) return new Boolean (*this > dobj->tolong ());
 
872
      break;
 
873
    case Object::LEQ:
 
874
      if (iobj != nilp) return new Boolean (*this <= *iobj);
 
875
      if (dobj != nilp) return new Boolean (*this <= dobj->tolong ());
 
876
      break;
 
877
    case Object::LTH:
 
878
      if (iobj != nilp) return new Boolean (*this < *iobj);
 
879
      if (dobj != nilp) return new Boolean (*this < dobj->tolong ());
 
880
      break;
 
881
    }
 
882
    throw Exception ("type-error", "invalid operand with integer",
 
883
                     Object::repr (object));
 
884
  }
 
885
 
 
886
  // set an object to this integer
 
887
 
 
888
  Object* Integer::vdef (Runnable* robj, Nameset* nset, Object* object) {
 
889
    wrlock ();
 
890
    try {
 
891
      Integer* iobj = dynamic_cast <Integer*> (object);
 
892
      if (iobj != nilp) {
 
893
        *this = *iobj;
 
894
        robj->post (this);
 
895
        unlock ();
 
896
        return this;
 
897
      }
 
898
      Real* dobj = dynamic_cast <Real*> (object);
 
899
      if (dobj != nilp) {
 
900
        *this = dobj->tolong ();
 
901
        robj->post (this);
 
902
        unlock ();
 
903
        return this;
 
904
      }
 
905
      Character* cobj = dynamic_cast <Character*> (object);
 
906
      if (cobj != nilp) {
 
907
        *this = (t_long) cobj->toquad ();
 
908
        robj->post (this);
 
909
        unlock ();
 
910
        return this;
 
911
      }
 
912
      throw Exception ("type-error", "invalid object with integer vdef",
 
913
                       Object::repr (object));
 
914
    } catch (...) {
 
915
      unlock ();
 
916
      throw;
 
917
    }
 
918
  }
 
919
 
 
920
  // apply this object with a set of arguments and a quark
 
921
 
 
922
  Object* Integer::apply (Runnable* robj, Nameset* nset, const long quark,
 
923
                          Vector* argv) {
 
924
    // get the number of arguments
 
925
    long argc = (argv == nilp) ? 0 : argv->length ();
 
926
 
 
927
    // dispatch 0 argument
 
928
    if (argc == 0) {
 
929
      if (quark == QUARK_ABS)   return new Integer (abs    ());
 
930
      if (quark == QUARK_EVENP) return new Boolean (iseven ());
 
931
      if (quark == QUARK_ODDP)  return new Boolean (isodd  ());
 
932
      if (quark == QUARK_ZEROP) return new Boolean (iszero ());
 
933
 
 
934
      if (quark == QUARK_NOT)   return new Integer (~(*this));
 
935
      if (quark == QUARK_OPP) {
 
936
        wrlock ();
 
937
        try {
 
938
          ++(*this);
 
939
          robj->post (this);
 
940
          unlock ();
 
941
          return this;
 
942
        } catch (...) {
 
943
          unlock ();
 
944
          throw;
 
945
        }
 
946
      }
 
947
      if (quark == QUARK_OMM) {
 
948
        wrlock ();
 
949
        try {
 
950
          --(*this);
 
951
          robj->post (this);
 
952
          unlock ();
 
953
          return this;
 
954
        } catch (...) {
 
955
          unlock ();
 
956
          throw;
 
957
        }
 
958
      } 
 
959
    }
 
960
    // dispatch 1 argument
 
961
    if (argc == 1) {
 
962
      if (quark == QUARK_ADD) return oper (Object::ADD, argv->get (0));
 
963
      if (quark == QUARK_SUB) return oper (Object::SUB, argv->get (0));
 
964
      if (quark == QUARK_MUL) return oper (Object::MUL, argv->get (0));
 
965
      if (quark == QUARK_DIV) return oper (Object::DIV, argv->get (0));
 
966
      if (quark == QUARK_EQL) return oper (Object::EQL, argv->get (0));
 
967
      if (quark == QUARK_NEQ) return oper (Object::NEQ, argv->get (0));
 
968
      if (quark == QUARK_LTH) return oper (Object::LTH, argv->get (0));
 
969
      if (quark == QUARK_LEQ) return oper (Object::LEQ, argv->get (0));
 
970
      if (quark == QUARK_GTH) return oper (Object::GTH, argv->get (0));
 
971
      if (quark == QUARK_GEQ) return oper (Object::GEQ, argv->get (0));
 
972
 
 
973
      if (quark == QUARK_AEQ) {
 
974
        wrlock ();
 
975
        try {
 
976
          t_long val = argv->getlong (0);
 
977
          *this += val;
 
978
          robj->post (this);
 
979
          unlock ();
 
980
          return this;
 
981
        } catch (...) {
 
982
          unlock ();
 
983
          throw;
 
984
        }
 
985
      }
 
986
      if (quark == QUARK_SEQ) {
 
987
        wrlock ();
 
988
        try {
 
989
          t_long val = argv->getlong (0);
 
990
          *this -= val;
 
991
          robj->post (this);
 
992
          unlock ();
 
993
          return this;
 
994
        } catch (...) {
 
995
          unlock ();
 
996
          throw;
 
997
        }
 
998
      }
 
999
      if (quark == QUARK_MEQ) {
 
1000
        wrlock ();
 
1001
        try {
 
1002
          t_long val = argv->getlong (0);
 
1003
          *this *= val;
 
1004
          robj->post (this);
 
1005
          unlock ();
 
1006
          return this;
 
1007
        } catch (...) {
 
1008
          unlock ();
 
1009
          throw;
 
1010
        }
 
1011
      }
 
1012
      if (quark == QUARK_DEQ) {
 
1013
        wrlock ();
 
1014
        try {
 
1015
          t_long val = argv->getlong (0);
 
1016
          *this /= val;
 
1017
          robj->post (this);
 
1018
          unlock ();
 
1019
          return this;
 
1020
        } catch (...) {
 
1021
          unlock ();
 
1022
          throw;
 
1023
        }
 
1024
      }
 
1025
      if (quark == QUARK_MOD) {
 
1026
        t_long val = argv->getlong (0);
 
1027
        return new Integer (*this % val);
 
1028
      }
 
1029
      if (quark == QUARK_SHL) {
 
1030
        t_long asl = argv->getlong (0);
 
1031
        Object* result = new Integer (*this << asl);
 
1032
        return result;
 
1033
      }
 
1034
      if (quark == QUARK_SHR) {
 
1035
        t_long asr = argv->getlong (0);
 
1036
        Object* result = new Integer (*this >> asr);
 
1037
        return result;
 
1038
      }
 
1039
      if (quark == QUARK_XOR) {
 
1040
        t_long val = argv->getlong (0);
 
1041
        Object* result = new Integer (*this ^ val);
 
1042
        return result;
 
1043
      }
 
1044
      if (quark == QUARK_AND) {
 
1045
        t_long val = argv->getlong (0);
 
1046
        Object* result = new Integer (*this & val);
 
1047
        return result;
 
1048
      }
 
1049
      if (quark == QUARK_OR) {
 
1050
        t_long val = argv->getlong (0);
 
1051
        Object* result = new Integer (*this | val);
 
1052
        return result;
 
1053
      }
 
1054
    } 
 
1055
    // call the number method
 
1056
    return Number::apply (robj, nset, quark, argv);
 
1057
  }
 
1058
}