Subversion Repositories Kolibri OS

Rev

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