Subversion Repositories Kolibri OS

Rev

Rev 7696 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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