Subversion Repositories Kolibri OS

Rev

Rev 7696 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
7983 leency 1
(*
7597 akron1 2
    Copyright 2016, 2018 Anton Krotov
6613 leency 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 .
16
*)
17
 
18
MODULE Out;
19
 
20
IMPORT ConsoleLib, sys := SYSTEM;
21
 
22
CONST
23
 
7597 akron1 24
  d = 1.0 - 5.0E-12;
6613 leency 25
 
26
VAR
27
 
7597 akron1 28
  Realp: PROCEDURE (x: REAL; width: INTEGER);
6613 leency 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
 
7597 akron1 70
PROCEDURE IsNan(AValue: REAL): BOOLEAN;
6613 leency 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
 
7597 akron1 78
PROCEDURE IsInf(x: REAL): BOOLEAN;
79
  RETURN ABS(x) = sys.INF()
6613 leency 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
 
7597 akron1 95
PROCEDURE OutInf(x: REAL; width: INTEGER);
96
VAR s: ARRAY 5 OF CHAR; i: INTEGER;
6613 leency 97
BEGIN
98
  IF IsNan(x) THEN
99
    s := "Nan";
100
    INC(width)
7597 akron1 101
  ELSIF IsInf(x) & (x > 0.0) THEN
6613 leency 102
    s := "+Inf"
7597 akron1 103
  ELSIF IsInf(x) & (x < 0.0) THEN
6613 leency 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
 
7597 akron1 118
PROCEDURE _FixReal(x: REAL; width, p: INTEGER);
119
VAR e, len, i: INTEGER; y: REAL; minus: BOOLEAN;
6613 leency 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;
7597 akron1 128
    IF x < 0.0 THEN
6613 leency 129
      minus := TRUE;
130
      INC(len);
131
      x := ABS(x)
132
    END;
133
    e := 0;
7597 akron1 134
    WHILE x >= 10.0 DO
135
      x := x / 10.0;
6613 leency 136
      INC(e)
137
    END;
138
    IF e >= 0 THEN
139
      len := len + e + p + 1;
7597 akron1 140
      IF x > 9.0 + d THEN
141
        INC(len)
6613 leency 142
      END;
143
      IF p > 0 THEN
7597 akron1 144
        INC(len)
6613 leency 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;
7597 akron1 156
    WHILE (y < 1.0) & (y # 0.0) DO
157
      y := y * 10.0;
6613 leency 158
      DEC(e)
159
    END;
160
    IF e < 0 THEN
7597 akron1 161
      IF x - FLT(FLOOR(x)) > d THEN
162
        Char("1");
163
        x := 0.0
6613 leency 164
      ELSE
7597 akron1 165
        Char("0");
166
        x := x * 10.0
6613 leency 167
      END
168
    ELSE
169
      WHILE e >= 0 DO
7597 akron1 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)
6613 leency 182
      END
183
    END;
184
    IF p > 0 THEN
185
      Char(".")
186
    END;
187
    WHILE p > 0 DO
7597 akron1 188
      IF x - FLT(FLOOR(x)) > d THEN
189
        Char(CHR(FLOOR(x) + ORD("0") + 1));
190
        x := 0.0
6613 leency 191
      ELSE
7597 akron1 192
        Char(CHR(FLOOR(x) + ORD("0")));
193
        x := (x - FLT(FLOOR(x))) * 10.0
6613 leency 194
      END;
195
      DEC(p)
196
    END
197
  END
6647 akron1 198
END _FixReal;
6613 leency 199
 
7597 akron1 200
PROCEDURE Real*(x: REAL; width: INTEGER);
6613 leency 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;
7597 akron1 215
    IF x < 0.0 THEN
6613 leency 216
      x := -x;
217
      minus := TRUE
218
    ELSE
219
      minus := FALSE
220
    END;
7597 akron1 221
    WHILE x >= 10.0 DO
222
      x := x / 10.0;
6613 leency 223
      INC(e)
224
    END;
7597 akron1 225
    WHILE (x < 1.0) & (x # 0.0) DO
226
      x := x * 10.0;
6613 leency 227
      DEC(e)
228
    END;
7597 akron1 229
    IF x > 9.0 + d THEN
230
      x := 1.0;
6613 leency 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;
6647 akron1 239
    Realp := Real;
240
    _FixReal(x, width, width - 3);
6613 leency 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
 
7597 akron1 258
PROCEDURE FixReal*(x: REAL; width, p: INTEGER);
6647 akron1 259
BEGIN
260
  Realp := Real;
261
  _FixReal(x, width, p)
262
END FixReal;
263
 
6613 leency 264
PROCEDURE Open*;
265
END Open;
266
 
7983 leency 267
END Out.