Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
6613 leency 1
(*
2
    Copyright 2016 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 .
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
87
	err := TRUE;
88
	flag := FALSE;
89
	res := 0
90
      ELSE
91
	res := res + (ORD(str[i]) - ORD("0"));
92
	INC(i)
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
120
	INC(i)
121
      END;
122
      IF (s[i] = "D") OR (s[i] = "E") OR (s[i] = "d") OR (s[i] = "e") THEN
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
131
      END
132
    END
133
  END
134
  RETURN Res & (s[i] <= 20X)
135
END CheckReal;
136
 
137
PROCEDURE StrToFloat(str: STRING; VAR err: BOOLEAN): LONGREAL;
138
CONST maxDBL = 1.69D308; maxINT = 7FFFFFFFH;
139
VAR i, scale: INTEGER; res, m, d: LONGREAL; minus, neg: BOOLEAN;
140
 
141
  PROCEDURE part1(): BOOLEAN;
142
  BEGIN
143
    res := 0.0D0;
144
    d := 1.0D0;
145
    WHILE digit(str[i]) DO
146
      res := res * 10.0D0 + LONG(FLT(ORD(str[i]) - ORD("0")));
147
      INC(i)
148
    END;
149
    IF str[i] = "." THEN
150
      INC(i);
151
      WHILE digit(str[i]) DO
152
	d := d / 10.0D0;
153
	res := res + LONG(FLT(ORD(str[i]) - ORD("0"))) * d;
154
	INC(i)
155
      END
156
    END
157
    RETURN str[i] # 0X
158
  END part1;
159
 
160
  PROCEDURE part2(): BOOLEAN;
161
  BEGIN
162
    INC(i);
163
    m := 10.0D0;
164
    minus := FALSE;
165
    IF str[i] = "+" THEN
166
      INC(i)
167
    ELSIF str[i] = "-" THEN
168
      minus := TRUE;
169
      INC(i);
170
      m := 0.1D0
171
    END;
172
    scale := 0;
173
    err := FALSE;
174
    WHILE ~err & digit(str[i]) DO
175
      IF scale > maxINT DIV 10 THEN
176
	err := TRUE;
177
	res := 0.0D0
178
      ELSE
179
	scale := scale * 10;
180
	IF scale > maxINT - (ORD(str[i]) - ORD("0")) THEN
181
	  err := TRUE;
182
	  res := 0.0D0
183
	ELSE
184
	  scale := scale + (ORD(str[i]) - ORD("0"));
185
	  INC(i)
186
	END
187
      END
188
    END
189
    RETURN ~err
190
  END part2;
191
 
192
  PROCEDURE part3;
193
  VAR i: INTEGER;
194
  BEGIN
195
    err := FALSE;
196
    IF scale = maxINT THEN
197
      err := TRUE;
198
      res := 0.0D0
199
    END;
200
    i := 1;
201
    WHILE ~err & (i <= scale) DO
202
      IF ~minus & (res > maxDBL / m) THEN
203
	err := TRUE;
204
	res := 0.0D0
205
      ELSE
206
	res := res * m;
207
	INC(i)
208
      END
209
    END
210
  END part3;
211
 
212
BEGIN
213
  IF CheckReal(str, i, neg) THEN
214
    IF part1() & part2() THEN
215
      part3
216
    END;
217
    IF neg THEN
218
      res := -res
219
    END
220
  ELSE
221
    res := 0.0D0;
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
 
254
PROCEDURE LongReal*(VAR x: LONGREAL);
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 LongReal;
264
 
265
PROCEDURE Real*(VAR x: REAL);
266
CONST maxREAL = 3.39E38;
267
VAR y: LONGREAL;
268
BEGIN
269
  LongReal(y);
270
  IF Done THEN
271
    IF ABS(y) > LONG(maxREAL) THEN
272
      x := 0.0;
273
      Done := FALSE
274
    ELSE
275
      x := SHORT(y)
276
    END
277
  END
278
END Real;
279
 
280
PROCEDURE Int*(VAR x: INTEGER);
281
VAR str: STRING; err: BOOLEAN;
282
BEGIN
283
  err := FALSE;
284
  REPEAT
285
    String(str)
286
  UNTIL ~Space(str);
287
  x := StrToInt(str, err);
288
  Done := ~err
289
END Int;
290
 
291
PROCEDURE Open*;
292
BEGIN
293
  Done := TRUE
294
END Open;
295
 
296
END In.