Subversion Repositories Kolibri OS

Rev

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

Rev 7983 Rev 8097
1
(*
1
(*
2
    BSD 2-Clause License
2
    BSD 2-Clause License
3
 
3
 
4
    Copyright (c) 2018-2020, Anton Krotov
4
    Copyright (c) 2018-2020, Anton Krotov
5
    All rights reserved.
5
    All rights reserved.
6
*)
6
*)
7
 
7
 
8
MODULE ARITH;
8
MODULE ARITH;
9
 
9
 
10
IMPORT AVLTREES, STRINGS, UTILS;
10
IMPORT AVLTREES, STRINGS, UTILS;
11
 
11
 
12
 
12
 
13
CONST
13
CONST
14
 
14
 
15
    tINTEGER* = 1;  tREAL* = 2;  tSET*    = 3;
15
    tINTEGER* = 1;  tREAL* = 2;  tSET*    = 3;
16
    tBOOLEAN* = 4;  tCHAR* = 5;  tWCHAR*  = 6;
16
    tBOOLEAN* = 4;  tCHAR* = 5;  tWCHAR*  = 6;
17
    tSTRING*  = 7;
17
    tSTRING*  = 7;
-
 
18
 
-
 
19
    opEQ* = 0; opNE* = 1; opLT* = 2; opLE* = 3; opGT* = 4; opGE* = 5;
18
 
-
 
19
 
20
    opIN* = 6; opIS* = 7;
20
TYPE
21
 
21
 
22
 
22
    RELATION* = ARRAY 3 OF CHAR;
23
TYPE
23
 
24
 
24
    VALUE* = RECORD
25
    VALUE* = RECORD
25
 
26
 
26
        typ*:      INTEGER;
27
        typ*:      INTEGER;
27
 
28
 
28
        int:       INTEGER;
29
        int:       INTEGER;
29
        float:     REAL;
30
        float:     REAL;
30
        set:       SET;
31
        set:       SET;
31
        bool:      BOOLEAN;
32
        bool:      BOOLEAN;
32
 
33
 
33
        string*:   AVLTREES.DATA
34
        string*:   AVLTREES.DATA
34
 
35
 
35
    END;
36
    END;
36
 
37
 
37
 
38
 
38
VAR
39
VAR
39
 
40
 
40
    digit: ARRAY 256 OF INTEGER;
41
    digit: ARRAY 256 OF INTEGER;
41
 
42
 
42
 
43
 
43
PROCEDURE Int* (v: VALUE): INTEGER;
44
PROCEDURE Int* (v: VALUE): INTEGER;
44
VAR
45
VAR
45
    res: INTEGER;
46
    res: INTEGER;
46
 
47
 
47
BEGIN
48
BEGIN
48
 
49
 
49
    CASE v.typ OF
50
    CASE v.typ OF
50
    |tINTEGER, tCHAR, tWCHAR:
51
    |tINTEGER, tCHAR, tWCHAR:
51
        res := v.int
52
        res := v.int
52
    |tSET:
53
    |tSET:
53
        res := UTILS.Long(ORD(v.set))
54
        res := UTILS.Long(ORD(v.set))
54
    |tBOOLEAN:
55
    |tBOOLEAN:
55
        res := ORD(v.bool)
56
        res := ORD(v.bool)
56
    END
57
    END
57
 
58
 
58
    RETURN res
59
    RETURN res
59
END Int;
60
END Int;
60
 
61
 
61
 
62
 
62
PROCEDURE getBool* (v: VALUE): BOOLEAN;
63
PROCEDURE getBool* (v: VALUE): BOOLEAN;
63
BEGIN
64
BEGIN
64
    ASSERT(v.typ = tBOOLEAN);
65
    ASSERT(v.typ = tBOOLEAN);
65
 
66
 
66
    RETURN v.bool
67
    RETURN v.bool
67
END getBool;
68
END getBool;
68
 
69
 
69
 
70
 
70
PROCEDURE Float* (v: VALUE): REAL;
71
PROCEDURE Float* (v: VALUE): REAL;
71
BEGIN
72
BEGIN
72
    ASSERT(v.typ = tREAL);
73
    ASSERT(v.typ = tREAL);
73
 
74
 
74
    RETURN v.float
75
    RETURN v.float
75
END Float;
76
END Float;
76
 
77
 
77
 
78
 
78
PROCEDURE range* (i: VALUE; a, b: INTEGER): BOOLEAN;
79
PROCEDURE range* (i: VALUE; a, b: INTEGER): BOOLEAN;
79
    RETURN (a <= i.int) & (i.int <= b)
80
    RETURN (a <= i.int) & (i.int <= b)
80
END range;
81
END range;
81
 
82
 
82
 
83
 
83
PROCEDURE check* (v: VALUE): BOOLEAN;
84
PROCEDURE check* (v: VALUE): BOOLEAN;
84
VAR
85
VAR
85
    res: BOOLEAN;
86
    res: BOOLEAN;
86
 
87
 
87
BEGIN
88
BEGIN
88
    CASE v.typ OF
89
    CASE v.typ OF
89
    |tINTEGER: res := range(v, UTILS.target.minInt, UTILS.target.maxInt)
90
    |tINTEGER: res := range(v, UTILS.target.minInt, UTILS.target.maxInt)
90
    |tCHAR:    res := range(v, 0, 255)
91
    |tCHAR:    res := range(v, 0, 255)
91
    |tWCHAR:   res := range(v, 0, 65535)
92
    |tWCHAR:   res := range(v, 0, 65535)
92
    |tREAL:    res := (-UTILS.target.maxReal <= v.float) & (v.float <= UTILS.target.maxReal)
93
    |tREAL:    res := (-UTILS.target.maxReal <= v.float) & (v.float <= UTILS.target.maxReal)
93
    END
94
    END
94
 
95
 
95
    RETURN res
96
    RETURN res
96
END check;
97
END check;
97
 
98
 
98
 
99
 
99
PROCEDURE isZero* (v: VALUE): BOOLEAN;
100
PROCEDURE isZero* (v: VALUE): BOOLEAN;
100
VAR
101
VAR
101
    res: BOOLEAN;
