Subversion Repositories Kolibri OS

Rev

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

  1. (*
  2.     Copyright 2016, 2018 Anton Krotov
  3.  
  4.     This program is free software: you can redistribute it and/or modify
  5.     it under the terms of the GNU Lesser General Public License as published by
  6.     the Free Software Foundation, either version 3 of the License, or
  7.     (at your option) any later version.
  8.  
  9.     This program is distributed in the hope that it will be useful,
  10.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.     GNU Lesser General Public License for more details.
  13.  
  14.     You should have received a copy of the GNU Lesser General Public License
  15.     along with this program.  If not, see <http://www.gnu.org/licenses/>.
  16. *)
  17.  
  18. MODULE Out;
  19.  
  20. IMPORT ConsoleLib, sys := SYSTEM;
  21.  
  22. CONST
  23.  
  24.   d = 1.0 - 5.0E-12;
  25.  
  26. VAR
  27.  
  28.   Realp: PROCEDURE (x: REAL; width: INTEGER);
  29.  
  30. PROCEDURE Char*(c: CHAR);
  31. BEGIN
  32.   ConsoleLib.write_string(sys.ADR(c), 1)
  33. END Char;
  34.  
  35. PROCEDURE String*(s: ARRAY OF CHAR);
  36. BEGIN
  37.   ConsoleLib.write_string(sys.ADR(s[0]), LENGTH(s))
  38. END String;
  39.  
  40. PROCEDURE WriteInt(x, n: INTEGER);
  41. VAR i: INTEGER; a: ARRAY 16 OF CHAR; neg: BOOLEAN;
  42. BEGIN
  43.   i := 0;
  44.   IF n < 1 THEN
  45.     n := 1
  46.   END;
  47.   IF x < 0 THEN
  48.     x := -x;
  49.     DEC(n);
  50.     neg := TRUE
  51.   END;
  52.   REPEAT
  53.     a[i] := CHR(x MOD 10 + ORD("0"));
  54.     x := x DIV 10;
  55.     INC(i)
  56.   UNTIL x = 0;
  57.   WHILE n > i DO
  58.     Char(" ");
  59.     DEC(n)
  60.   END;
  61.   IF neg THEN
  62.     Char("-")
  63.   END;
  64.   REPEAT
  65.     DEC(i);
  66.     Char(a[i])
  67.   UNTIL i = 0
  68. END WriteInt;
  69.  
  70. PROCEDURE IsNan(AValue: REAL): BOOLEAN;
  71. VAR h, l: SET;
  72. BEGIN
  73.   sys.GET(sys.ADR(AValue), l);
  74.   sys.GET(sys.ADR(AValue) + 4, h)
  75.   RETURN (h * {20..30} = {20..30}) & ((h * {0..19} # {}) OR (l * {0..31} # {}))
  76. END IsNan;
  77.  
  78. PROCEDURE IsInf(x: REAL): BOOLEAN;
  79.   RETURN ABS(x) = sys.INF()
  80. END IsInf;
  81.  
  82. PROCEDURE Int*(x, width: INTEGER);
  83. VAR i: INTEGER;
  84. BEGIN
  85.   IF x # 80000000H THEN
  86.     WriteInt(x, width)
  87.   ELSE
  88.     FOR i := 12 TO width DO
  89.       Char(20X)
  90.     END;
  91.     String("-2147483648")
  92.   END
  93. END Int;
  94.  
  95. PROCEDURE OutInf(x: REAL; width: INTEGER);
  96. VAR s: ARRAY 5 OF CHAR; i: INTEGER;
  97. BEGIN
  98.   IF IsNan(x) THEN
  99.     s := "Nan";
  100.     INC(width)
  101.   ELSIF IsInf(x) & (x > 0.0) THEN
  102.     s := "+Inf"
  103.   ELSIF IsInf(x) & (x < 0.0) THEN
  104.     s := "-Inf"
  105.   END;
  106.   FOR i := 1 TO width - 4 DO
  107.     Char(" ")
  108.   END;
  109.   String(s)
  110. END OutInf;
  111.  
  112. PROCEDURE Ln*;
  113. BEGIN
  114.   Char(0DX);
  115.   Char(0AX)
  116. END Ln;
  117.  
  118. PROCEDURE _FixReal(x: REAL; width, p: INTEGER);
  119. VAR e, len, i: INTEGER; y: REAL; minus: BOOLEAN;
  120. BEGIN
  121.   IF IsNan(x) OR IsInf(x) THEN
  122.     OutInf(x, width)
  123.   ELSIF p < 0 THEN
  124.     Realp(x, width)
  125.   ELSE
  126.     len := 0;
  127.     minus := FALSE;
  128.     IF x < 0.0 THEN
  129.       minus := TRUE;
  130.       INC(len);
  131.       x := ABS(x)
  132.     END;
  133.     e := 0;
  134.     WHILE x >= 10.0 DO
  135.       x := x / 10.0;
  136.       INC(e)
  137.     END;
  138.     IF e >= 0 THEN
  139.       len := len + e + p + 1;
  140.       IF x > 9.0 + d THEN
  141.         INC(len)
  142.       END;
  143.       IF p > 0 THEN
  144.         INC(len)
  145.       END
  146.     ELSE
  147.       len := len + p + 2
  148.     END;
  149.     FOR i := 1 TO width - len DO
  150.       Char(" ")
  151.     END;
  152.     IF minus THEN
  153.       Char("-")
  154.     END;
  155.     y := x;
  156.     WHILE (y < 1.0) & (y # 0.0) DO
  157.       y := y * 10.0;
  158.       DEC(e)
  159.     END;
  160.     IF e < 0 THEN
  161.       IF x - FLT(FLOOR(x)) > d THEN
  162.         Char("1");
  163.         x := 0.0
  164.       ELSE
  165.         Char("0");
  166.         x := x * 10.0
  167.       END
  168.     ELSE
  169.       WHILE e >= 0 DO
  170.         IF x - FLT(FLOOR(x)) > d THEN
  171.           IF x > 9.0 THEN
  172.             String("10")
  173.           ELSE
  174.             Char(CHR(FLOOR(x) + ORD("0") + 1))
  175.           END;
  176.           x := 0.0
  177.         ELSE
  178.           Char(CHR(FLOOR(x) + ORD("0")));
  179.           x := (x - FLT(FLOOR(x))) * 10.0
  180.         END;
  181.         DEC(e)
  182.       END
  183.     END;
  184.     IF p > 0 THEN
  185.       Char(".")
  186.     END;
  187.     WHILE p > 0 DO
  188.       IF x - FLT(FLOOR(x)) > d THEN
  189.         Char(CHR(FLOOR(x) + ORD("0") + 1));
  190.         x := 0.0
  191.       ELSE
  192.         Char(CHR(FLOOR(x) + ORD("0")));
  193.         x := (x - FLT(FLOOR(x))) * 10.0
  194.       END;
  195.       DEC(p)
  196.     END
  197.   END
  198. END _FixReal;
  199.  
  200. PROCEDURE Real*(x: REAL; width: INTEGER);
  201. VAR e, n, i: INTEGER; minus: BOOLEAN;
  202. BEGIN
  203.   IF IsNan(x) OR IsInf(x) THEN
  204.     OutInf(x, width)
  205.   ELSE
  206.     e := 0;
  207.     n := 0;
  208.     IF width > 23 THEN
  209.       n := width - 23;
  210.       width := 23
  211.     ELSIF width < 9 THEN
  212.       width := 9
  213.     END;
  214.     width := width - 5;
  215.     IF x < 0.0 THEN
  216.       x := -x;
  217.       minus := TRUE
  218.     ELSE
  219.       minus := FALSE
  220.     END;
  221.     WHILE x >= 10.0 DO
  222.       x := x / 10.0;
  223.       INC(e)
  224.     END;
  225.     WHILE (x < 1.0) & (x # 0.0) DO
  226.       x := x * 10.0;
  227.       DEC(e)
  228.     END;
  229.     IF x > 9.0 + d THEN
  230.       x := 1.0;
  231.       INC(e)
  232.     END;
  233.     FOR i := 1 TO n DO
  234.       Char(" ")
  235.     END;
  236.     IF minus THEN
  237.       x := -x
  238.     END;
  239.     Realp := Real;
  240.     _FixReal(x, width, width - 3);
  241.     Char("E");
  242.     IF e >= 0 THEN
  243.       Char("+")
  244.     ELSE
  245.       Char("-");
  246.       e := ABS(e)
  247.     END;
  248.     IF e < 100 THEN
  249.       Char("0")
  250.     END;
  251.     IF e < 10 THEN
  252.       Char("0")
  253.     END;
  254.     Int(e, 0)
  255.   END
  256. END Real;
  257.  
  258. PROCEDURE FixReal*(x: REAL; width, p: INTEGER);
  259. BEGIN
  260.   Realp := Real;
  261.   _FixReal(x, width, p)
  262. END FixReal;
  263.  
  264. PROCEDURE Open*;
  265. END Open;
  266.  
  267. END Out.