Subversion Repositories Kolibri OS

Rev

Rev 8097 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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