102
    res: BOOLEAN;
102
 
103
 
103
BEGIN
104
BEGIN
104
    CASE v.typ OF
105
    CASE v.typ OF
105
    |tINTEGER: res := v.int = 0
106
    |tINTEGER: res := v.int = 0
106
    |tREAL:    res := v.float = 0.0
107
    |tREAL:    res := v.float = 0.0
107
    END
108
    END
108
 
109
 
109
    RETURN res
110
    RETURN res
110
END isZero;
111
END isZero;
111
 
112
 
112
 
113
 
113
PROCEDURE iconv* (s: ARRAY OF CHAR; VAR v: VALUE; VAR error: INTEGER);
114
PROCEDURE iconv* (s: ARRAY OF CHAR; VAR v: VALUE; VAR error: INTEGER);
114
VAR
115
VAR
115
    value: INTEGER;
116
    value: INTEGER;
116
    i:     INTEGER;
117
    i:     INTEGER;
117
    d:     INTEGER;
118
    d:     INTEGER;
118
 
119
 
119
BEGIN
120
BEGIN
120
    error := 0;
121
    error := 0;
121
    value := 0;
122
    value := 0;
122
 
123
 
123
    i := 0;
124
    i := 0;
124
    WHILE STRINGS.digit(s[i]) & (error = 0) DO
125
    WHILE STRINGS.digit(s[i]) & (error = 0) DO
125
        d := digit[ORD(s[i])];
126
        d := digit[ORD(s[i])];
126
        IF value <= (UTILS.maxint - d) DIV 10 THEN
127
        IF value <= (UTILS.maxint - d) DIV 10 THEN
127
            value := value * 10 + d;
128
            value := value * 10 + d;
128
            INC(i)
129
            INC(i)
129
        ELSE
130
        ELSE
130
            error := 1
131
            error := 1
131
        END
132
        END
132
    END;
133
    END;
133
 
134
 
134
    IF error = 0 THEN
135
    IF error = 0 THEN
135
        v.int := value;
136
        v.int := value;
136
        v.typ := tINTEGER;
137
        v.typ := tINTEGER;
137
        IF ~check(v) THEN
138
        IF ~check(v) THEN
138
            error := 1
139
            error := 1
139
        END
140
        END
140
    END
141
    END
141
 
142
 
142
END iconv;
143
END iconv;
143
 
144
 
144
 
145
 
145
PROCEDURE hconv* (s: ARRAY OF CHAR; VAR v: VALUE; VAR error: INTEGER);
146
PROCEDURE hconv* (s: ARRAY OF CHAR; VAR v: VALUE; VAR error: INTEGER);
146
VAR
147
VAR
147
    value: INTEGER;
148
    value: INTEGER;
148
    i:     INTEGER;
149
    i:     INTEGER;
149
    n:     INTEGER;
150
    n:     INTEGER;
150
    d:     INTEGER;
151
    d:     INTEGER;
151
 
152
 
152
BEGIN
153
BEGIN
153
    ASSERT(STRINGS.digit(s[0]));
154
    ASSERT(STRINGS.digit(s[0]));
154
 
155
 
155
    error := 0;
156
    error := 0;
156
    value := 0;
157
    value := 0;
157
 
158
 
158
    n := -1;
159
    n := -1;
159
    i := 0;
160
    i := 0;
