Subversion Repositories Kolibri OS

Rev

Rev 7597 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
7597 akron1 1
(*
2
    BSD 2-Clause License
3
 
4
    Copyright (c) 2018, 2019, Anton Krotov
5
    All rights reserved.
6
*)
7
 
8
MODULE ARITH;
9
 
7693 akron1 10
IMPORT AVLTREES, STRINGS, UTILS;
7597 akron1 11
 
12
 
13
CONST
14
 
15
    tINTEGER* = 1;  tREAL* = 2;  tSET*    = 3;
16
    tBOOLEAN* = 4;  tCHAR* = 5;  tWCHAR*  = 6;
17
    tSTRING*  = 7;
18
 
19
 
20
TYPE
21
 
22
    RELATION* = ARRAY 3 OF CHAR;
23
 
24
    VALUE* = RECORD
25
 
26
        typ*:      INTEGER;
27
 
28
        int:       INTEGER;
29
        float:     REAL;
30
        set:       SET;
31
        bool:      BOOLEAN;
32
 
33
        string*:   AVLTREES.DATA
34
 
35
    END;
36
 
37
 
38
VAR
39
 
40
    digit: ARRAY 256 OF INTEGER;
41
 
42
 
43
PROCEDURE Int* (v: VALUE): INTEGER;
44
VAR
45
    res: INTEGER;
46
 
47
BEGIN
48
 
49
    IF v.typ = tINTEGER THEN
50
        res := v.int
51
    ELSIF v.typ = tCHAR THEN
52
        res := v.int
53
    ELSIF v.typ = tWCHAR THEN
54
        res := v.int
55
    ELSIF v.typ = tSET THEN
7693 akron1 56
        res := UTILS.Long(ORD(v.set))
7597 akron1 57
    ELSIF v.typ = tBOOLEAN THEN
58
        res := ORD(v.bool)
59
    END
60
 
61
    RETURN res
62
END Int;
63
 
64
 
65
PROCEDURE getBool* (v: VALUE): BOOLEAN;
66
BEGIN
67
    ASSERT(v.typ = tBOOLEAN);
68
 
69
    RETURN v.bool
70
END getBool;
71
 
72
 
73
PROCEDURE Float* (v: VALUE): REAL;
74
BEGIN
75
    ASSERT(v.typ = tREAL);
76
 
77
    RETURN v.float
78
END Float;
79
 
80
 
81
PROCEDURE check* (v: VALUE): BOOLEAN;
82
VAR
83
    error: BOOLEAN;
84
 
85
BEGIN
86
    error := FALSE;
87
 
7693 akron1 88
    IF (v.typ = tINTEGER) & ((v.int < UTILS.target.minInt) OR (v.int > UTILS.target.maxInt)) THEN
7597 akron1 89
        error := TRUE
90
    ELSIF (v.typ = tCHAR) & ((v.int < 0) OR (v.int > 255)) THEN
91
        error := TRUE
92
    ELSIF (v.typ = tWCHAR) & ((v.int < 0) OR (v.int > 65535)) THEN
93
        error := TRUE
7693 akron1 94
    ELSIF (v.typ = tREAL) & ((v.float < -UTILS.target.maxReal) OR (v.float > UTILS.target.maxReal)) THEN
7597 akron1 95
        error := TRUE
96
    END
97
 
98
    RETURN ~error
99
END check;
100
 
101
 
102
PROCEDURE isZero* (v: VALUE): BOOLEAN;
103
VAR
104
    res: BOOLEAN;
105
BEGIN
106
    ASSERT(v.typ IN {tINTEGER, tREAL});
107
 
108
    IF v.typ = tINTEGER THEN
109
        res := v.int = 0
110
    ELSIF v.typ = tREAL THEN
111
        res := v.float = 0.0
112
    END
113
 
114
    RETURN res
115
END isZero;
116
 
117
 
118
PROCEDURE iconv* (s: ARRAY OF CHAR; VAR v: VALUE; VAR error: INTEGER);
119
VAR
120
    value: INTEGER;
121
    i:     INTEGER;
122
    d:     INTEGER;
123
 
124
BEGIN
125
    error := 0;
126
    value := 0;
127
 
128
    i := 0;
129
    WHILE STRINGS.digit(s[i]) & (error = 0) DO
130
        d := digit[ORD(s[i])];
131
        IF value <= (UTILS.maxint - d) DIV 10 THEN
132
            value := value * 10 + d;
133
            INC(i)
