Subversion Repositories Kolibri OS

Rev

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

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