160
    WHILE (s[i] # "H") & (s[i] # "X") & (error = 0) DO
161
    WHILE (s[i] # "H") & (s[i] # "X") & (error = 0) DO
161
 
162
 
162
        d := digit[ORD(s[i])];
163
        d := digit[ORD(s[i])];
163
        IF (n = -1) & (d # 0) THEN
164
        IF (n = -1) & (d # 0) THEN
164
            n := i
165
            n := i
165
        END;
166
        END;
166
 
167
 
167
        IF (n # -1) & (i - n + 1 > UTILS.target.maxHex) THEN
168
        IF (n # -1) & (i - n + 1 > UTILS.target.maxHex) THEN
168
            error := 2
169
            error := 2
169
        ELSE
170
        ELSE
170
            value := value * 16 + d;
171
            value := value * 16 + d;
171
            INC(i)
172
            INC(i)
172
        END
173
        END
173
 
174
 
174
    END;
175
    END;
175
 
176
 
176
    value := UTILS.Long(value);
177
    value := UTILS.Long(value);
177
 
178
 
178
    IF (s[i] = "X") & (n # -1) & (i - n > 4) THEN
179
    IF (s[i] = "X") & (n # -1) & (i - n > 4) THEN
179
        error := 3
180
        error := 3
180
    END;
181
    END;
181
 
182
 
182
    IF error = 0 THEN
183
    IF error = 0 THEN
183
        v.int := value;
184
        v.int := value;
184
        IF s[i] = "X" THEN
185
        IF s[i] = "X" THEN
185
            v.typ := tCHAR;
186
            v.typ := tCHAR;
186
            IF ~check(v) THEN
187
            IF ~check(v) THEN
187
                v.typ := tWCHAR;
188
                v.typ := tWCHAR;
188
                IF ~check(v) THEN
189
                IF ~check(v) THEN
189
                    error := 3
190
                    error := 3
190
                END
191
                END
191
            END
192
            END
192
        ELSE
193
        ELSE
193
            v.typ := tINTEGER;
194
            v.typ := tINTEGER;
194
            IF ~check(v) THEN
195
            IF ~check(v) THEN
195
                error := 2
196
                error := 2
196
            END
197
            END
197
        END
198
        END
198
    END
199
    END
199
 
200
 
200
END hconv;
201
END hconv;
201
 
202
 
202
 
203
 
203
PROCEDURE opFloat2 (VAR a: REAL; b: REAL; op: CHAR): BOOLEAN;
204
PROCEDURE opFloat2 (VAR a: REAL; b: REAL; op: CHAR): BOOLEAN;
204
BEGIN
205
BEGIN
205
    CASE op OF
206
    CASE op OF
206
    |"+": a := a + b
207
    |"+": a := a + b
207
    |"-": a := a - b
208
    |"-": a := a - b
208
    |"*": a := a * b
209
    |"*": a := a * b
209
    |"/": a := a / b
210
    |"/": a := a / b
210
    END
211
    END
211
 
212
 
212
    RETURN (-UTILS.maxreal <= a) & (a <= UTILS.maxreal) (* +inf > UTILS.maxreal *)
213
    RETURN (-UTILS.maxreal <= a) & (a <= UTILS.maxreal) (* +inf > UTILS.maxreal *)
213
END opFloat2;
214
END opFloat2;
214
 
215
 
215
 
216
 
216
PROCEDURE fconv* (s: ARRAY OF CHAR; VAR v: VALUE; VAR error: INTEGER);
217
PROCEDURE fconv* (s: ARRAY OF CHAR; VAR v: VALUE; VAR error: INTEGER);
217
VAR
218
VAR
218
    value:    REAL;
219
    value:    REAL;
219
    exp10:    REAL;
220
    exp10:    REAL;
220
    i, n, d:  INTEGER;
221
    i, n, d:  INTEGER;
221
    minus:    BOOLEAN;
222
    minus:    BOOLEAN;
222
 
223
 
223
BEGIN
224
BEGIN
224
    error := 0;
225
    error := 0;
225
    value := 0.0;
226
    value := 0.0;
226
    exp10 := 10.0;
227
    exp10 := 10.0;
227
    minus := FALSE;
228
    minus := FALSE;
228
    n := 0;
229
    n := 0;
229
 
230
 
230
    i := 0;
231
    i := 0;
231
    WHILE (error = 0) & STRINGS.digit(s[i]) DO
232
    WHILE (error = 0) & STRINGS.digit(s[i]) DO
232
        IF opFloat2(value, 10.0, "*") & opFloat2(value, FLT(digit[ORD(s[i])]), "+") THEN
233
        IF opFloat2(value, 10.0, "*") & opFloat2(value, FLT(digit[ORD(s[i])]), "+") THEN
233
            INC(i)
234
            INC(i)
234
        ELSE
235
        ELSE
235
            error := 4
236
            error := 4
236
        END
237
        END
237
    END;
238
    END;
238
 
239
 
239
    INC(i);
240
    INC(i);
240
 
241
 
241
    WHILE (error = 0) & STRINGS.digit(s[i]) DO
242
    WHILE (error = 0) & STRINGS.digit(s[i]) DO
242
        IF opFloat2(value, FLT(digit[ORD(s[i])]) / exp10, "+") & opFloat2(exp10, 10.0, "*") THEN
243
        IF opFloat2(value, FLT(digit[ORD(s[i])]) / exp10, "+") & opFloat2(exp10, 10.0, "*") THEN
243
            INC(i)
244
            INC(i)
244
        ELSE
245
        ELSE
245
            error := 4
246
            error := 4
246
        END
247
        END
247
    END;
248
    END;
248
 
249
 
249
    IF s[i] = "E" THEN
250
    IF s[i] = "E" THEN
250
        INC(i)
251
        INC(i)
251
    END;
252
    END;
252
 
253
 
253
    IF (s[i] = "-") OR (s[i] = "+") THEN
254
    IF (s[i] = "-") OR (s[i] = "+") THEN
254
        minus := s[i] = "-";
255
        minus := s[i] = "-";
255
        INC(i)
256
        INC(i)
256
    END;
257
    END;
257
 
258
 
258
    WHILE (error = 0) & STRINGS.digit(s[i]) DO
259
    WHILE (error = 0) & STRINGS.digit(s[i]) DO
259
        d := digit[ORD(s[i])];
260
        d := digit[ORD(s[i])];
260
        IF n <= (UTILS.maxint - d) DIV 10 THEN
261
        IF n <= (UTILS.maxint - d) DIV 10 THEN
261
            n := n * 10 + d;
262
            n := n * 10 + d;
262
            INC(i)
263
            INC(i)
263
        ELSE
264
        ELSE
264
            error := 5
265
            error := 5
265
        END
266
        END
266
    END;
267
    END;
267
 
268
 
268
    exp10 := 1.0;
269
    exp10 := 1.0;
269
    WHILE (error = 0) & (n > 0) DO
270
    WHILE (error = 0) & (n > 0) DO
270
        IF opFloat2(exp10, 10.0, "*") THEN
271
        IF opFloat2(exp10, 10.0, "*") THEN
271
            DEC(n)
272
            DEC(n)
272
        ELSE
273
        ELSE
273
            error := 4
274
            error := 4
274
        END
275
        END
275
    END;
276
    END;
276
 
277
 
277
    IF error = 0 THEN
278
    IF error = 0 THEN
278
        IF minus THEN
279
        IF minus THEN
279
            IF ~opFloat2(value, exp10, "/") THEN
280
            IF ~opFloat2(value, exp10, "/") THEN
280
                error := 4
281
                error := 4
281
            END
282
            END
282
        ELSE
283
        ELSE
283
            IF ~opFloat2(value, exp10, "*") THEN
284
            IF ~opFloat2(value, exp10, "*") THEN
284
                error := 4
285
                error := 4
285
            END
286
            END
286
        END
287
        END
287
    END;
288
    END;
288
 
289
 
289
    IF error = 0 THEN
290
    IF error = 0 THEN
290
        v.float := value;
291
        v.float := value;
291
        v.typ := tREAL;
292
        v.typ := tREAL;
292
        IF ~check(v) THEN
293
        IF ~check(v) THEN
293
            error := 4
294
            error := 4
294
        END
295
        END
295
    END
296
    END
296
 
297
 
297
END fconv;
298
END fconv;
298
 
299
 
299
 
300
 
300
PROCEDURE setChar* (VAR v: VALUE; ord: INTEGER);
301
PROCEDURE setChar* (VAR v: VALUE; ord: INTEGER);
301
BEGIN
302
BEGIN
302
    v.typ := tCHAR;
303
    v.typ := tCHAR;
303
    v.int := ord
304
    v.int := ord
304
END setChar;
305
END setChar;
305
 
306
 
306
 
307
 
307
PROCEDURE setWChar* (VAR v: VALUE; ord: INTEGER);
308
PROCEDURE setWChar* (VAR v: VALUE; ord: INTEGER);
308
BEGIN
309
BEGIN
309
    v.typ := tWCHAR;
310
    v.typ := tWCHAR;
310
    v.int := ord
311
    v.int := ord
311
END setWChar;
312
END setWChar;
312
 
313
 
313
 
314
 
314
PROCEDURE addInt (VAR a: INTEGER; b: INTEGER): BOOLEAN;
315
PROCEDURE addInt (VAR a: INTEGER; b: INTEGER): BOOLEAN;
315
VAR
316
VAR
316
    error: BOOLEAN;
317
    error: BOOLEAN;
317
 
318
 
318
BEGIN
319
BEGIN
319
    IF (a > 0) & (b > 0) THEN
320
    IF (a > 0) & (b > 0) THEN
320
        error := a > UTILS.maxint - b
321
        error := a > UTILS.maxint - b
321
    ELSIF (a < 0) & (b < 0) THEN
322
    ELSIF (a < 0) & (b < 0) THEN
322
        error := a < UTILS.minint - b
323
        error := a < UTILS.minint - b
323
    ELSE
324
    ELSE
324
        error := FALSE
325
        error := FALSE
325
    END;
326
    END;
326
 
327
 
327
    IF ~error THEN
328
    IF ~error THEN
328
        a := a + b
329
        a := a + b
329
    ELSE
330
    ELSE
330
        a := 0
331
        a := 0
331
    END
332
    END
332
 
333
 
333
    RETURN ~error
334
    RETURN ~error
334
END addInt;
335
END addInt;
335
 
336
 
336
 
337
 
337
PROCEDURE subInt (VAR a: INTEGER; b: INTEGER): BOOLEAN;
338
PROCEDURE subInt (VAR a: INTEGER; b: INTEGER): BOOLEAN;
338
VAR
339
VAR
339
    error: BOOLEAN;
340
    error: BOOLEAN;
340
 
341
 
341
BEGIN
342
BEGIN
342
    IF (a > 0) & (b < 0) THEN
343
    IF (a > 0) & (b < 0) THEN
343
        error := a > UTILS.maxint + b
344
        error := a > UTILS.maxint + b
344
    ELSIF (a < 0) & (b > 0) THEN
345
    ELSIF (a < 0) & (b > 0) THEN
345
        error := a < UTILS.minint + b
346
        error := a < UTILS.minint + b
346
    ELSIF (a = 0) & (b < 0) THEN
347
    ELSIF (a = 0) & (b < 0) THEN
347
        error := b = UTILS.minint
348
        error := b = UTILS.minint
348
    ELSE
349
    ELSE
349
        error := FALSE
350
        error := FALSE
350
    END;
351
    END;
351
 
352
 
352
    IF ~error THEN
353
    IF ~error THEN
353
        a := a - b
354
        a := a - b
354
    ELSE
355
    ELSE
355
        a := 0
356
        a := 0
356
    END
357
    END
357
 
358
 
358
    RETURN ~error
359
    RETURN ~error
359
END subInt;
360
END subInt;
360
 
361
 
361
 
362
 
362
PROCEDURE lg2 (x: INTEGER): INTEGER;
363
PROCEDURE lg2 (x: INTEGER): INTEGER;
363
VAR
364
VAR
364
    n: INTEGER;
365
    n: INTEGER;
365
 
366
 
366
BEGIN
367
BEGIN
367
    ASSERT(x > 0);
368
    ASSERT(x > 0);
368
 
369
 
369
    n := UTILS.Log2(x);
370
    n := UTILS.Log2(x);
370
    IF n = -1 THEN
371
    IF n = -1 THEN
371
        n := 255
372
        n := 255
372
    END
373
    END
373
 
374
 
374
    RETURN n
375
    RETURN n
375
END lg2;
376
END lg2;
376
 
377
 
377
 
378
 
378
PROCEDURE mulInt* (VAR a: INTEGER; b: INTEGER): BOOLEAN;
379
PROCEDURE mulInt* (VAR a: INTEGER; b: INTEGER): BOOLEAN;
379
VAR
380
VAR
380
    error:    BOOLEAN;
381
    error:    BOOLEAN;
381
    min, max: INTEGER;
382
    min, max: INTEGER;
382
 
383
 
383
BEGIN
384
BEGIN
384
    min := UTILS.minint;
385
    min := UTILS.minint;
385
    max := UTILS.maxint;
386
    max := UTILS.maxint;
386
 
387
 
387
    IF ((a > 1) & (b > 1)) OR ((a < 0) & (b < 0)) THEN
388
    IF ((a > 1) & (b > 1)) OR ((a < 0) & (b < 0)) THEN
388
        error := (a = min) OR (b = min) OR (ABS(a) > max DIV ABS(b))
389
        error := (a = min) OR (b = min) OR (ABS(a) > max DIV ABS(b))
389
 
390
 
390
    ELSIF ((a > 1) & (b < 0)) OR ((a < 0) & (b > 1)) THEN
391
    ELSIF ((a > 1) & (b < 0)) OR ((a < 0) & (b > 1)) THEN
391
        error := (a = min) OR (b = min);
392
        error := (a = min) OR (b = min);
392
        IF ~error THEN
393
        IF ~error THEN
393
            IF lg2(ABS(a)) + lg2(ABS(b)) >= UTILS.bit_depth THEN
394
            IF lg2(ABS(a)) + lg2(ABS(b)) >= UTILS.bit_depth THEN
394
                error := ABS(a) > max DIV ABS(b)
395
                error := ABS(a) > max DIV ABS(b)
395
            END
396
            END
396
        END
397
        END
397
 
398
 
398
    ELSE
399
    ELSE
399
        error := FALSE
400
        error := FALSE
400
    END;
401
    END;
401
 
402
 
402
    IF ~error THEN
403
    IF ~error THEN
403
        a := a * b
404
        a := a * b
404
    ELSE
405
    ELSE
405
        a := 0
406
        a := 0
406
    END
407
    END
407
 
408
 
408
    RETURN ~error
409
    RETURN ~error
409
END mulInt;
410
END mulInt;
410
 
411
 
411
 
412
 
412
PROCEDURE _ASR (x, n: INTEGER): INTEGER;
413
PROCEDURE _ASR (x, n: INTEGER): INTEGER;
413
    RETURN ASR(UTILS.Long(x), n)
414
    RETURN ASR(UTILS.Long(x), n)
414
END _ASR;
415
END _ASR;
415
 
416
 
416
 
417
 
417
PROCEDURE _LSR (x, n: INTEGER): INTEGER;
418
PROCEDURE _LSR (x, n: INTEGER): INTEGER;
418
    RETURN UTILS.Long(LSR(UTILS.Short(x), n))
419
    RETURN UTILS.Long(LSR(UTILS.Short(x), n))
419
END _LSR;
420
END _LSR;
420
 
421
 
421
 
422
 
422
PROCEDURE _LSL (x, n: INTEGER): INTEGER;
423
PROCEDURE _LSL (x, n: INTEGER): INTEGER;
423
    RETURN UTILS.Long(LSL(x, n))
424
    RETURN UTILS.Long(LSL(x, n))
424
END _LSL;
425
END _LSL;
425
 
426
 
426
 
427
 
427
PROCEDURE _ROR1_32 (x: INTEGER): INTEGER;
428
PROCEDURE _ROR1_32 (x: INTEGER): INTEGER;
428
BEGIN
429
BEGIN
429
    x := UTILS.Short(x);
430
    x := UTILS.Short(x);
430
    x := ORD(BITS(LSR(x, 1)) + BITS(LSL(x, 31)))
431
    x := ORD(BITS(LSR(x, 1)) + BITS(LSL(x, 31)))
431
    RETURN UTILS.Long(x)
432
    RETURN UTILS.Long(x)
432
END _ROR1_32;
433
END _ROR1_32;
433
 
434
 
434
 
435
 
435
PROCEDURE _ROR1_16 (x: INTEGER): INTEGER;
436
PROCEDURE _ROR1_16 (x: INTEGER): INTEGER;
436
BEGIN
437
BEGIN
437
    x := x MOD 65536;
438
    x := x MOD 65536;
438
    x := ORD(BITS(LSR(x, 1)) + BITS(LSL(x, 15)))
439
    x := ORD(BITS(LSR(x, 1)) + BITS(LSL(x, 15)))
439
    RETURN UTILS.Long(x)
440
    RETURN UTILS.Long(x)
440
END _ROR1_16;
441
END _ROR1_16;
441
 
442
 
442
 
443
 
443
PROCEDURE _ROR (x, n: INTEGER): INTEGER;
444
PROCEDURE _ROR (x, n: INTEGER): INTEGER;
444
BEGIN
445
BEGIN
445
 
446
 
446
    CASE UTILS.bit_diff OF
447
    CASE UTILS.bit_diff OF
447
    |0: x := ROR(x, n)
448
    |0: x := ROR(x, n)
448
    |16, 48:
449
    |16, 48:
449
        n := n MOD 16;
450
        n := n MOD 16;
450
        WHILE n > 0 DO
451
        WHILE n > 0 DO
451
            x := _ROR1_16(x);
452
            x := _ROR1_16(x);
452
            DEC(n)
453
            DEC(n)
453
        END
454
        END
454
    |32:
455
    |32:
455
        n := n MOD 32;
456
        n := n MOD 32;
456
        WHILE n > 0 DO
457
        WHILE n > 0 DO
457
            x := _ROR1_32(x);
458
            x := _ROR1_32(x);
458
            DEC(n)
459
            DEC(n)
459
        END
460
        END
460
    END
461
    END
461
 
462
 
462
    RETURN x
463
    RETURN x
463
END _ROR;
464
END _ROR;
464
 
465
 
465
 
466
 
466
PROCEDURE opInt* (VAR a: VALUE; b: VALUE; op: CHAR): BOOLEAN;
467
PROCEDURE opInt* (VAR a: VALUE; b: VALUE; op: CHAR): BOOLEAN;
467
VAR
468
VAR
468
    success: BOOLEAN;
469
    success: BOOLEAN;
469
 
470
 
470
BEGIN
471
BEGIN
471
    success := TRUE;
472
    success := TRUE;
472
 
473
 
473
    CASE op OF
474
    CASE op OF
474
    |"+": success := addInt(a.int, b.int)
475
    |"+": success := addInt(a.int, b.int)
475
    |"-": success := subInt(a.int, b.int)
476
    |"-": success := subInt(a.int, b.int)
476
    |"*": success := mulInt(a.int, b.int)
477
    |"*": success := mulInt(a.int, b.int)
477
    |"/": success := FALSE
478
    |"/": success := FALSE
478
    |"D": a.int := a.int DIV b.int
479
    |"D": a.int := a.int DIV b.int
479
    |"M": a.int := a.int MOD b.int
480
    |"M": a.int := a.int MOD b.int
480
    |"L": a.int := _LSL(a.int, b.int)
481
    |"L": a.int := _LSL(a.int, b.int)
481
    |"A": a.int := _ASR(a.int, b.int)
482
    |"A": a.int := _ASR(a.int, b.int)
482
    |"O": a.int := _ROR(a.int, b.int)
483
    |"O": a.int := _ROR(a.int, b.int)
483
    |"R": a.int := _LSR(a.int, b.int)
484
    |"R": a.int := _LSR(a.int, b.int)
484
    |"m": a.int := MIN(a.int, b.int)
485
    |"m": a.int := MIN(a.int, b.int)
485
    |"x": a.int := MAX(a.int, b.int)
486
    |"x": a.int := MAX(a.int, b.int)
486
    END;
487
    END;
487
    a.typ := tINTEGER
488
    a.typ := tINTEGER
488
 
489
 
489
    RETURN success & check(a)
490
    RETURN success & check(a)
490
END opInt;
491
END opInt;
491
 
492
 
492
 
493
 
493
PROCEDURE charToStr* (c: VALUE; VAR s: ARRAY OF CHAR);
494
PROCEDURE charToStr* (c: VALUE; VAR s: ARRAY OF CHAR);
494
BEGIN
495
BEGIN
495
    s[0] := CHR(c.int);
496
    s[0] := CHR(c.int);
496
    s[1] := 0X
497
    s[1] := 0X
497
END charToStr;
498
END charToStr;
498
 
499
 
499
 
500
 
500
PROCEDURE opSet* (VAR a: VALUE; b: VALUE; op: CHAR);
501
PROCEDURE opSet* (VAR a: VALUE; b: VALUE; op: CHAR);
501
BEGIN
502
BEGIN
502
    CASE op OF
503
    CASE op OF
503
    |"+": a.set := a.set + b.set
504
    |"+": a.set := a.set + b.set
504
    |"-": a.set := a.set - b.set
505
    |"-": a.set := a.set - b.set
505
    |"*": a.set := a.set * b.set
506
    |"*": a.set := a.set * b.set
506
    |"/": a.set := a.set / b.set
507
    |"/": a.set := a.set / b.set
507
    END;
508
    END;
508
    a.typ := tSET
509
    a.typ := tSET
509
END opSet;
510
END opSet;
510
 
511
 
511
 
512
 
512
PROCEDURE opFloat* (VAR a: VALUE; b: VALUE; op: CHAR): BOOLEAN;
513
PROCEDURE opFloat* (VAR a: VALUE; b: VALUE; op: CHAR): BOOLEAN;
513
BEGIN
514
BEGIN
514
    a.typ := tREAL
515
    a.typ := tREAL
515
    RETURN opFloat2(a.float, b.float, op) & check(a)
516
    RETURN opFloat2(a.float, b.float, op) & check(a)
516
END opFloat;
517
END opFloat;
517
 
518
 
518
 
519
 
519
PROCEDURE ord* (VAR v: VALUE);
520
PROCEDURE ord* (VAR v: VALUE);
520
BEGIN
521
BEGIN
521
    CASE v.typ OF
522
    CASE v.typ OF
522
    |tCHAR, tWCHAR:
523
    |tCHAR, tWCHAR:
523
    |tBOOLEAN: v.int := ORD(v.bool)
524
    |tBOOLEAN: v.int := ORD(v.bool)
524
    |tSET:     v.int := UTILS.Long(ORD(v.set))
525
    |tSET:     v.int := UTILS.Long(ORD(v.set))
525
    END;
526
    END;
526
    v.typ := tINTEGER
527
    v.typ := tINTEGER
527
END ord;
528
END ord;
528
 
529
 
529
 
530
 
530
PROCEDURE odd* (VAR v: VALUE);
531
PROCEDURE odd* (VAR v: VALUE);
531
BEGIN
532
BEGIN
532
    v.typ := tBOOLEAN;
533
    v.typ := tBOOLEAN;
533
    v.bool := ODD(v.int)
534
    v.bool := ODD(v.int)
534
END odd;
535
END odd;
535
 
536
 
536
 
537
 
537
PROCEDURE bits* (VAR v: VALUE);
538
PROCEDURE bits* (VAR v: VALUE);
538
BEGIN
539
BEGIN
539
    v.typ := tSET;
540
    v.typ := tSET;
540
    v.set := BITS(v.int)
541
    v.set := BITS(v.int)
541
END bits;
542
END bits;
542
 
543
 
543
 
544
 
544
PROCEDURE abs* (VAR v: VALUE): BOOLEAN;
545
PROCEDURE abs* (VAR v: VALUE): BOOLEAN;
545
VAR
546
VAR
546
    res: BOOLEAN;
547
    res: BOOLEAN;
547
 
548
 
548
BEGIN
549
BEGIN
549
    res := FALSE;
550
    res := FALSE;
550
 
551
 
551
    CASE v.typ OF
552
    CASE v.typ OF
552
    |tREAL:
553
    |tREAL:
553
        v.float := ABS(v.float);
554
        v.float := ABS(v.float);
554
        res := TRUE
555
        res := TRUE
555
    |tINTEGER:
556
    |tINTEGER:
556
        IF v.int # UTILS.minint THEN
557
        IF v.int # UTILS.minint THEN
557
            v.int := ABS(v.int);
558
            v.int := ABS(v.int);
558
            res := TRUE
559
            res := TRUE
559
        END
560
        END
560
    END
561
    END
561
 
562
 
562
    RETURN res
563
    RETURN res
563
END abs;
564
END abs;
564
 
565
 
565
 
566
 
566
PROCEDURE floor* (VAR v: VALUE): BOOLEAN;
567
PROCEDURE floor* (VAR v: VALUE): BOOLEAN;
567
VAR
568
VAR
568
    res: BOOLEAN;
569
    res: BOOLEAN;
569
 
570
 
570
BEGIN
571
BEGIN
571
    v.typ := tINTEGER;
572
    v.typ := tINTEGER;
572
    res := (FLT(UTILS.minint) <= v.float) & (v.float <= FLT(UTILS.maxint));
573
    res := (FLT(UTILS.minint) <= v.float) & (v.float <= FLT(UTILS.maxint));
573
    IF res THEN
574
    IF res THEN
574
        v.int := FLOOR(v.float)
575
        v.int := FLOOR(v.float)
575
    END
576
    END
576
 
577
 
577
    RETURN res
578
    RETURN res
578
END floor;
579
END floor;
579
 
580
 
580
 
581
 
581
PROCEDURE flt* (VAR v: VALUE);
582
PROCEDURE flt* (VAR v: VALUE);
582
BEGIN
583
BEGIN
583
    v.typ := tREAL;
584
    v.typ := tREAL;
584
    v.float := FLT(v.int)
585
    v.float := FLT(v.int)
585
END flt;
586
END flt;
586
 
587
 
587
 
588
 
588
PROCEDURE neg* (VAR v: VALUE): BOOLEAN;
589
PROCEDURE neg* (VAR v: VALUE): BOOLEAN;
589
VAR
590
VAR
590
    z: VALUE;
591
    z: VALUE;
591
    res: BOOLEAN;
592
    res: BOOLEAN;
592
 
593
 
593
BEGIN
594
BEGIN
594
    res := TRUE;
595
    res := TRUE;
595
 
596
 
596
    z.typ := tINTEGER;
597
    z.typ := tINTEGER;
597
    z.int := 0;
598
    z.int := 0;
598
 
599
 
599
    CASE v.typ OF
600
    CASE v.typ OF
600
    |tREAL:     v.float := -v.float
601
    |tREAL:     v.float := -v.float
601
    |tSET:      v.set := -v.set
602
    |tSET:      v.set := -v.set
602
    |tINTEGER:  res := opInt(z, v, "-"); v := z
603
    |tINTEGER:  res := opInt(z, v, "-"); v := z
603
    |tBOOLEAN:  v.bool := ~v.bool
604
    |tBOOLEAN:  v.bool := ~v.bool
604
    END
605
    END
605
 
606
 
606
    RETURN res
607
    RETURN res
607
END neg;
608
END neg;
608
 
609
 
609
 
610
 
610
PROCEDURE setbool* (VAR v: VALUE; b: BOOLEAN);
611
PROCEDURE setbool* (VAR v: VALUE; b: BOOLEAN);
611
BEGIN
612
BEGIN
612
    v.bool := b;
613
    v.bool := b;
613
    v.typ := tBOOLEAN
614
    v.typ := tBOOLEAN
614
END setbool;
615
END setbool;
615
 
616
 
616
 
617
 
617
PROCEDURE opBoolean* (VAR a: VALUE; b: VALUE; op: CHAR);
618
PROCEDURE opBoolean* (VAR a: VALUE; b: VALUE; op: CHAR);
618
BEGIN
619
BEGIN
619
    CASE op OF
620
    CASE op OF
620
    |"&": a.bool := a.bool & b.bool
621
    |"&": a.bool := a.bool & b.bool
621
    |"|": a.bool := a.bool OR b.bool
622
    |"|": a.bool := a.bool OR b.bool
622
    END;
623
    END;
623
    a.typ := tBOOLEAN
624
    a.typ := tBOOLEAN
624
END opBoolean;
625
END opBoolean;
625
 
626
 
626
 
627
 
627
PROCEDURE less (v, v2: VALUE; VAR error: INTEGER): BOOLEAN;
628
PROCEDURE less (v, v2: VALUE; VAR error: INTEGER): BOOLEAN;
628
VAR
629
VAR
629
    res: BOOLEAN;
630
    res: BOOLEAN;
630
 
631
 
631
BEGIN
632
BEGIN
632
    res := FALSE;
633
    res := FALSE;
633
 
634
 
634
    IF (v.typ = v2.typ) OR (v.typ IN {tCHAR, tWCHAR}) & (v2.typ IN {tCHAR, tWCHAR}) THEN
635
    IF (v.typ = v2.typ) OR (v.typ IN {tCHAR, tWCHAR}) & (v2.typ IN {tCHAR, tWCHAR}) THEN
635
        CASE v.typ OF
636
        CASE v.typ OF
636
        |tINTEGER,
637
        |tINTEGER,
637
         tWCHAR,
638
         tWCHAR,
638
         tCHAR:     res := v.int < v2.int
639
         tCHAR:     res := v.int < v2.int
639
        |tREAL:     res := v.float < v2.float
640
        |tREAL:     res := v.float < v2.float
640
        |tBOOLEAN,
641
        |tBOOLEAN,
641
         tSET:      error := 1
642
         tSET:      error := 1
642
        END
643
        END
643
    ELSE
644
    ELSE
644
        error := 1
645
        error := 1
645
    END
646
    END
646
 
647
 
647
    RETURN res
648
    RETURN res
648
END less;
649
END less;
649
 
650
 
650
 
651
 
651
PROCEDURE equal (v, v2: VALUE; VAR error: INTEGER): BOOLEAN;
652
PROCEDURE equal (v, v2: VALUE; VAR error: INTEGER): BOOLEAN;
652
VAR
653
VAR
653
    res: BOOLEAN;
654
    res: BOOLEAN;
654
 
655
 
655
BEGIN
656
BEGIN
656
    res := FALSE;
657
    res := FALSE;
657
 
658
 
658
    IF (v.typ = v2.typ) OR (v.typ IN {tCHAR, tWCHAR}) & (v2.typ IN {tCHAR, tWCHAR}) THEN
659
    IF (v.typ = v2.typ) OR (v.typ IN {tCHAR, tWCHAR}) & (v2.typ IN {tCHAR, tWCHAR}) THEN
659
        CASE v.typ OF
660
        CASE v.typ OF
660
        |tINTEGER,
661
        |tINTEGER,
661
         tWCHAR,
662
         tWCHAR,
662
         tCHAR:     res := v.int = v2.int
663
         tCHAR:     res := v.int = v2.int
663
        |tREAL:     res := v.float = v2.float
664
        |tREAL:     res := v.float = v2.float
664
        |tBOOLEAN:  res := v.bool = v2.bool
665
        |tBOOLEAN:  res := v.bool = v2.bool
665
        |tSET:      res := v.set = v2.set
666
        |tSET:      res := v.set = v2.set
666
        END
667
        END
667
    ELSE
668
    ELSE
668
        error := 1
669
        error := 1
669
    END
670
    END
670
 
671
 
671
    RETURN res
672
    RETURN res
672
END equal;
673
END equal;
673
 
674
 
674
 
675
 
675
PROCEDURE relation* (VAR v: VALUE; v2: VALUE; operator: RELATION; VAR error: INTEGER);
676
PROCEDURE relation* (VAR v: VALUE; v2: VALUE; op: INTEGER; VAR error: INTEGER);
676
VAR
677
VAR
677
    res: BOOLEAN;
678
    res: BOOLEAN;
678
 
679
 
679
BEGIN
680
BEGIN
680
    error := 0;
681
    error := 0;
681
 
682
 
682
    res := FALSE;
683
    res := FALSE;
683
 
684
 
684
    CASE operator[0] OF
685
    CASE op OF
685
 
686
 
686
    |"=":
687
    |opEQ:
687
        res := equal(v, v2, error)
688
        res := equal(v, v2, error)
688
 
689
 
689
    |"#":
690
    |opNE:
-
 
691
        res := ~equal(v, v2, error)
-
 
692
 
690
        res := ~equal(v, v2, error)
693
    |opLT:
691
 
694
        res := less(v, v2, error)
692
    |"<":
695
 
693
        IF operator[1] = "=" THEN
696
    |opLE:
694
            res := less(v, v2, error);
697
        res := less(v, v2, error);
695
            IF error = 0 THEN
698
        IF error = 0 THEN
696
                res := equal(v, v2, error) OR res
699
            res := equal(v, v2, error) OR res
697
            END
700
        END
698
        ELSE
-
 
699
            res := less(v, v2, error)
-
 
700
        END
-
 
701
 
701
 
702
    |">":
-
 
703
        IF operator[1] = "=" THEN
702
    |opGE:
-
 
703
        res := ~less(v, v2, error)
704
            res := ~less(v, v2, error)
704
 
705
        ELSE
705
    |opGT:
706
            res := less(v, v2, error);
706
        res := less(v, v2, error);
707
            IF error = 0 THEN
707
        IF error = 0 THEN
708
                res := equal(v, v2, error) OR res
708
            res := equal(v, v2, error) OR res
709
            END;
709
        END;
710
            res := ~res
710
        res := ~res
711
        END
-
 
712
 
711
 
713
    |"I":
712
    |opIN:
714
        IF (v.typ = tINTEGER) & (v2.typ = tSET) THEN
713
        IF (v.typ = tINTEGER) & (v2.typ = tSET) THEN
715
            IF range(v, 0, UTILS.target.maxSet) THEN
714
            IF range(v, 0, UTILS.target.maxSet) THEN
716
                res := v.int IN v2.set
715
                res := v.int IN v2.set
717
            ELSE
716
            ELSE
718
                error := 2
717
                error := 2
719
            END
718
            END
720
        ELSE
719
        ELSE
721
            error := 1
720
            error := 1
722
        END
721
        END
723
 
722
 
724
    END;
723
    END;
725
 
724
 
726
    IF error = 0 THEN
725
    IF error = 0 THEN
727
        v.bool := res;
726
        v.bool := res;
728
        v.typ  := tBOOLEAN
727
        v.typ  := tBOOLEAN
729
    END
728
    END
730
 
729
 
731
END relation;
730
END relation;
732
 
731
 
733
 
732
 
734
PROCEDURE emptySet* (VAR v: VALUE);
733
PROCEDURE emptySet* (VAR v: VALUE);
735
BEGIN
734
BEGIN
736
    v.typ := tSET;
735
    v.typ := tSET;
737
    v.set := {}
736
    v.set := {}
738
END emptySet;
737
END emptySet;
739
 
738
 
740
 
739
 
741
PROCEDURE constrSet* (VAR v: VALUE; a, b: VALUE);
740
PROCEDURE constrSet* (VAR v: VALUE; a, b: VALUE);
742
BEGIN
741
BEGIN
743
    v.typ := tSET;
742
    v.typ := tSET;
744
    v.set := {a.int .. b.int}
743
    v.set := {a.int .. b.int}
745
END constrSet;
744
END constrSet;
746
 
745
 
747
 
746
 
748
PROCEDURE getInt* (v: VALUE): INTEGER;
747
PROCEDURE getInt* (v: VALUE): INTEGER;
749
BEGIN
748
BEGIN
750
    ASSERT(check(v))
749
    ASSERT(check(v))
751
 
750
 
752
    RETURN v.int
751
    RETURN v.int
753
END getInt;
752
END getInt;
754
 
753
 
755
 
754
 
756
PROCEDURE setInt* (VAR v: VALUE; i: INTEGER): BOOLEAN;
755
PROCEDURE setInt* (VAR v: VALUE; i: INTEGER): BOOLEAN;
757
BEGIN
756
BEGIN
758
    v.int := i;
757
    v.int := i;
759
    v.typ := tINTEGER
758
    v.typ := tINTEGER
760
 
759
 
761
    RETURN check(v)
760
    RETURN check(v)
762
END setInt;
761
END setInt;
-
 
762
 
-
 
763
 
-
 
764
PROCEDURE concat* (VAR s: ARRAY OF CHAR; s1: ARRAY OF CHAR): BOOLEAN;
-
 
765
VAR
-
 
766
    res: BOOLEAN;
-
 
767
 
-
 
768
BEGIN
-
 
769
    res := LENGTH(s) + LENGTH(s1) < LEN(s);
-
 
770
    IF res THEN
-
 
771
        STRINGS.append(s, s1)
-
 
772
    END
-
 
773
 
-
 
774
    RETURN res
-
 
775
END concat;
763
 
776
 
764
 
777
 
765
PROCEDURE init;
778
PROCEDURE init;
766
VAR
779
VAR
767
    i: INTEGER;
780
    i: INTEGER;
768
 
781
 
769
BEGIN
782
BEGIN
770
    FOR i := 0 TO LEN(digit) - 1 DO
783
    FOR i := 0 TO LEN(digit) - 1 DO
771
        digit[i] := -1
784
        digit[i] := -1
772
    END;
785
    END;
773
 
786
 
774
    FOR i := ORD("0") TO ORD("9") DO
787
    FOR i := ORD("0") TO ORD("9") DO
775
        digit[i] := i - ORD("0")
788
        digit[i] := i - ORD("0")
776
    END;
789
    END;
777
 
790
 
778
    FOR i := ORD("A") TO ORD("F") DO
791
    FOR i := ORD("A") TO ORD("F") DO
779
        digit[i] := i - ORD("A") + 10
792
        digit[i] := i - ORD("A") + 10
780
    END
793
    END
781
END init;
794
END init;
782
 
795
 
783
 
796
 
784
BEGIN
797
BEGIN
785
    init
798
    init
786
END ARITH.
799
END ARITH.
787
>
-