Subversion Repositories Kolibri OS

Rev

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

  1. (*
  2.     Copyright 2013, 2014, 2017, 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 sys := SYSTEM, WINAPI;
  21.  
  22. CONST
  23.  
  24.   d = 1.0 - 5.0E-12;
  25.  
  26. VAR
  27.  
  28.   hConsoleOutput: INTEGER;
  29.   Realp: PROCEDURE (x: REAL; width: INTEGER);
  30.  
  31.  
  32. PROCEDURE String*(s: ARRAY OF CHAR);
  33. VAR count: INTEGER;
  34. BEGIN
  35.   WINAPI.WriteFile(hConsoleOutput, sys.ADR(s[0]), LENGTH(s), sys.ADR(count), NIL)
  36. END String;
  37.  
  38. PROCEDURE StringW*(s: ARRAY OF WCHAR);
  39. VAR count: INTEGER;
  40. BEGIN
  41.   WINAPI.WriteConsoleW(hConsoleOutput, sys.ADR(s[0]), LENGTH(s), sys.ADR(count), 0)
  42. END StringW;
  43.  
  44. PROCEDURE Char*(x: CHAR);
  45. VAR count: INTEGER;
  46. BEGIN
  47.   WINAPI.WriteFile(hConsoleOutput, sys.ADR(x), 1, sys.ADR(count), NIL)
  48. END Char;
  49.  
  50. PROCEDURE WriteInt(x, n: INTEGER);
  51. VAR i: INTEGER; a: ARRAY 16 OF CHAR; neg: BOOLEAN;
  52. BEGIN
  53.   i := 0;
  54.   IF n < 1 THEN
  55.     n := 1
  56.   END;
  57.   IF x < 0 THEN
  58.     x := -x;
  59.     DEC(n);
  60.     neg := TRUE
  61.   END;
  62.   REPEAT
  63.     a[i] := CHR(x MOD 10 + ORD("0"));
  64.     x := x DIV 10;
  65.     INC(i)
  66.   UNTIL x = 0;
  67.   WHILE n > i DO
  68.     Char(" ");
  69.     DEC(n)
  70.   END;
  71.   IF neg THEN
  72.     Char("-")
  73.   END;
  74.   REPEAT
  75.     DEC(i);
  76.     Char(a[i])
  77.   UNTIL i = 0
  78. END WriteInt;
  79.  
  80. PROCEDURE IsNan(AValue: REAL): BOOLEAN;
  81. VAR h, l: SET;
  82. BEGIN
  83.   sys.GET(sys.ADR(AValue), l);
  84.   sys.GET(sys.ADR(AValue) + 4, h)
  85.   RETURN (h * {20..30} = {20..30}) & ((h * {0..19} # {}) OR (l * {0..31} # {}))
  86. END IsNan;
  87.  
  88. PROCEDURE IsInf(x: REAL): BOOLEAN;
  89.   RETURN ABS(x) = sys.INF()
  90. END IsInf;
  91.  
  92. PROCEDURE Int*(x, width: INTEGER);
  93. VAR i: INTEGER;
  94. BEGIN
  95.   IF x # 80000000H THEN
  96.     WriteInt(x, width)
  97.   ELSE
  98.     FOR i := 12 TO width DO
  99.       Char(20X)
  100.     END;
  101.     String("-2147483648")
  102.   END
  103. END Int;
  104.  
  105. PROCEDURE OutInf(x: REAL; width: INTEGER);
  106. VAR s: ARRAY 5 OF CHAR; i: INTEGER;
  107. BEGIN
  108.   IF IsNan(x) THEN
  109.     s := "Nan";
  110.     INC(width)
  111.   ELSIF IsInf(x) & (x > 0.0) THEN
  112.     s := "+Inf"
  113.   ELSIF IsInf(x) & (x < 0.0) THEN
  114.     s := "-Inf"
  115.   END;
  116.   FOR i := 1 TO width - 4 DO
  117.     Char(" ")
  118.   END;
  119.   String(s)
  120. END OutInf;
  121.  
  122. PROCEDURE Ln*;
  123. BEGIN
  124.   Char(0DX);
  125.   Char(0AX)
  126. END Ln;
  127.  
  128. PROCEDURE _FixReal(x: REAL; width, p: INTEGER);
  129. VAR e, len, i: INTEGER; y: REAL; minus: BOOLEAN;
  130. BEGIN
  131.   IF IsNan(x) OR IsInf(x) THEN
  132.     OutInf(x, width)
  133.   ELSIF p < 0 THEN
  134.     Realp(x, width)
  135.   ELSE
  136.     len := 0;
  137.     minus := FALSE;
  138.     IF x < 0.0 THEN
  139.       minus := TRUE;
  140.       INC(len);
  141.       x := ABS(x)
  142.     END;
  143.     e := 0;
  144.     WHILE x >= 10.0 DO
  145.       x := x / 10.0;
  146.       INC(e)
  147.     END;
  148.  
  149.     IF e >= 0 THEN
  150.       len := len + e + p + 1;
  151.       IF x > 9.0 + d THEN
  152.         INC(len)
  153.       END;
  154.       IF p > 0 THEN
  155.         INC(len)
  156.       END;
  157.     ELSE
  158.       len := len + p + 2
  159.     END;
  160.     FOR i := 1 TO width - len DO
  161.       Char(" ")
  162.     END;
  163.     IF minus THEN
  164.       Char("-")
  165.     END;
  166.     y := x;
  167.     WHILE (y < 1.0) & (y # 0.0) DO
  168.       y := y * 10.0;
  169.       DEC(e)
  170.     END;
  171.     IF e < 0 THEN
  172.       IF x - FLT(FLOOR(x)) > d THEN
  173.         Char("1");
  174.         x := 0.0
  175.       ELSE
  176.         Char("0");
  177.         x := x * 10.0
  178.       END
  179.     ELSE
  180.       WHILE e >= 0 DO
  181.         IF x - FLT(FLOOR(x)) > d THEN
  182.           IF x > 9.0 THEN
  183.             String("10")
  184.           ELSE
  185.             Char(CHR(FLOOR(x) + ORD("0") + 1))
  186.           END;
  187.           x := 0.0
  188.         ELSE
  189.           Char(CHR(FLOOR(x) + ORD("0")));
  190.           x := (x - FLT(FLOOR(x))) * 10.0
  191.         END;
  192.         DEC(e)
  193.       END
  194.     END;
  195.     IF p > 0 THEN
  196.       Char(".")
  197.     END;
  198.     WHILE p > 0 DO
  199.       IF x - FLT(FLOOR(x)) > d THEN
  200.         Char(CHR(FLOOR(x) + ORD("0") + 1));
  201.         x := 0.0
  202.       ELSE
  203.         Char(CHR(FLOOR(x) + ORD("0")));
  204.         x := (x - FLT(FLOOR(x))) * 10.0
  205.       END;
  206.       DEC(p)
  207.     END
  208.   END
  209. END _FixReal;
  210.  
  211. PROCEDURE Real*(x: REAL; width: INTEGER);
  212. VAR e, n, i: INTEGER; minus: BOOLEAN;
  213. BEGIN
  214.   Realp := Real;
  215.   IF IsNan(x) OR IsInf(x) THEN
  216.     OutInf(x, width)
  217.   ELSE
  218.     e := 0;
  219.     n := 0;
  220.     IF width > 23 THEN
  221.       n := width - 23;
  222.       width := 23
  223.     ELSIF width < 9 THEN
  224.       width := 9
  225.     END;
  226.     width := width - 5;
  227.     IF x < 0.0 THEN
  228.       x := -x;
  229.       minus := TRUE
  230.     ELSE
  231.       minus := FALSE
  232.     END;
  233.     WHILE x >= 10.0 DO
  234.       x := x / 10.0;
  235.       INC(e)
  236.     END;
  237.     WHILE (x < 1.0) & (x # 0.0) DO
  238.       x := x * 10.0;
  239.       DEC(e)
  240.     END;
  241.     IF x > 9.0 + d THEN
  242.       x := 1.0;
  243.       INC(e)
  244.     END;
  245.     FOR i := 1 TO n DO
  246.       Char(" ")
  247.     END;
  248.     IF minus THEN
  249.       x := -x
  250.     END;
  251.     _FixReal(x, width, width - 3);
  252.     Char("E");
  253.     IF e >= 0 THEN
  254.       Char("+")
  255.     ELSE
  256.       Char("-");
  257.       e := ABS(e)
  258.     END;
  259.     IF e < 100 THEN
  260.       Char("0")
  261.     END;
  262.     IF e < 10 THEN
  263.       Char("0")
  264.     END;
  265.     Int(e, 0)
  266.   END
  267. END Real;
  268.  
  269. PROCEDURE FixReal*(x: REAL; width, p: INTEGER);
  270. BEGIN
  271.   Realp := Real;
  272.   _FixReal(x, width, p)
  273. END FixReal;
  274.  
  275. PROCEDURE Open*;
  276. BEGIN
  277.   hConsoleOutput := WINAPI.GetStdHandle(-11)
  278. END Open;
  279.  
  280. END Out.