134
        ELSE
135
            error := 1
136
        END
137
    END;
138
 
139
    IF error = 0 THEN
140
        v.int := value;
141
        v.typ := tINTEGER;
142
        IF ~check(v) THEN
143
            error := 1
144
        END
145
    END
146
 
147
END iconv;
148
 
149
 
150
PROCEDURE hconv* (s: ARRAY OF CHAR; VAR v: VALUE; VAR error: INTEGER);
151
VAR
152
    value: INTEGER;
153
    i:     INTEGER;
154
    n:     INTEGER;
155
    d:     INTEGER;
156
 
157
BEGIN
158
    ASSERT(STRINGS.digit(s[0]));
159
 
160
    error := 0;
161
    value := 0;
162
 
163
    n := -1;
164
    i := 0;
165
    WHILE (s[i] # "H") & (s[i] # "X") & (error = 0) DO
166
 
167
        d := digit[ORD(s[i])];
168
        IF (n = -1) & (d # 0) THEN
169
            n := i
170
        END;
171
 
7693 akron1 172
        IF (n # -1) & (i - n + 1 > UTILS.target.maxHex) THEN
7597 akron1 173
            error := 2
174
        ELSE
175
            value := value * 16 + d;
176
            INC(i)
177
        END
178
 
179
    END;
180
 
7693 akron1 181
    value := UTILS.Long(value);
7597 akron1 182
 
183
    IF (s[i] = "X") & (n # -1) & (i - n > 4) THEN
184
        error := 3
185
    END;
186
 
187
    IF error = 0 THEN
188
        v.int := value;
189
        IF s[i] = "X" THEN
190
            v.typ := tCHAR;
191
            IF ~check(v) THEN
192
                v.typ := tWCHAR;
193
                IF ~check(v) THEN
194
                    error := 3
195
                END
196
            END
197
        ELSE
198
            v.typ := tINTEGER;
199
            IF ~check(v) THEN
200
                error := 2
201
            END
202
        END
203
    END
204
 
205
END hconv;
206
 
207
 
208
PROCEDURE opFloat2 (VAR a: REAL; b: REAL; op: CHAR): BOOLEAN;
209
VAR
210
    max: REAL;
211
    res: BOOLEAN;
212
 
213
BEGIN
214
    max := UTILS.maxreal;
215
 
216
    CASE op OF
217
    |"+":
218
        IF (a < 0.0) & (b < 0.0) THEN
219
            res := a > -max - b
220
        ELSIF (a > 0.0) & (b > 0.0) THEN
221
            res := a <  max - b
222
        ELSE
223
            res := TRUE
224
        END;
225
        IF res THEN
226
            a := a + b
227
        END
228
 
229
    |"-":
230
        IF (a < 0.0) & (b > 0.0) THEN
231
            res := a > b - max
232
        ELSIF (a > 0.0) & (b < 0.0) THEN
233
            res := a < b + max
234
        ELSE
235
            res := TRUE
236
        END;
237
        IF res THEN
238
            a := a - b
239
        END
240
 
241
    |"*":
242
        IF (ABS(a) > 1.0) & (ABS(b) > 1.0) THEN
243
            res := ABS(a) < max / ABS(b)
244
        ELSE
245
            res := TRUE
246
        END;
247
        IF res THEN
248
            a := a * b
249
        END
250
 
251
    |"/":
252
        IF ABS(b) < 1.0 THEN
253
            res := ABS(a) < max * ABS(b)
254
        ELSE
255
            res := TRUE
256
        END;
257
        IF res THEN
258
            a := a / b
259
        END
260
 
261
    END
262
 
263
    RETURN res
264
END opFloat2;
265
 
266
 
267
PROCEDURE fconv* (s: ARRAY OF CHAR; VAR v: VALUE; VAR error: INTEGER);
268
VAR
269
    value:    REAL;
270
    exp10:    REAL;
271
    i, n, d:  INTEGER;
272
    minus:    BOOLEAN;
273
 
274
BEGIN
275
    error := 0;
276
    value := 0.0;
277
    exp10 := 10.0;
278
    minus := FALSE;
279
    n := 0;
280
 
281
    i := 0;
282
    WHILE (error = 0) & STRINGS.digit(s[i]) DO
283
        IF opFloat2(value, 10.0, "*") & opFloat2(value, FLT(digit[ORD(s[i])]), "+") THEN
284
            INC(i)
285
        ELSE
286
            error := 4
287
        END
288
    END;
289
 
290
    INC(i);
291
 
292
    WHILE (error = 0) & STRINGS.digit(s[i]) DO
293
        IF opFloat2(value, FLT(digit[ORD(s[i])]) / exp10, "+") & opFloat2(exp10, 10.0, "*") THEN
294
            INC(i)
295
        ELSE
296
            error := 4
297
        END
298
    END;
299
 
300
    IF s[i] = "E" THEN
301
        INC(i)
302
    END;
303
 
304
    IF (s[i] = "-") OR (s[i] = "+") THEN
305
        minus := s[i] = "-";
306
        INC(i)
307
    END;
308
 
309
    WHILE (error = 0) & STRINGS.digit(s[i]) DO
310
        d := digit[ORD(s[i])];
311
        IF n <= (UTILS.maxint - d) DIV 10 THEN
312
            n := n * 10 + d;
313
            INC(i)
314
        ELSE
315
            error := 5
316
        END
317
    END;
318
 
319
    exp10 := 1.0;
320
    WHILE (error = 0) & (n > 0) DO
321
        IF opFloat2(exp10, 10.0, "*") THEN
322
            DEC(n)
323
        ELSE
324
            error := 4
325
        END
326
    END;
327
 
328
    IF error = 0 THEN
329
        IF minus THEN
330
            IF ~opFloat2(value, exp10, "/") THEN
331
                error := 4
332
            END
333
        ELSE
334
            IF ~opFloat2(value, exp10, "*") THEN
335
                error := 4
336
            END
337
        END
338
    END;
339
 
340
    IF error = 0 THEN
341
        v.float := value;
342
        v.typ := tREAL;
343
        IF ~check(v) THEN
344
            error := 4
345
        END
346
    END
347
 
348
END fconv;
349
 
350
 
351
PROCEDURE setChar* (VAR v: VALUE; ord: INTEGER);
352
BEGIN
353
    v.typ := tCHAR;
354
    v.int := ord
355
END setChar;
356
 
357
 
358
PROCEDURE setWChar* (VAR v: VALUE; ord: INTEGER);
359
BEGIN
360
    v.typ := tWCHAR;
361
    v.int := ord
362
END setWChar;
363
 
364
 
365
PROCEDURE addInt (VAR a: INTEGER; b: INTEGER): BOOLEAN;
366
VAR
367
    error: BOOLEAN;
368
 
369
BEGIN
370
    IF (a > 0) & (b > 0) THEN
371
        error := a > UTILS.maxint - b
372
    ELSIF (a < 0) & (b < 0) THEN
373
        error := a < UTILS.minint - b
374
    ELSE
375
        error := FALSE
376
    END;
377
 
378
    IF ~error THEN
379
        a := a + b
380
    ELSE
381
        a := 0
382
    END
383
 
384
    RETURN ~error
385
END addInt;
386
 
387
 
388
PROCEDURE subInt (VAR a: INTEGER; b: INTEGER): BOOLEAN;
389
VAR
390
    error: BOOLEAN;
391
 
392
BEGIN
393
    IF (a > 0) & (b < 0) THEN
394
        error := a > UTILS.maxint + b
395
    ELSIF (a < 0) & (b > 0) THEN
396
        error := a < UTILS.minint + b
397
    ELSIF (a = 0) & (b < 0) THEN
398
        error := b = UTILS.minint
399
    ELSE
400
        error := FALSE
401
    END;
402
 
403
    IF ~error THEN
404
        a := a - b
405
    ELSE
406
        a := 0
407
    END
408
 
409
    RETURN ~error
410
END subInt;
411
 
412
 
413
PROCEDURE lg2 (x: INTEGER): INTEGER;
414
VAR
415
    n: INTEGER;
416
 
417
BEGIN
418
    ASSERT(x > 0);
419
 
420
    n := 0;
421
    WHILE ~ODD(x) DO
422
        x := x DIV 2;
423
        INC(n)
424
    END;
425
 
426
    IF x # 1 THEN
427
        n := 255
428
    END
429
 
430
    RETURN n
431
END lg2;
432
 
433
 
434
PROCEDURE mulInt* (VAR a: INTEGER; b: INTEGER): BOOLEAN;
435
VAR
436
    error:    BOOLEAN;
437
    min, max: INTEGER;
438
 
439
BEGIN
440
    min := UTILS.minint;
441
    max := UTILS.maxint;
442
 
443
    IF ((a > 1) & (b > 1)) OR ((a < 0) & (b < 0)) THEN
444
        error := (a = min) OR (b = min) OR (ABS(a) > max DIV ABS(b))
445
 
446
    ELSIF ((a > 1) & (b < 0)) OR ((a < 0) & (b > 1)) THEN
447
        error := (a = min) OR (b = min);
448
        IF ~error THEN
449
            IF lg2(ABS(a)) + lg2(ABS(b)) >= UTILS.bit_depth THEN
450
                error := ABS(a) > max DIV ABS(b)
451
            END
452
        END
453
 
454
    ELSE
455
        error := FALSE
456
    END;
457
 
458
    IF ~error THEN
459
        a := a * b
460
    ELSE
461
        a := 0
462
    END
463
 
464
    RETURN ~error
465
END mulInt;
466
 
467
 
468
PROCEDURE _ASR (x, n: INTEGER): INTEGER;
7693 akron1 469
    RETURN ASR(UTILS.Long(x), n)
7597 akron1 470
END _ASR;
471
 
472
 
473
PROCEDURE _LSR (x, n: INTEGER): INTEGER;
7693 akron1 474
    RETURN UTILS.Long(LSR(UTILS.Short(x), n))
7597 akron1 475
END _LSR;
476
 
477
 
478
PROCEDURE _LSL (x, n: INTEGER): INTEGER;
7693 akron1 479
    RETURN UTILS.Long(LSL(x, n))
7597 akron1 480
END _LSL;
481
 
482
 
483
PROCEDURE _ROR1_32 (x: INTEGER): INTEGER;
484
BEGIN
7693 akron1 485
    x := UTILS.Short(x);
7597 akron1 486
    x := ORD(BITS(LSR(x, 1)) + BITS(LSL(x, 31)))
7693 akron1 487
    RETURN UTILS.Long(x)
7597 akron1 488
END _ROR1_32;
489
 
490
 
7693 akron1 491
PROCEDURE _ROR1_16 (x: INTEGER): INTEGER;
492
BEGIN
493
    x := x MOD 65536;
494
    x := ORD(BITS(LSR(x, 1)) + BITS(LSL(x, 15)))
495
    RETURN UTILS.Long(x)
496
END _ROR1_16;
497
 
498
 
7597 akron1 499
PROCEDURE _ROR (x, n: INTEGER): INTEGER;
500
BEGIN
7693 akron1 501
 
502
    CASE UTILS.bit_diff OF
503
    |0: x := ROR(x, n)
504
    |16, 48:
505
        n := n MOD 16;
506
        WHILE n > 0 DO
507
            x := _ROR1_16(x);
508
            DEC(n)
509
        END
510
    |32:
7597 akron1 511
        n := n MOD 32;
512
        WHILE n > 0 DO
513
            x := _ROR1_32(x);
514
            DEC(n)
515
        END
516
    END
517
 
518
    RETURN x
519
END _ROR;
520
 
521
 
522
PROCEDURE opInt* (VAR a: VALUE; b: VALUE; op: CHAR): BOOLEAN;
523
VAR
524
    success: BOOLEAN;
525
 
526
BEGIN
527
    success := TRUE;
528
 
529
    CASE op OF
530
    |"+": success := addInt(a.int, b.int)
531
    |"-": success := subInt(a.int, b.int)
532
    |"*": success := mulInt(a.int, b.int)
533
    |"/": success := FALSE
534
    |"D": IF (b.int # -1) OR (a.int # UTILS.minint) THEN a.int := a.int DIV b.int ELSE success := FALSE END
535
    |"M": a.int := a.int MOD b.int
536
    |"L": a.int := _LSL(a.int, b.int)
537
    |"A": a.int := _ASR(a.int, b.int)
538
    |"O": a.int := _ROR(a.int, b.int)
539
    |"R": a.int := _LSR(a.int, b.int)
540
    |"m": a.int := MIN(a.int, b.int)
541
    |"x": a.int := MAX(a.int, b.int)
542
    END;
543
    a.typ := tINTEGER
544
 
545
    RETURN success & check(a)
546
END opInt;
547
 
548
 
549
PROCEDURE charToStr* (c: VALUE; VAR s: ARRAY OF CHAR);
550
BEGIN
551
    s[0] := CHR(c.int);
552
    s[1] := 0X
553
END charToStr;
554
 
555
 
556
PROCEDURE opSet* (VAR a: VALUE; b: VALUE; op: CHAR);
557
BEGIN
558
    CASE op OF
559
    |"+": a.set := a.set + b.set
560
    |"-": a.set := a.set - b.set
561
    |"*": a.set := a.set * b.set
562
    |"/": a.set := a.set / b.set
563
    END;
564
    a.typ := tSET
565
END opSet;
566
 
567
 
568
PROCEDURE opFloat* (VAR a: VALUE; b: VALUE; op: CHAR): BOOLEAN;
569
BEGIN
570
    a.typ := tREAL
571
    RETURN opFloat2(a.float, b.float, op) & check(a)
572
END opFloat;
573
 
574
 
575
PROCEDURE ord* (VAR v: VALUE);
576
BEGIN
577
    CASE v.typ OF
578
    |tCHAR, tWCHAR:
579
    |tBOOLEAN: v.int := ORD(v.bool)
7693 akron1 580
    |tSET:     v.int := UTILS.Long(ORD(v.set))
7597 akron1 581
    END;
582
    v.typ := tINTEGER
583
END ord;
584
 
585
 
586
PROCEDURE odd* (VAR v: VALUE);
587
BEGIN
588
    v.typ := tBOOLEAN;
589
    v.bool := ODD(v.int)
590
END odd;
591
 
592
 
593
PROCEDURE bits* (VAR v: VALUE);
594
BEGIN
595
    v.typ := tSET;
596
    v.set := BITS(v.int)
597
END bits;
598
 
599
 
600
PROCEDURE abs* (VAR v: VALUE): BOOLEAN;
601
VAR
602
    res: BOOLEAN;
603
 
604
BEGIN
7693 akron1 605
    res := FALSE;
7597 akron1 606
 
607
    CASE v.typ OF
608
    |tREAL:
609
        v.float := ABS(v.float);
610
        res := TRUE
611
    |tINTEGER:
612
        IF v.int # UTILS.minint THEN
613
            v.int := ABS(v.int);
614
            res := TRUE
615
        END
7693 akron1 616
    END
617
 
7597 akron1 618
    RETURN res
619
END abs;
620
 
621
 
622
PROCEDURE floor* (VAR v: VALUE): BOOLEAN;
623
VAR
624
    res: BOOLEAN;
625
 
626
BEGIN
627
    v.typ := tINTEGER;
628
    res := (FLT(UTILS.minint) <= v.float) & (v.float <= FLT(UTILS.maxint));
629
    IF res THEN
630
        v.int := FLOOR(v.float)
631
    END
632
 
633
    RETURN res
634
END floor;
635
 
636
 
637
PROCEDURE flt* (VAR v: VALUE);
638
BEGIN
639
    v.typ := tREAL;
640
    v.float := FLT(v.int)
641
END flt;
642
 
643
 
644
PROCEDURE neg* (VAR v: VALUE): BOOLEAN;
645
VAR
646
    z: VALUE;
647
    res: BOOLEAN;
648
 
649
BEGIN
650
    res := TRUE;
651
 
652
    z.typ := tINTEGER;
653
    z.int := 0;
654
 
655
    CASE v.typ OF
656
    |tREAL:     v.float := -v.float
657
    |tSET:      v.set := -v.set
658
    |tINTEGER:  res := opInt(z, v, "-"); v := z
659
    |tBOOLEAN:  v.bool := ~v.bool
660
    END
661
 
662
    RETURN res
663
END neg;
664
 
665
 
666
PROCEDURE setbool* (VAR v: VALUE; b: BOOLEAN);
667
BEGIN
668
    v.bool := b;
669
    v.typ := tBOOLEAN
670
END setbool;
671
 
672
 
673
PROCEDURE opBoolean* (VAR a: VALUE; b: VALUE; op: CHAR);
674
BEGIN
675
    CASE op OF
676
    |"&": a.bool := a.bool & b.bool
677
    |"|": a.bool := a.bool OR b.bool
678
    END;
679
    a.typ := tBOOLEAN
680
END opBoolean;
681
 
682
 
683
PROCEDURE range* (i: VALUE; a, b: INTEGER): BOOLEAN;
684
    RETURN (a <= i.int) & (i.int <= b)
685
END range;
686
 
687
 
688
PROCEDURE less (v, v2: VALUE; VAR error: INTEGER): BOOLEAN;
689
VAR
690
    res: BOOLEAN;
691
 
692
BEGIN
693
    res := FALSE;
694
 
695
    IF (v.typ = v2.typ) OR (v.typ IN {tCHAR, tWCHAR}) & (v2.typ IN {tCHAR, tWCHAR}) THEN
696
        CASE v.typ OF
697
        |tINTEGER,
698
         tWCHAR,
699
         tCHAR:     res := v.int < v2.int
700
        |tREAL:     res := v.float < v2.float
701
        |tBOOLEAN,
702
         tSET:      error := 1
703
        END
704
    ELSE
705
        error := 1
706
    END
707
 
708
    RETURN res
709
END less;
710
 
711
 
712
PROCEDURE equal (v, v2: VALUE; VAR error: INTEGER): BOOLEAN;
713
VAR
714
    res: BOOLEAN;
715
 
716
BEGIN
717
    res := FALSE;
718
 
719
    IF (v.typ = v2.typ) OR (v.typ IN {tCHAR, tWCHAR}) & (v2.typ IN {tCHAR, tWCHAR}) THEN
720
        CASE v.typ OF
721
        |tINTEGER,
722
         tWCHAR,
723
         tCHAR:     res := v.int = v2.int
724
        |tREAL:     res := v.float = v2.float
725
        |tBOOLEAN:  res := v.bool = v2.bool
726
        |tSET:      res := v.set = v2.set
727
        END
728
    ELSE
729
        error := 1
730
    END
731
 
732
    RETURN res
733
END equal;
734
 
735
 
736
PROCEDURE relation* (VAR v: VALUE; v2: VALUE; operator: RELATION; VAR error: INTEGER);
737
VAR
738
    res: BOOLEAN;
739
 
740
BEGIN
741
    error := 0;
742
 
743
    res := FALSE;
744
 
745
    CASE operator[0] OF
746
 
747
    |"=":
748
        res := equal(v, v2, error)
749
 
750
    |"#":
751
        res := ~equal(v, v2, error)
752
 
753
    |"<":
754
        IF operator[1] = "=" THEN
755
            res := less(v, v2, error);
756
            IF error = 0 THEN
757
                res := equal(v, v2, error) OR res
758
            END
759
        ELSE
760
            res := less(v, v2, error)
761
        END
762
 
763
    |">":
764
        IF operator[1] = "=" THEN
765
            res := ~less(v, v2, error)
766
        ELSE
767
            res := less(v, v2, error);
768
            IF error = 0 THEN
769
                res := equal(v, v2, error) OR res
770
            END;
771
            res := ~res
772
        END
773
 
774
    |"I":
775
        IF (v.typ = tINTEGER) & (v2.typ = tSET) THEN
7693 akron1 776
            IF range(v, 0, UTILS.target.maxSet) THEN
7597 akron1 777
                res := v.int IN v2.set
778
            ELSE
779
                error := 2
780
            END
781
        ELSE
782
            error := 1
783
        END
784
 
785
    END;
786
 
787
    IF error = 0 THEN
788
        v.bool := res;
789
        v.typ  := tBOOLEAN
790
    END
791
 
792
END relation;
793
 
794
 
795
PROCEDURE emptySet* (VAR v: VALUE);
796
BEGIN
797
    v.typ := tSET;
798
    v.set := {}
799
END emptySet;
800
 
801
 
802
PROCEDURE constrSet* (VAR v: VALUE; a, b: VALUE);
803
BEGIN
804
    v.typ := tSET;
805
    v.set := {a.int .. b.int}
806
END constrSet;
807
 
808
 
809
PROCEDURE getInt* (v: VALUE): INTEGER;
810
BEGIN
811
    ASSERT(check(v))
812
 
813
    RETURN v.int
814
END getInt;
815
 
816
 
817
PROCEDURE setInt* (VAR v: VALUE; i: INTEGER): BOOLEAN;
818
BEGIN
819
    v.int := i;
820
    v.typ := tINTEGER
821
 
822
    RETURN check(v)
823
END setInt;
824
 
825
 
826
PROCEDURE init;
827
VAR
828
    i: INTEGER;
829
 
830
BEGIN
831
    FOR i := 0 TO LEN(digit) - 1 DO
832
        digit[i] := -1
833
    END;
834
 
835
    FOR i := ORD("0") TO ORD("9") DO
836
        digit[i] := i - ORD("0")
837
    END;
838
 
839
    FOR i := ORD("A") TO ORD("F") DO
840
        digit[i] := i - ORD("A") + 10
841
    END
842
END init;
843
 
844
 
845
BEGIN
846
    init
847
END ARITH.