Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
7597 akron1 1
(*
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 In;
19
 
20
IMPORT sys := SYSTEM, ConsoleLib;
21
 
22
TYPE
23
 
24
  STRING = ARRAY 260 OF CHAR;
25
 
26
VAR
27
 
28
  Done* : BOOLEAN;
29
 
30
PROCEDURE digit(ch: CHAR): BOOLEAN;
31
  RETURN (ch >= "0") & (ch <= "9")
32
END digit;
33
 
34
PROCEDURE CheckInt(s: STRING; VAR first, last: INTEGER; VAR neg: BOOLEAN; Point: BOOLEAN): BOOLEAN;
35
VAR i: INTEGER;
36
BEGIN
37
  i := 0;
38
  neg := FALSE;
39
  WHILE (s[i] <= 20X) & (s[i] # 0X) DO
40
    INC(i)
41
  END;
42
  IF s[i] = "-" THEN
43
    neg := TRUE;
44
    INC(i)
45
  ELSIF s[i] = "+" THEN
46
    INC(i)
47
  END;
48
  first := i;
49
  WHILE digit(s[i]) DO
50
    INC(i)
51
  END;
52
  last := i
53
  RETURN ((s[i] <= 20X) OR (Point & (s[i] = "."))) & digit(s[first])
54
END CheckInt;
55
 
56
PROCEDURE IsMinInt(str: STRING; pos: INTEGER): BOOLEAN;
57
VAR i: INTEGER; min: STRING;
58
BEGIN
59
  i := 0;
60
  min := "2147483648";
61
  WHILE (min[i] # 0X) & (str[i] # 0X) & (min[i] = str[i + pos]) DO
62
    INC(i)
63
  END
64
  RETURN i = 10
65
END IsMinInt;
66
 
67
PROCEDURE StrToInt(str: STRING; VAR err: BOOLEAN): INTEGER;
68
CONST maxINT = 7FFFFFFFH;
69
VAR i, n, res: INTEGER; flag, neg: BOOLEAN;
70
BEGIN
71
  res := 0;
72
  flag := CheckInt(str, i, n, neg, FALSE);
73
  err := ~flag;
74
  IF flag & neg & IsMinInt(str, i) THEN
75
    flag := FALSE;
76
    neg := FALSE;
77
    res := 80000000H
78
  END;
79
  WHILE flag & digit(str[i]) DO
80
    IF res > maxINT DIV 10 THEN
81
      err := TRUE;
82
      flag := FALSE;
83
      res := 0
84
    ELSE
85
      res := res * 10;
86
      IF res > maxINT - (ORD(str[i]) - ORD("0")) THEN
7597 akron1 87
        err := TRUE;
88
        flag := FALSE;
89
        res := 0
6613 leency 90
      ELSE
7597 akron1 91
        res := res + (ORD(str[i]) - ORD("0"));
92
        INC(i)
6613 leency 93
      END
94
    END
95
  END;
96
  IF neg THEN
97
    res := -res
98
  END
99
  RETURN res
100
END StrToInt;
101
 
102
PROCEDURE Space(s: STRING): BOOLEAN;
103
VAR i: INTEGER;
104
BEGIN
105
  i := 0;
106
  WHILE (s[i] # 0X) & (s[i] <= 20X) DO
107
    INC(i)
108
  END
109
  RETURN s[i] = 0X
110
END Space;
111
 
112
PROCEDURE CheckReal(s: STRING; VAR n: INTEGER; VAR neg: BOOLEAN): BOOLEAN;
113
VAR i: INTEGER; Res: BOOLEAN;
114
BEGIN
115
  Res := CheckInt(s, n, i, neg, TRUE);
116
  IF Res THEN
117
    IF s[i] = "." THEN
118
      INC(i);
119
      WHILE digit(s[i]) DO
7597 akron1 120
        INC(i)
6613 leency 121
      END;
122
      IF (s[i] = "D") OR (s[i] = "E") OR (s[i] = "d") OR (s[i] = "e") THEN
7597 akron1 123
        INC(i);
124
        IF (s[i] = "+") OR (s[i] = "-") THEN
125
          INC(i)
126
        END;
127
        Res := digit(s[i]);
128
        WHILE digit(s[i]) DO
129
          INC(i)
130
        END
6613 leency 131
      END
132
    END
133
  END
134
  RETURN Res & (s[i] <= 20X)
135
END CheckReal;
136
 
7597 akron1 137
PROCEDURE StrToFloat(str: STRING; VAR err: BOOLEAN): REAL;
138
CONST maxDBL = 1.69E308; maxINT = 7FFFFFFFH;
139
VAR i, scale: INTEGER; res, m, d: REAL; minus, neg: BOOLEAN;
6613 leency 140
 
7597 akron1 141
  PROCEDURE part1 (str: STRING; VAR res, d: REAL; VAR i: INTEGER): BOOLEAN;
6613 leency 142
  BEGIN
7597 akron1 143
    res := 0.0;
144
    d := 1.0;
6613 leency 145
    WHILE digit(str[i]) DO
7597 akron1 146
      res := res * 10.0 + FLT(ORD(str[i]) - ORD("0"));
6613 leency 147
      INC(i)
148
    END;
149
    IF str[i] = "." THEN
150
      INC(i);
151
      WHILE digit(str[i]) DO
7597 akron1 152
        d := d / 10.0;
153
        res := res + FLT(ORD(str[i]) - ORD("0")) * d;
154
        INC(i)
6613 leency 155
      END
156
    END
157
    RETURN str[i] # 0X
158
  END part1;
159
 
7597 akron1 160
  PROCEDURE part2 (str: STRING; VAR i, scale: INTEGER; VAR minus, err: BOOLEAN; VAR m, res: REAL): BOOLEAN;
6613 leency 161
  BEGIN
162
    INC(i);
7597 akron1 163
    m := 10.0;
6613 leency 164
    minus := FALSE;
165
    IF str[i] = "+" THEN
166
      INC(i)
167
    ELSIF str[i] = "-" THEN
168
      minus := TRUE;
169
      INC(i);
7597 akron1 170
      m := 0.1
6613 leency 171
    END;
172
    scale := 0;
173
    err := FALSE;
174
    WHILE ~err & digit(str[i]) DO
175
      IF scale > maxINT DIV 10 THEN
7597 akron1 176
        err := TRUE;
177
        res := 0.0
6613 leency 178
      ELSE
7597 akron1 179
        scale := scale * 10;
180
        IF scale > maxINT - (ORD(str[i]) - ORD("0")) THEN
181
          err := TRUE;
182
          res := 0.0
183
        ELSE
184
          scale := scale + (ORD(str[i]) - ORD("0"));
185
          INC(i)
186
        END
6613 leency 187
      END
188
    END
189
    RETURN ~err
190
  END part2;
191
 
7597 akron1 192
  PROCEDURE part3 (VAR err, minus: BOOLEAN; VAR res, m: REAL; VAR scale: INTEGER);
6613 leency 193
  VAR i: INTEGER;
194
  BEGIN
195
    err := FALSE;
196
    IF scale = maxINT THEN
197
      err := TRUE;
7597 akron1 198
      res := 0.0
6613 leency 199
    END;
200
    i := 1;
201
    WHILE ~err & (i <= scale) DO
202
      IF ~minus & (res > maxDBL / m) THEN
7597 akron1 203
        err := TRUE;
204
        res := 0.0
6613 leency 205
      ELSE
7597 akron1 206
        res := res * m;
207
        INC(i)
6613 leency 208
      END
209
    END
210
  END part3;
211
 
212
BEGIN
213
  IF CheckReal(str, i, neg) THEN
7597 akron1 214
    IF part1(str, res, d, i) & part2(str, i, scale, minus, err, m, res) THEN
215
      part3(err, minus, res, m, scale)
6613 leency 216
    END;
217
    IF neg THEN
218
      res := -res
219
    END
220
  ELSE
7597 akron1 221
    res := 0.0;
6613 leency 222
    err := TRUE
223
  END
224
  RETURN res
225
END StrToFloat;
226
 
227
PROCEDURE String*(VAR s: ARRAY OF CHAR);
228
VAR res, length: INTEGER; str: STRING;
229
BEGIN
230
  res := ConsoleLib.gets(sys.ADR(str[0]), LEN(str));
231
  length := LENGTH(str);
232
  IF length > 0 THEN
233
    str[length - 1] := 0X
234
  END;
235
  COPY(str, s);
236
  Done := TRUE
237
END String;
238
 
239
PROCEDURE Char*(VAR x: CHAR);
240
VAR str: STRING;
241
BEGIN
242
  String(str);
243
  x := str[0];
244
  Done := TRUE
245
END Char;
246
 
247
PROCEDURE Ln*;
248
VAR str: STRING;
249
BEGIN
250
  String(str);
251
  Done := TRUE
252
END Ln;
253
 
7597 akron1 254
PROCEDURE Real* (VAR x: REAL);
6613 leency 255
VAR str: STRING; err: BOOLEAN;
256
BEGIN
257
  err := FALSE;
258
  REPEAT
259
    String(str)
260
  UNTIL ~Space(str);
261
  x := StrToFloat(str, err);
262
  Done := ~err
263
END Real;
264
 
7597 akron1 265
 
6613 leency 266
PROCEDURE Int*(VAR x: INTEGER);
267
VAR str: STRING; err: BOOLEAN;
268
BEGIN
269
  err := FALSE;
270
  REPEAT
271
    String(str)
272
  UNTIL ~Space(str);
273
  x := StrToInt(str, err);
274
  Done := ~err
275
END Int;
276
 
277
PROCEDURE Open*;
278
BEGIN
279
  Done := TRUE
280
END Open;
281
 
282
END In.