Subversion Repositories Kolibri OS

Rev

Rev 8859 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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