Subversion Repositories Kolibri OS

Rev

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

  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, 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 := UTILS.Long(ORD(v.set))
  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.  
  88.     IF (v.typ = tINTEGER) & ((v.int < UTILS.target.minInt) OR (v.int > UTILS.target.maxInt)) THEN
  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
  94.     ELSIF (v.typ = tREAL) & ((v.float < -UTILS.target.maxReal) OR (v.float > UTILS.target.maxReal)) THEN
  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.  
  172.         IF (n # -1) & (i - n + 1 > UTILS.target.maxHex) THEN
  173.             error := 2
  174.         ELSE
  175.             value := value * 16 + d;
  176.             INC(i)
  177.         END
  178.  
  179.     END;
  180.  
  181.     value := UTILS.Long(value);
  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;
  469.     RETURN ASR(UTILS.Long(x), n)
  470. END _ASR;
  471.  
  472.  
  473. PROCEDURE _LSR (x, n: INTEGER): INTEGER;
  474.     RETURN UTILS.Long(LSR(UTILS.Short(x), n))
  475. END _LSR;
  476.  
  477.  
  478. PROCEDURE _LSL (x, n: INTEGER): INTEGER;
  479.     RETURN UTILS.Long(LSL(x, n))
  480. END _LSL;
  481.  
  482.  
  483. PROCEDURE _ROR1_32 (x: INTEGER): INTEGER;
  484. BEGIN
  485.     x := UTILS.Short(x);
  486.     x := ORD(BITS(LSR(x, 1)) + BITS(LSL(x, 31)))
  487.     RETURN UTILS.Long(x)
  488. END _ROR1_32;
  489.  
  490.  
  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.  
  499. PROCEDURE _ROR (x, n: INTEGER): INTEGER;
  500. BEGIN
  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:
  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)
  580.     |tSET:     v.int := UTILS.Long(ORD(v.set))
  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
  605.     res := FALSE;
  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
  616.     END
  617.  
  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
  776.             IF range(v, 0, UTILS.target.maxSet) THEN
  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.