Subversion Repositories Kolibri OS

Rev

Rev 7696 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

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