Subversion Repositories Kolibri OS

Rev

Rev 7693 | 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.     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 check* (v: VALUE): BOOLEAN;
  79. VAR
  80.     res: BOOLEAN;
  81.  
  82. BEGIN
  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)
  88.     END
  89.  
  90.     RETURN res
  91. END check;
  92.  
  93.  
  94. PROCEDURE isZero* (v: VALUE): BOOLEAN;
  95. VAR
  96.     res: BOOLEAN;
  97.  
  98. BEGIN
  99.     CASE v.typ OF
  100.     |tINTEGER: res := v.int = 0
  101.     |tREAL:    res := v.float = 0.0
  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.  
  162.         IF (n # -1) & (i - n + 1 > UTILS.target.maxHex) THEN
  163.             error := 2
  164.         ELSE
  165.             value := value * 16 + d;
  166.             INC(i)
  167.         END
  168.  
  169.     END;
  170.  
  171.     value := UTILS.Long(value);
  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;
  459.     RETURN ASR(UTILS.Long(x), n)
  460. END _ASR;
  461.  
  462.  
  463. PROCEDURE _LSR (x, n: INTEGER): INTEGER;
  464.     RETURN UTILS.Long(LSR(UTILS.Short(x), n))
  465. END _LSR;
  466.  
  467.  
  468. PROCEDURE _LSL (x, n: INTEGER): INTEGER;
  469.     RETURN UTILS.Long(LSL(x, n))
  470. END _LSL;
  471.  
  472.  
  473. PROCEDURE _ROR1_32 (x: INTEGER): INTEGER;
  474. BEGIN
  475.     x := UTILS.Short(x);
  476.     x := ORD(BITS(LSR(x, 1)) + BITS(LSL(x, 31)))
  477.     RETURN UTILS.Long(x)
  478. END _ROR1_32;
  479.  
  480.  
  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.  
  489. PROCEDURE _ROR (x, n: INTEGER): INTEGER;
  490. BEGIN
  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:
  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)
  570.     |tSET:     v.int := UTILS.Long(ORD(v.set))
  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
  595.     res := FALSE;
  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
  606.     END
  607.  
  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
  766.             IF range(v, 0, UTILS.target.maxSet) THEN
  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
  837. END ARITH.
  838.