Subversion Repositories Kolibri OS

Rev

Rev 7667 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 7667 Rev 7693
Line 7... Line 7...
7
 
7
 
Line 8... Line 8...
8
MODULE STATEMENTS;
8
MODULE STATEMENTS;
Line 9... Line 9...
9
 
9
 
10
IMPORT
10
IMPORT
Line 11... Line 11...
11
 
11
 
Line 12... Line 12...
12
    PARS, PROG, SCAN, ARITH, STRINGS, LISTS, CODE, X86, AMD64,
12
    PARS, PROG, SCAN, ARITH, STRINGS, LISTS, IL, X86, AMD64, MSP430,
Line 27... Line 27...
27
 
27
 
Line 28... Line 28...
28
    chkIDX* = 0; chkGUARD* = 1; chkPTR* = 2; chkCHR* = 3; chkWCHR* = 4; chkBYTE* = 5;
28
    chkIDX* = 0; chkGUARD* = 1; chkPTR* = 2; chkCHR* = 3; chkWCHR* = 4; chkBYTE* = 5;
Line -... Line 29...
-
 
29
 
-
 
30
    chkALL* = {chkIDX, chkGUARD, chkPTR, chkCHR, chkWCHR, chkBYTE};
Line 29... Line 31...
29
 
31
 
Line 30... Line 32...
30
    chkALL* = {chkIDX, chkGUARD, chkPTR, chkCHR, chkWCHR, chkBYTE};
32
    cpuX86 = 1; cpuAMD64 = 2; cpuMSP430 = 3;
Line 55... Line 57...
55
    END;
57
    END;
Line 56... Line 58...
56
 
58
 
Line 57... Line 59...
57
    CASE_VARIANT = POINTER TO RECORD (LISTS.ITEM)
59
    CASE_VARIANT = POINTER TO RECORD (LISTS.ITEM)
58
 
60
 
59
        label:      INTEGER;
61
        label:     INTEGER;
Line 60... Line 62...
60
        cmd:        CODE.COMMAND;
62
        cmd:       IL.COMMAND;
Line 61... Line 63...
61
        processed:  BOOLEAN
63
        processed: BOOLEAN
Line 62... Line 64...
62
 
64
 
Line 63... Line 65...
63
    END;
65
    END;
Line 64... Line 66...
64
 
66
 
Line 65... Line 67...
65
 
67
 
Line -... Line 68...
-
 
68
VAR
-
 
69
 
-
 
70
    Options: PROG.OPTIONS;
-
 
71
 
Line 66... Line 72...
66
VAR
72
    begcall, endcall: IL.COMMAND;
67
 
73
 
68
    begcall, endcall: CODE.COMMAND;
74
    CaseLabels, CaseVar: C.COLLECTION;
Line 83... Line 89...
83
    RETURN e.obj IN {eVAR, eVPAR, ePARAM, eVREC}
89
    RETURN e.obj IN {eVAR, eVPAR, ePARAM, eVREC}
84
END isVar;
90
END isVar;
Line 85... Line 91...
85
 
91
 
86
 
92
 
87
PROCEDURE isBoolean (e: PARS.EXPR): BOOLEAN;
93
PROCEDURE isBoolean (e: PARS.EXPR): BOOLEAN;
Line 88... Line 94...
88
    RETURN isExpr(e) & (e.type.typ = PROG.tBOOLEAN)
94
    RETURN isExpr(e) & (e.type = tBOOLEAN)
89
END isBoolean;
95
END isBoolean;
90
 
96
 
Line 91... Line 97...
91
 
97
 
92
PROCEDURE isInteger (e: PARS.EXPR): BOOLEAN;
98
PROCEDURE isInteger (e: PARS.EXPR): BOOLEAN;
93
    RETURN isExpr(e) & (e.type.typ = PROG.tINTEGER)
99
    RETURN isExpr(e) & (e.type = tINTEGER)
Line 94... Line 100...
94
END isInteger;
100
END isInteger;
95
 
101
 
96
 
102
 
Line 97... Line 103...
97
PROCEDURE isByte (e: PARS.EXPR): BOOLEAN;
103
PROCEDURE isByte (e: PARS.EXPR): BOOLEAN;
98
    RETURN isExpr(e) & (e.type.typ = PROG.tBYTE)
104
    RETURN isExpr(e) & (e.type = tBYTE)
99
END isByte;
105
END isByte;
Line 100... Line 106...
100
 
106
 
101
 
107
 
102
PROCEDURE isInt (e: PARS.EXPR): BOOLEAN;
108
PROCEDURE isInt (e: PARS.EXPR): BOOLEAN;
Line 103... Line 109...
103
    RETURN isByte(e) OR isInteger(e)
109
    RETURN isByte(e) OR isInteger(e)
104
END isInt;
110
END isInt;
Line 123... Line 129...
123
    RETURN (e.obj = eCONST) & (e.type.typ IN {PROG.tSTRING, PROG.tCHAR, PROG.tWCHAR})
129
    RETURN (e.obj = eCONST) & (e.type.typ IN {PROG.tSTRING, PROG.tCHAR, PROG.tWCHAR})
124
END isStringW;
130
END isStringW;
Line 125... Line 131...
125
 
131
 
126
 
132
 
127
PROCEDURE isChar (e: PARS.EXPR): BOOLEAN;
133
PROCEDURE isChar (e: PARS.EXPR): BOOLEAN;
Line 128... Line -...
128
    RETURN isExpr(e) & (e.type.typ = PROG.tCHAR)
-
 
129
END isChar;
-
 
130
 
-
 
131
 
-
 
132
PROCEDURE isCharArray (e: PARS.EXPR): BOOLEAN;
-
 
133
    RETURN isExpr(e) & (e.type.typ = PROG.tARRAY) & (e.type.base.typ = PROG.tCHAR)
134
    RETURN isExpr(e) & (e.type = tCHAR)
134
END isCharArray;
135
END isChar;
135
 
136
 
Line 136... Line -...
136
 
-
 
137
PROCEDURE isCharW (e: PARS.EXPR): BOOLEAN;
-
 
138
    RETURN isExpr(e) & (e.type.typ = PROG.tWCHAR)
-
 
139
END isCharW;
-
 
140
 
-
 
141
 
-
 
142
PROCEDURE isCharArrayW (e: PARS.EXPR): BOOLEAN;
-
 
143
    RETURN isExpr(e) & (e.type.typ = PROG.tARRAY) & (e.type.base.typ = PROG.tWCHAR)
-
 
144
END isCharArrayW;
-
 
145
 
-
 
146
 
137
 
147
PROCEDURE isCharArrayX (e: PARS.EXPR): BOOLEAN;
138
PROCEDURE isCharW (e: PARS.EXPR): BOOLEAN;
148
    RETURN isExpr(e) & (e.type.typ = PROG.tARRAY) & (e.type.base.typ IN {PROG.tCHAR, PROG.tWCHAR})
139
    RETURN isExpr(e) & (e.type = tWCHAR)
Line 149... Line 140...
149
END isCharArrayX;
140
END isCharW;
150
 
141
 
151
 
142
 
Line -... Line 143...
-
 
143
PROCEDURE isPtr (e: PARS.EXPR): BOOLEAN;
-
 
144
    RETURN isExpr(e) & (e.type.typ = PROG.tPOINTER)
-
 
145
END isPtr;
-
 
146
 
-
 
147
 
152
PROCEDURE isPtr (e: PARS.EXPR): BOOLEAN;
148
PROCEDURE isRec (e: PARS.EXPR): BOOLEAN;
153
    RETURN isExpr(e) & (e.type.typ = PROG.tPOINTER)
149
    RETURN isExpr(e) & (e.type.typ = PROG.tRECORD)
154
END isPtr;
150
END isRec;
Line 172... Line 168...
172
PROCEDURE isNil (e: PARS.EXPR): BOOLEAN;
168
PROCEDURE isNil (e: PARS.EXPR): BOOLEAN;
173
    RETURN e.type.typ = PROG.tNIL
169
    RETURN e.type.typ = PROG.tNIL
174
END isNil;
170
END isNil;
Line -... Line 171...
-
 
171
 
-
 
172
 
-
 
173
PROCEDURE isCharArray (e: PARS.EXPR): BOOLEAN;
-
 
174
    RETURN isArr(e) & (e.type.base = tCHAR)
-
 
175
END isCharArray;
-
 
176
 
-
 
177
 
-
 
178
PROCEDURE isCharArrayW (e: PARS.EXPR): BOOLEAN;
-
 
179
    RETURN isArr(e) & (e.type.base = tWCHAR)
-
 
180
END isCharArrayW;
-
 
181
 
-
 
182
 
-
 
183
PROCEDURE isCharArrayX (e: PARS.EXPR): BOOLEAN;
-
 
184
    RETURN isCharArray(e) OR isCharArrayW(e)
-
 
185
END isCharArrayX;
175
 
186
 
176
 
187
 
-
 
188
PROCEDURE getpos (parser: PARS.PARSER; VAR pos: PARS.POSITION);
177
PROCEDURE getpos (parser: PARS.PARSER; VAR pos: SCAN.POSITION);
189
BEGIN
-
 
190
    pos.line   := parser.lex.pos.line;
178
BEGIN
191
    pos.col    := parser.lex.pos.col;
Line 179... Line 192...
179
    pos := parser.lex.pos
192
    pos.parser := parser
180
END getpos;
193
END getpos;
-
 
194
 
181
 
195
 
182
 
196
PROCEDURE NextPos (parser: PARS.PARSER; VAR pos: PARS.POSITION);
Line 183... Line 197...
183
PROCEDURE NextPos (parser: PARS.PARSER; VAR pos: SCAN.POSITION);
197
BEGIN
184
BEGIN
198
    PARS.Next(parser);
185
    PARS.NextPos(parser, pos)
199
    getpos(parser, pos)
Line 186... Line 200...
186
END NextPos;
200
END NextPos;
187
 
201
 
188
 
202
 
189
PROCEDURE strlen (e: PARS.EXPR): INTEGER;
203
PROCEDURE strlen (e: PARS.EXPR): INTEGER;
190
VAR
204
VAR
191
    res: INTEGER;
205
    res: INTEGER;
192
 
206
 
193
BEGIN
207
BEGIN
Line 264... Line 278...
264
BEGIN
278
BEGIN
265
    IF isExpr(e) OR (e.obj IN {ePROC, eIMP}) THEN
279
    IF isExpr(e) OR (e.obj IN {ePROC, eIMP}) THEN
266
        IF arrcomp(e.type, t) THEN
280
        IF arrcomp(e.type, t) THEN
267
            res := TRUE
281
            res := TRUE
268
        ELSIF isInt(e) & (t.typ IN {PROG.tBYTE, PROG.tINTEGER}) THEN
282
        ELSIF isInt(e) & (t.typ IN {PROG.tBYTE, PROG.tINTEGER}) THEN
269
            IF (e.obj = eCONST) & (t.typ = PROG.tBYTE) THEN
283
            IF (e.obj = eCONST) & (t = tBYTE) THEN
270
                res := ARITH.range(e.value, 0, 255)
284
                res := ARITH.range(e.value, 0, 255)
271
            ELSE
285
            ELSE
272
                res := TRUE
286
                res := TRUE
273
            END
287
            END
274
        ELSIF isSet(e) & (t.typ = PROG.tSET) THEN
288
        ELSIF isSet(e) & (t = tSET) THEN
275
            res := TRUE
289
            res := TRUE
276
        ELSIF isBoolean(e) & (t.typ = PROG.tBOOLEAN) THEN
290
        ELSIF isBoolean(e) & (t = tBOOLEAN) THEN
277
            res := TRUE
291
            res := TRUE
278
        ELSIF isReal(e) & (t.typ = PROG.tREAL) THEN
292
        ELSIF isReal(e) & (t = tREAL) THEN
279
            res := TRUE
293
            res := TRUE
280
        ELSIF isChar(e) & (t.typ = PROG.tCHAR) THEN
294
        ELSIF isChar(e) & (t = tCHAR) THEN
281
            res := TRUE
295
            res := TRUE
282
        ELSIF (e.obj = eCONST) & isChar(e) & (t.typ = PROG.tWCHAR) THEN
296
        ELSIF (e.obj = eCONST) & isChar(e) & (t = tWCHAR) THEN
283
            res := TRUE
297
            res := TRUE
284
        ELSIF isStringW1(e) & (t.typ = PROG.tWCHAR) THEN
298
        ELSIF isStringW1(e) & (t = tWCHAR) THEN
285
            res := TRUE
299
            res := TRUE
286
        ELSIF isCharW(e) & (t.typ = PROG.tWCHAR) THEN
300
        ELSIF isCharW(e) & (t = tWCHAR) THEN
287
            res := TRUE
301
            res := TRUE
288
        ELSIF PROG.isBaseOf(t, e.type) THEN
302
        ELSIF PROG.isBaseOf(t, e.type) THEN
289
            res := TRUE
303
            res := TRUE
290
        ELSIF ~PROG.isOpenArray(t) & ~PROG.isOpenArray(e.type) & PROG.isTypeEq(t, e.type) THEN
304
        ELSIF ~PROG.isOpenArray(t) & ~PROG.isOpenArray(e.type) & PROG.isTypeEq(t, e.type) THEN
291
            res := TRUE
305
            res := TRUE
292
        ELSIF isNil(e) & (t.typ IN {PROG.tPOINTER, PROG.tPROCEDURE}) THEN
306
        ELSIF isNil(e) & (t.typ IN {PROG.tPOINTER, PROG.tPROCEDURE}) THEN
293
            res := TRUE
307
            res := TRUE
294
        ELSIF isString(e) & ((t.typ = PROG.tARRAY) & (t.base.typ = PROG.tCHAR) & (t.length > strlen(e))) THEN
308
        ELSIF isString(e) & ((t.typ = PROG.tARRAY) & (t.base = tCHAR) & (t.length > strlen(e))) THEN
295
            res := TRUE
309
            res := TRUE
296
        ELSIF isStringW(e) & ((t.typ = PROG.tARRAY) & (t.base.typ = PROG.tWCHAR) & (t.length > utf8strlen(e))) THEN
310
        ELSIF isStringW(e) & ((t.typ = PROG.tARRAY) & (t.base = tWCHAR) & (t.length > utf8strlen(e))) THEN
297
            res := TRUE
311
            res := TRUE
298
        ELSE
312
        ELSE
299
            res := FALSE
313
            res := FALSE
300
        END
314
        END
301
    ELSE
315
    ELSE
Line 312... Line 326...
312
 
326
 
313
BEGIN
327
BEGIN
314
    IF strlen(e) # 1 THEN
328
    IF strlen(e) # 1 THEN
315
        string := e.value.string(SCAN.IDENT);
329
        string := e.value.string(SCAN.IDENT);
316
        IF string.offset = -1 THEN
330
        IF string.offset = -1 THEN
317
            string.offset := CODE.putstr(string.s);
331
            string.offset := IL.putstr(string.s);
318
        END;
332
        END;
319
        offset := string.offset
333
        offset := string.offset
320
    ELSE
334
    ELSE
321
        offset := CODE.putstr1(ARITH.Int(e.value))
335
        offset := IL.putstr1(ARITH.Int(e.value))
Line 322... Line 336...
322
    END
336
    END
323
 
337
 
Line 332... Line 346...
332
 
346
 
333
BEGIN
347
BEGIN
334
    IF utf8strlen(e) # 1 THEN
348
    IF utf8strlen(e) # 1 THEN
335
        string := e.value.string(SCAN.IDENT);
349
        string := e.value.string(SCAN.IDENT);
336
        IF string.offsetW = -1 THEN
350
        IF string.offsetW = -1 THEN
337
            string.offsetW := CODE.putstrW(string.s);
351
            string.offsetW := IL.putstrW(string.s);
338
        END;
352
        END;
339
        offset := string.offsetW
353
        offset := string.offsetW
340
    ELSE
354
    ELSE
341
        IF e.type.typ IN {PROG.tWCHAR, PROG.tCHAR} THEN
355
        IF e.type.typ IN {PROG.tWCHAR, PROG.tCHAR} THEN
342
            offset := CODE.putstrW1(ARITH.Int(e.value))
356
            offset := IL.putstrW1(ARITH.Int(e.value))
343
        ELSE (* e.type.typ = PROG.tSTRING *)
357
        ELSE (* e.type.typ = PROG.tSTRING *)
344
            string := e.value.string(SCAN.IDENT);
358
            string := e.value.string(SCAN.IDENT);
345
            IF string.offsetW = -1 THEN
359
            IF string.offsetW = -1 THEN
346
                string.offsetW := CODE.putstrW(string.s);
360
                string.offsetW := IL.putstrW(string.s);
347
            END;
361
            END;
348
            offset := string.offsetW
362
            offset := string.offsetW
349
        END
363
        END
Line 356... Line 370...
356
PROCEDURE CheckRange (range, line, errno: INTEGER);
370
PROCEDURE CheckRange (range, line, errno: INTEGER);
357
VAR
371
VAR
358
    label: INTEGER;
372
    label: INTEGER;
Line 359... Line 373...
359
 
373
 
360
BEGIN
374
BEGIN
361
    label := CODE.NewLabel();
375
    label := IL.NewLabel();
362
    CODE.AddCmd2(CODE.opCHKIDX, label, range);
376
    IL.AddCmd2(IL.opCHKIDX, label, range);
363
    CODE.OnError(line, errno);
377
    IL.OnError(line, errno);
364
    CODE.SetLabel(label)
378
    IL.SetLabel(label)
Line 365... Line 379...
365
END CheckRange;
379
END CheckRange;
366
 
380
 
Line 382... Line 396...
382
    IF isExpr(e) OR (e.obj IN {ePROC, eIMP}) THEN
396
    IF isExpr(e) OR (e.obj IN {ePROC, eIMP}) THEN
383
        res := TRUE;
397
        res := TRUE;
384
        IF arrcomp(e.type, VarType) THEN
398
        IF arrcomp(e.type, VarType) THEN
Line 385... Line 399...
385
 
399
 
386
            IF ~PROG.isOpenArray(VarType) THEN
400
            IF ~PROG.isOpenArray(VarType) THEN
387
                CODE.AddCmd(CODE.opCONST, VarType.length)
401
                IL.Const(VarType.length)
388
            END;
402
            END;
389
            CODE.AddCmd(CODE.opCOPYA, VarType.base.size);
403
            IL.AddCmd(IL.opCOPYA, VarType.base.size);
390
            label := CODE.NewLabel();
404
            label := IL.NewLabel();
391
            CODE.AddJmpCmd(CODE.opJE, label);
405
            IL.AddJmpCmd(IL.opJE, label);
392
            CODE.OnError(line, errCOPY);
406
            IL.OnError(line, errCOPY);
Line 393... Line 407...
393
            CODE.SetLabel(label)
407
            IL.SetLabel(label)
394
 
408
 
395
        ELSIF isInt(e) & (VarType.typ IN {PROG.tBYTE, PROG.tINTEGER}) THEN
409
        ELSIF isInt(e) & (VarType.typ IN {PROG.tBYTE, PROG.tINTEGER}) THEN
396
            IF VarType.typ = PROG.tINTEGER THEN
410
            IF VarType = tINTEGER THEN
397
                IF e.obj = eCONST THEN
411
                IF e.obj = eCONST THEN
398
                    CODE.AddCmd(CODE.opSAVEC, ARITH.Int(e.value))
412
                    IL.AddCmd(IL.opSAVEC, ARITH.Int(e.value))
399
                ELSE
413
                ELSE
400
                    CODE.AddCmd0(CODE.opSAVE)
414
                    IL.AddCmd0(IL.opSAVE)
401
                END
415
                END
402
            ELSE
416
            ELSE
403
                IF e.obj = eCONST THEN
417
                IF e.obj = eCONST THEN
404
                    res := ARITH.range(e.value, 0, 255);
418
                    res := ARITH.range(e.value, 0, 255);
405
                    IF res THEN
419
                    IF res THEN
406
                        CODE.AddCmd(CODE.opSAVE8C, ARITH.Int(e.value))
420
                        IL.AddCmd(IL.opSAVE8C, ARITH.Int(e.value))
407
                    END
421
                    END
408
                ELSE
422
                ELSE
409
                    IF chkBYTE IN checking THEN
423
                    IF chkBYTE IN Options.checking THEN
410
                        label := CODE.NewLabel();
424
                        label := IL.NewLabel();
411
                        CODE.AddCmd2(CODE.opCHKBYTE, label, 0);
425
                        IL.AddCmd2(IL.opCHKBYTE, label, 0);
412
                        CODE.OnError(line, errBYTE);
426
                        IL.OnError(line, errBYTE);
413
                        CODE.SetLabel(label)
427
                        IL.SetLabel(label)
414
                    END;
428
                    END;
415
                    CODE.AddCmd0(CODE.opSAVE8)
429
                    IL.AddCmd0(IL.opSAVE8)
416
                END
430
                END
417
            END
431
            END
418
        ELSIF isSet(e) & (VarType.typ = PROG.tSET) THEN
432
        ELSIF isSet(e) & (VarType = tSET) THEN
419
            IF e.obj = eCONST THEN
433
            IF e.obj = eCONST THEN
420
                CODE.AddCmd(CODE.opSAVEC, ARITH.Int(e.value))
434
                IL.AddCmd(IL.opSAVEC, ARITH.Int(e.value))
421
            ELSE
435
            ELSE
422
                CODE.AddCmd0(CODE.opSAVE)
436
                IL.AddCmd0(IL.opSAVE)
423
            END
437
            END
424
        ELSIF isBoolean(e) & (VarType.typ = PROG.tBOOLEAN) THEN
438
        ELSIF isBoolean(e) & (VarType = tBOOLEAN) THEN
425
            IF e.obj = eCONST THEN
439
            IF e.obj = eCONST THEN
426
                CODE.AddCmd(CODE.opSBOOLC, ARITH.Int(e.value))
440
                IL.AddCmd(IL.opSBOOLC, ARITH.Int(e.value))
427
            ELSE
441
            ELSE
428
                CODE.AddCmd0(CODE.opSBOOL)
442
                IL.AddCmd0(IL.opSBOOL)
429
            END
443
            END
430
        ELSIF isReal(e) & (VarType.typ = PROG.tREAL) THEN
444
        ELSIF isReal(e) & (VarType = tREAL) THEN
431
            IF e.obj = eCONST THEN
445
            IF e.obj = eCONST THEN
432
                CODE.Float(ARITH.Float(e.value))
446
                IL.Float(ARITH.Float(e.value))
433
            END;
447
            END;
434
            CODE.savef
448
            IL.savef
435
        ELSIF isChar(e) & (VarType.typ = PROG.tCHAR) THEN
449
        ELSIF isChar(e) & (VarType = tCHAR) THEN
436
            IF e.obj = eCONST THEN
450
            IF e.obj = eCONST THEN
437
                CODE.AddCmd(CODE.opSAVE8C, ARITH.Int(e.value))
451
                IL.AddCmd(IL.opSAVE8C, ARITH.Int(e.value))
438
            ELSE
452
            ELSE
439
                CODE.AddCmd0(CODE.opSAVE8)
453
                IL.AddCmd0(IL.opSAVE8)
440
            END
454
            END
441
        ELSIF (e.obj = eCONST) & isChar(e) & (VarType.typ = PROG.tWCHAR) THEN
455
        ELSIF (e.obj = eCONST) & isChar(e) & (VarType = tWCHAR) THEN
442
            CODE.AddCmd(CODE.opSAVE16C, ARITH.Int(e.value))
456
            IL.AddCmd(IL.opSAVE16C, ARITH.Int(e.value))
443
        ELSIF isStringW1(e) & (VarType.typ = PROG.tWCHAR) THEN
457
        ELSIF isStringW1(e) & (VarType = tWCHAR) THEN
444
            CODE.AddCmd(CODE.opSAVE16C, StrToWChar(e.value.string(SCAN.IDENT).s))
458
            IL.AddCmd(IL.opSAVE16C, StrToWChar(e.value.string(SCAN.IDENT).s))
445
        ELSIF isCharW(e) & (VarType.typ = PROG.tWCHAR) THEN
459
        ELSIF isCharW(e) & (VarType = tWCHAR) THEN
446
            IF e.obj = eCONST THEN
460
            IF e.obj = eCONST THEN
447
                CODE.AddCmd(CODE.opSAVE16C, ARITH.Int(e.value))
461
                IL.AddCmd(IL.opSAVE16C, ARITH.Int(e.value))
448
            ELSE
462
            ELSE
449
                CODE.AddCmd0(CODE.opSAVE16)
463
                IL.AddCmd0(IL.opSAVE16)
450
            END
464
            END
451
        ELSIF PROG.isBaseOf(VarType, e.type) THEN
465
        ELSIF PROG.isBaseOf(VarType, e.type) THEN
452
            IF VarType.typ = PROG.tPOINTER THEN
466
            IF VarType.typ = PROG.tPOINTER THEN
453
                CODE.AddCmd0(CODE.opSAVE)
467
                IL.AddCmd0(IL.opSAVE)
454
            ELSE
468
            ELSE
455
                CODE.AddCmd(CODE.opCOPY, VarType.size)
469
                IL.AddCmd(IL.opCOPY, VarType.size)
456
            END
470
            END
457
        ELSIF (e.type.typ = PROG.tCARD32) & (VarType.typ = PROG.tCARD32) THEN
471
        ELSIF (e.type.typ = PROG.tCARD32) & (VarType.typ = PROG.tCARD32) THEN
458
            CODE.AddCmd0(CODE.opSAVE32)
472
            IL.AddCmd0(IL.opSAVE32)
459
        ELSIF (e.type.typ = PROG.tCARD16) & (VarType.typ = PROG.tCARD16) THEN
473
        ELSIF (e.type.typ = PROG.tCARD16) & (VarType.typ = PROG.tCARD16) THEN
460
            CODE.AddCmd0(CODE.opSAVE16)
474
            IL.AddCmd0(IL.opSAVE16)
461
        ELSIF ~PROG.isOpenArray(VarType) & ~PROG.isOpenArray(e.type) & PROG.isTypeEq(VarType, e.type) THEN
475
        ELSIF ~PROG.isOpenArray(VarType) & ~PROG.isOpenArray(e.type) & PROG.isTypeEq(VarType, e.type) THEN
462
            IF e.obj = ePROC THEN
476
            IF e.obj = ePROC THEN
463
                CODE.AssignProc(e.ident.proc.label)
477
                IL.AssignProc(e.ident.proc.label)
464
            ELSIF e.obj = eIMP THEN
478
            ELSIF e.obj = eIMP THEN
465
                CODE.AssignImpProc(e.ident.import)
479
                IL.AssignImpProc(e.ident.import)
466
            ELSE
480
            ELSE
467
                IF VarType.typ = PROG.tPROCEDURE THEN
481
                IF VarType.typ = PROG.tPROCEDURE THEN
468
                    CODE.AddCmd0(CODE.opSAVE)
482
                    IL.AddCmd0(IL.opSAVE)
469
                ELSE
483
                ELSE
470
                    CODE.AddCmd(CODE.opCOPY, VarType.size)
484
                    IL.AddCmd(IL.opCOPY, VarType.size)
471
                END
485
                END
472
            END
486
            END
473
        ELSIF isNil(e) & (VarType.typ IN {PROG.tPOINTER, PROG.tPROCEDURE}) THEN
487
        ELSIF isNil(e) & (VarType.typ IN {PROG.tPOINTER, PROG.tPROCEDURE}) THEN
474
            CODE.AddCmd(CODE.opSAVEC, 0)
488
            IL.AddCmd(IL.opSAVEC, 0)
475
        ELSIF isString(e) & ((VarType.typ = PROG.tARRAY) & (VarType.base.typ = PROG.tCHAR) & (VarType.length > strlen(e))) THEN
489
        ELSIF isString(e) & ((VarType.typ = PROG.tARRAY) & (VarType.base = tCHAR) & (VarType.length > strlen(e))) THEN
476
            CODE.saves(String(e), strlen(e) + 1)
490
            IL.saves(String(e), strlen(e) + 1)
477
        ELSIF isStringW(e) & ((VarType.typ = PROG.tARRAY) & (VarType.base.typ = PROG.tWCHAR) & (VarType.length > utf8strlen(e))) THEN
491
        ELSIF isStringW(e) & ((VarType.typ = PROG.tARRAY) & (VarType.base = tWCHAR) & (VarType.length > utf8strlen(e))) THEN
478
            CODE.saves(StringW(e), (utf8strlen(e) + 1) * 2)
492
            IL.saves(StringW(e), (utf8strlen(e) + 1) * 2)
479
        ELSE
493
        ELSE
480
            res := FALSE
494
            res := FALSE
481
        END
495
        END
Line 486... Line 500...
486
END assign;
500
END assign;
Line 487... Line 501...
487
 
501
 
488
 
502
 
489
PROCEDURE LoadConst (e: PARS.EXPR);
503
PROCEDURE LoadConst (e: PARS.EXPR);
490
BEGIN
504
BEGIN
Line 491... Line 505...
491
    CODE.AddCmd(CODE.opCONST, ARITH.Int(e.value))
505
    IL.Const(ARITH.Int(e.value))
-
 
506
END LoadConst;
-
 
507
 
Line 492... Line 508...
492
END LoadConst;
508
 
493
 
509
PROCEDURE paramcomp (parser: PARS.PARSER; pos: PARS.POSITION; e: PARS.EXPR; p: PROG.PARAM);
494
 
510
VAR
Line 528... Line 544...
528
    VAR
544
    VAR
529
        n: INTEGER;
545
        n: INTEGER;
530
        d1, d2: INTEGER;
546
        d1, d2: INTEGER;
531
    BEGIN
547
    BEGIN
532
        IF t.length # 0 THEN
548
        IF t.length # 0 THEN
533
            CODE.AddCmd(CODE.opPARAM, 1);
549
            IL.Param1;
534
            n := PROG.Dim(t2) - 1;
550
            n := PROG.Dim(t2) - 1;
535
            WHILE n >= 0 DO
551
            WHILE n >= 0 DO
536
                CODE.AddCmd(CODE.opCONST, ArrLen(t, n));
552
                IL.Const(ArrLen(t, n));
537
                CODE.AddCmd(CODE.opPARAM, 1);
553
                IL.Param1;
538
                DEC(n)
554
                DEC(n)
539
            END
555
            END
540
        ELSE
556
        ELSE
541
            d1 := PROG.Dim(t);
557
            d1 := PROG.Dim(t);
542
            d2 := PROG.Dim(t2);
558
            d2 := PROG.Dim(t2);
543
            IF d1 # d2 THEN
559
            IF d1 # d2 THEN
544
                n := d2 - d1;
560
                n := d2 - d1;
545
                WHILE d2 > d1 DO
561
                WHILE d2 > d1 DO
546
                    CODE.AddCmd(CODE.opCONST, ArrLen(t, d2 - 1));
562
                    IL.Const(ArrLen(t, d2 - 1));
547
                    DEC(d2)
563
                    DEC(d2)
548
                END;
564
                END;
549
                d2 := PROG.Dim(t2);
565
                d2 := PROG.Dim(t2);
550
                WHILE n > 0 DO
566
                WHILE n > 0 DO
551
                    CODE.AddCmd(CODE.opROT, d2);
567
                    IL.AddCmd(IL.opROT, d2);
552
                    DEC(n)
568
                    DEC(n)
553
                END
569
                END
554
            END;
570
            END;
555
            CODE.AddCmd(CODE.opPARAM, PROG.Dim(t2) + 1)
571
            IL.AddCmd(IL.opPARAM, PROG.Dim(t2) + 1)
556
        END
572
        END
557
    END OpenArray;
573
    END OpenArray;
Line 558... Line 574...
558
 
574
 
559
 
575
 
Line 560... Line 576...
560
BEGIN
576
BEGIN
561
    IF p.vPar THEN
577
    IF p.vPar THEN
562
 
578
 
563
        PARS.check(isVar(e), parser, pos, 93);
579
        PARS.check(isVar(e), pos, 93);
564
        IF p.type.typ = PROG.tRECORD THEN
580
        IF p.type.typ = PROG.tRECORD THEN
565
            PARS.check(PROG.isBaseOf(p.type, e.type), parser, pos, 66);
581
            PARS.check(PROG.isBaseOf(p.type, e.type), pos, 66);
566
            IF e.obj = eVREC THEN
582
            IF e.obj = eVREC THEN
567
                IF e.ident # NIL THEN
583
                IF e.ident # NIL THEN
568
                    CODE.AddCmd(CODE.opVADR, e.ident.offset - 1)
584
                    IL.AddCmd(IL.opVADR, e.ident.offset - 1)
569
                ELSE
585
                ELSE
570
                    CODE.AddCmd0(CODE.opPUSHT)
586
                    IL.AddCmd0(IL.opPUSHT)
571
                END
587
                END
572
            ELSE
588
            ELSE
573
                CODE.AddCmd(CODE.opCONST, e.type.num)
589
                IL.Const(e.type.num)
574
            END;
590
            END;
575
            CODE.AddCmd(CODE.opPARAM, 2)
591
            IL.AddCmd(IL.opPARAM, 2)
576
        ELSIF PROG.isOpenArray(p.type) THEN
592
        ELSIF PROG.isOpenArray(p.type) THEN
577
            PARS.check(arrcomp(e, p), parser, pos, 66);
593
            PARS.check(arrcomp(e, p), pos, 66);
578
            OpenArray(e.type, p.type)
594
            OpenArray(e.type, p.type)
579
        ELSE
595
        ELSE
580
            PARS.check(PROG.isTypeEq(e.type, p.type), parser, pos, 66);
596
            PARS.check(PROG.isTypeEq(e.type, p.type), pos, 66);
Line 581... Line 597...
581
            CODE.AddCmd(CODE.opPARAM, 1)
597
            IL.Param1
582
        END;
598
        END;
583
        PARS.check(~e.readOnly, parser, pos, 94)
599
        PARS.check(~e.readOnly, pos, 94)
584
 
600
 
585
    ELSE
601
    ELSE
586
        PARS.check(isExpr(e) OR isProc(e), parser, pos, 66);
602
        PARS.check(isExpr(e) OR isProc(e), pos, 66);
587
        IF PROG.isOpenArray(p.type) THEN
603
        IF PROG.isOpenArray(p.type) THEN
588
            IF e.type.typ = PROG.tARRAY THEN
604
            IF e.type.typ = PROG.tARRAY THEN
589
                PARS.check(arrcomp(e, p), parser, pos, 66);
605
                PARS.check(arrcomp(e, p), pos, 66);
590
                OpenArray(e.type, p.type)
606
                OpenArray(e.type, p.type)
591
            ELSIF isString(e) & (p.type.typ = PROG.tARRAY) & (p.type.base.typ = PROG.tCHAR) THEN
607
            ELSIF isString(e) & (p.type.typ = PROG.tARRAY) & (p.type.base = tCHAR) THEN
592
                CODE.AddCmd(CODE.opSADR, String(e));
608
                IL.StrAdr(String(e));
593
                CODE.AddCmd(CODE.opPARAM, 1);
609
                IL.Param1;
594
                CODE.AddCmd(CODE.opCONST, strlen(e) + 1);
610
                IL.Const(strlen(e) + 1);
595
                CODE.AddCmd(CODE.opPARAM, 1)
611
                IL.Param1
596
            ELSIF isStringW(e) & (p.type.typ = PROG.tARRAY) & (p.type.base.typ = PROG.tWCHAR) THEN
612
            ELSIF isStringW(e) & (p.type.typ = PROG.tARRAY) & (p.type.base = tWCHAR) THEN
597
                CODE.AddCmd(CODE.opSADR, StringW(e));
613
                IL.StrAdr(StringW(e));
598
                CODE.AddCmd(CODE.opPARAM, 1);
614
                IL.Param1;
599
                CODE.AddCmd(CODE.opCONST, utf8strlen(e) + 1);
615
                IL.Const(utf8strlen(e) + 1);
600
                CODE.AddCmd(CODE.opPARAM, 1)
616
                IL.Param1
601
            ELSE
617
            ELSE
602
                PARS.error(parser, pos, 66)
618
                PARS.error(pos, 66)
603
            END
619
            END
604
        ELSE
620
        ELSE
605
            PARS.check(~PROG.isOpenArray(e.type), parser, pos, 66);
621
            PARS.check(~PROG.isOpenArray(e.type), pos, 66);
606
            PARS.check(assigncomp(e, p.type), parser, pos, 66);
622
            PARS.check(assigncomp(e, p.type), pos, 66);
607
            IF e.obj = eCONST THEN
623
            IF e.obj = eCONST THEN
608
                IF e.type.typ = PROG.tREAL THEN
624
                IF e.type = tREAL THEN
609
                    CODE.Float(ARITH.Float(e.value));
625
                    IL.Float(ARITH.Float(e.value));
610
                    CODE.pushf
626
                    IL.pushf
611
                ELSIF e.type.typ = PROG.tNIL THEN
627
                ELSIF e.type.typ = PROG.tNIL THEN
612
                    CODE.AddCmd(CODE.opCONST, 0);
628
                    IL.Const(0);
613
                    CODE.AddCmd(CODE.opPARAM, 1)
629
                    IL.Param1
614
                ELSIF isStringW1(e) & (p.type.typ = PROG.tWCHAR) THEN
630
                ELSIF isStringW1(e) & (p.type = tWCHAR) THEN
615
                    CODE.AddCmd(CODE.opCONST, StrToWChar(e.value.string(SCAN.IDENT).s));
631
                    IL.Const(StrToWChar(e.value.string(SCAN.IDENT).s));
616
                    CODE.AddCmd(CODE.opPARAM, 1)
632
                    IL.Param1
617
                ELSIF (e.type.typ = PROG.tSTRING) OR
633
                ELSIF (e.type.typ = PROG.tSTRING) OR
-
 
634
                      (e.type.typ IN {PROG.tCHAR, PROG.tWCHAR}) & (p.type.typ = PROG.tARRAY) & (p.type.base.typ IN {PROG.tCHAR, PROG.tWCHAR}) THEN
-
 
635
                    IF p.type.base = tCHAR THEN
-
 
636
                        stroffs := String(e);
618
                      (e.type.typ IN {PROG.tCHAR, PROG.tWCHAR}) & (p.type.typ = PROG.tARRAY) & (p.type.base.typ IN {PROG.tCHAR, PROG.tWCHAR}) THEN
637
                        IL.StrAdr(stroffs);
619
                    CODE.SetMinDataSize(p.type.size);
638
                        IF (CPU = cpuMSP430) & (p.type.size - strlen(e) - 1 > MSP430.IntVectorSize) THEN
-
 
639
                            ERRORS.WarningMsg(pos.line, pos.col, 0)
620
                    IF p.type.base.typ = PROG.tCHAR THEN
640
                        END
-
 
641
                    ELSE (* WCHAR *)
621
                        CODE.AddCmd(CODE.opSADR, String(e))
642
                        stroffs := StringW(e);
622
                    ELSE (* WCHAR *)
643
                        IL.StrAdr(stroffs)
623
                        CODE.AddCmd(CODE.opSADR, StringW(e))
644
                    END;
624
                    END;
645
                    IL.codes.dmin := stroffs + p.type.size;
625
                    CODE.AddCmd(CODE.opPARAM, 1)
646
                    IL.Param1
626
                ELSE
647
                ELSE
627
                    LoadConst(e);
648
                    LoadConst(e);
628
                    CODE.AddCmd(CODE.opPARAM, 1)
649
                    IL.Param1
629
                END
650
                END
630
            ELSIF e.obj = ePROC THEN
651
            ELSIF e.obj = ePROC THEN
631
                PARS.check(e.ident.global, parser, pos, 85);
652
                PARS.check(e.ident.global, pos, 85);
632
                CODE.PushProc(e.ident.proc.label);
653
                IL.PushProc(e.ident.proc.label);
633
                CODE.AddCmd(CODE.opPARAM, 1)
654
                IL.Param1
634
            ELSIF e.obj = eIMP THEN
655
            ELSIF e.obj = eIMP THEN
635
                CODE.PushImpProc(e.ident.import);
656
                IL.PushImpProc(e.ident.import);
636
                CODE.AddCmd(CODE.opPARAM, 1)
657
                IL.Param1
637
            ELSIF isExpr(e) & (e.type.typ = PROG.tREAL) THEN
658
            ELSIF isExpr(e) & (e.type = tREAL) THEN
638
                CODE.pushf
659
                IL.pushf
639
            ELSE
660
            ELSE
640
                IF (p.type.typ = PROG.tBYTE) & (e.type.typ = PROG.tINTEGER) & (chkBYTE IN checking) THEN
661
                IF (p.type = tBYTE) & (e.type = tINTEGER) & (chkBYTE IN Options.checking) THEN
641
                    CheckRange(256, pos.line, errBYTE)
662
                    CheckRange(256, pos.line, errBYTE)
Line 642... Line 663...
642
                END;
663
                END;
643
                CODE.AddCmd(CODE.opPARAM, 1)
664
                IL.Param1
Line -... Line 665...
-
 
665
            END
-
 
666
        END
-
 
667
 
-
 
668
    END
-
 
669
END paramcomp;
-
 
670
 
644
            END
671
 
645
        END
672
PROCEDURE PExpression (parser: PARS.PARSER; VAR e: PARS.EXPR);
646
 
673
BEGIN
647
    END
674
    parser.expression(parser, e)
648
END paramcomp;
675
END PExpression;
649
 
676
 
650
 
677
 
651
PROCEDURE stProc (parser: PARS.PARSER; VAR e: PARS.EXPR);
678
PROCEDURE stProc (parser: PARS.PARSER; VAR e: PARS.EXPR);
652
VAR
679
VAR
653
    e2:    PARS.EXPR;
680
    e2:    PARS.EXPR;
654
    pos:   SCAN.POSITION;
681
    pos:   PARS.POSITION;
655
    proc:  INTEGER;
682
    proc:  INTEGER;
-
 
683
    label: INTEGER;
Line 656... Line 684...
656
    label: INTEGER;
684
    n, i:  INTEGER;
657
    n, i:  INTEGER;
685
    code:  ARITH.VALUE;
658
    code:  ARITH.VALUE;
686
    e1:    PARS.EXPR;
659
    e1:    PARS.EXPR;
687
    wchar: BOOLEAN;
660
    wchar: BOOLEAN;
688
    cmd1,
661
    cmd1,
689
    cmd2:  IL.COMMAND;
662
    cmd2:  CODE.COMMAND;
690
    comma: BOOLEAN;
663
 
691
 
664
 
692
 
Line 665... Line 693...
665
    PROCEDURE varparam (parser: PARS.PARSER; pos: SCAN.POSITION; isfunc: isXXX; readOnly: BOOLEAN; VAR e: PARS.EXPR);
693
    PROCEDURE varparam (parser: PARS.PARSER; pos: PARS.POSITION; isfunc: isXXX; readOnly: BOOLEAN; VAR e: PARS.EXPR);
Line 689... Line 717...
689
    END shift_minmax;
717
    END shift_minmax;
Line 690... Line 718...
690
 
718
 
691
 
719
 
-
 
720
BEGIN
-
 
721
    ASSERT(e.obj IN {eSTPROC, eSTFUNC, eSYSPROC, eSYSFUNC});
-
 
722
    proc := e.stproc;
-
 
723
 
-
 
724
(*    IF (proc # PROG.sysNOP) & (proc # PROG.sysEINT) & (proc # PROG.sysDINT) THEN *)
-
 
725
        PARS.checklex(parser, SCAN.lxLROUND);
Line 692... Line 726...
692
BEGIN
726
        PARS.Next(parser);
693
    ASSERT(e.obj IN {eSTPROC, eSTFUNC, eSYSPROC, eSYSFUNC});
-
 
Line 694... Line 727...
694
 
727
(*    END; *)
695
    getpos(parser, pos);
728
 
696
    proc := e.stproc;
729
    getpos(parser, pos);
697
 
730
 
698
    IF e.obj IN {eSYSPROC, eSYSFUNC} THEN
731
    IF e.obj IN {eSYSPROC, eSYSFUNC} THEN
Line 699... Line 732...
699
        IF parser.unit.scopeLvl > 0 THEN
732
        IF parser.unit.scopeLvl > 0 THEN
Line 700... Line 733...
700
            parser.unit.scopes[parser.unit.scopeLvl].enter(CODE.COMMAND).allocReg := FALSE
733
            parser.unit.scopes[parser.unit.scopeLvl].enter(IL.COMMAND).allocReg := FALSE
701
        END
734
        END
702
    END;
735
    END;
703
 
736
 
704
    IF e.obj IN {eSTPROC, eSYSPROC} THEN
737
    IF e.obj IN {eSTPROC, eSYSPROC} THEN
705
 
738
 
706
        CASE proc OF
739
        CASE proc OF
707
        |PROG.stASSERT:
740
        |PROG.stASSERT:
708
            parser.expression(parser, e);
741
            PExpression(parser, e);
709
            PARS.check(isBoolean(e), parser, pos, 66);
742
            PARS.check(isBoolean(e), pos, 66);
710
            IF e.obj = eCONST THEN
743
            IF e.obj = eCONST THEN
711
                IF ~ARITH.getBool(e.value) THEN
744
                IF ~ARITH.getBool(e.value) THEN
712
                    CODE.OnError(pos.line, errASSERT)
745
                    IL.OnError(pos.line, errASSERT)
713
                END
746
                END
Line 714... Line 747...
714
            ELSE
747
            ELSE
715
                label := CODE.NewLabel();
748
                label := IL.NewLabel();
716
                CODE.AddJmpCmd(CODE.opJE, label);
749
                IL.AddJmpCmd(IL.opJE, label);
717
                CODE.OnError(pos.line, errASSERT);
750
                IL.OnError(pos.line, errASSERT);
718
                CODE.SetLabel(label)
751
                IL.SetLabel(label)
719
            END
752
            END
720
 
753
 
721
        |PROG.stINC, PROG.stDEC:
754
        |PROG.stINC, PROG.stDEC:
722
            CODE.pushBegEnd(begcall, endcall);
755
            IL.pushBegEnd(begcall, endcall);
723
            varparam(parser, pos, isInt, TRUE, e);
756
            varparam(parser, pos, isInt, TRUE, e);
724
            IF e.type.typ = PROG.tINTEGER THEN
757
            IF e.type = tINTEGER THEN
725
                IF parser.sym = SCAN.lxCOMMA THEN
758
                IF parser.sym = SCAN.lxCOMMA THEN
726
                    NextPos(parser, pos);
759
                    NextPos(parser, pos);
727
                    CODE.setlast(begcall);
760
                    IL.setlast(begcall);
728
                    parser.expression(parser, e2);
761
                    PExpression(parser, e2);
729
                    CODE.setlast(endcall.prev(CODE.COMMAND));
762
                    IL.setlast(endcall.prev(IL.COMMAND));
730
                    PARS.check(isInt(e2), parser, pos, 66);
763
                    PARS.check(isInt(e2), pos, 66);
731
                    IF e2.obj = eCONST THEN
764
                    IF e2.obj = eCONST THEN
732
                        CODE.AddCmd(CODE.opINCC + ORD(proc = PROG.stDEC), ARITH.Int(e2.value))
765
                        IL.AddCmd(IL.opINCC, ARITH.Int(e2.value) * (ORD(proc = PROG.stINC) * 2 - 1))
733
                    ELSE
766
                    ELSE
734
                        CODE.AddCmd0(CODE.opINC + ORD(proc = PROG.stDEC))
767
                        IL.AddCmd0(IL.opINC + ORD(proc = PROG.stDEC))
735
                    END
768
                    END
736
                ELSE
769
                ELSE
737
                    CODE.AddCmd0(CODE.opINC1 + ORD(proc = PROG.stDEC))
770
                    IL.AddCmd(IL.opINCC, ORD(proc = PROG.stINC) * 2 - 1)
738
                END
771
                END
739
            ELSE  (* e.type.typ = PROG.tBYTE *)
772
            ELSE  (* e.type = tBYTE *)
740
                IF parser.sym = SCAN.lxCOMMA THEN
773
                IF parser.sym = SCAN.lxCOMMA THEN
741
                    NextPos(parser, pos);
774
                    NextPos(parser, pos);
742
                    CODE.setlast(begcall);
775
                    IL.setlast(begcall);
743
                    parser.expression(parser, e2);
776
                    PExpression(parser, e2);
744
                    CODE.setlast(endcall.prev(CODE.COMMAND));
777
                    IL.setlast(endcall.prev(IL.COMMAND));
745
                    PARS.check(isInt(e2), parser, pos, 66);
778
                    PARS.check(isInt(e2), pos, 66);
746
                    IF e2.obj = eCONST THEN
779
                    IF e2.obj = eCONST THEN
747
                        CODE.AddCmd(CODE.opINCCB + ORD(proc = PROG.stDEC), ARITH.Int(e2.value))
780
                        IL.AddCmd(IL.opINCCB + ORD(proc = PROG.stDEC), ARITH.Int(e2.value))
748
                    ELSE
781
                    ELSE
Line 749... Line 782...
749
                        CODE.AddCmd0(CODE.opINCB + ORD(proc = PROG.stDEC))
782
                        IL.AddCmd0(IL.opINCB + ORD(proc = PROG.stDEC))
750
                    END
783
                    END
751
                ELSE
784
                ELSE
752
                    CODE.AddCmd0(CODE.opINC1B + ORD(proc = PROG.stDEC))
785
                    IL.AddCmd(IL.opINCCB + ORD(proc = PROG.stDEC), 1)
753
                END
786
                END
754
            END;
787
            END;
755
            CODE.popBegEnd(begcall, endcall)
788
            IL.popBegEnd(begcall, endcall)
756
 
789
 
757
        |PROG.stINCL, PROG.stEXCL:
790
        |PROG.stINCL, PROG.stEXCL:
758
            CODE.pushBegEnd(begcall, endcall);
791
            IL.pushBegEnd(begcall, endcall);
759
            varparam(parser, pos, isSet, TRUE, e);
792
            varparam(parser, pos, isSet, TRUE, e);
760
            PARS.checklex(parser, SCAN.lxCOMMA);
793
            PARS.checklex(parser, SCAN.lxCOMMA);
761
            NextPos(parser, pos);
794
            NextPos(parser, pos);
762
            CODE.setlast(begcall);
795
            IL.setlast(begcall);
763
            parser.expression(parser, e2);
796
            PExpression(parser, e2);
764
            CODE.setlast(endcall.prev(CODE.COMMAND));
797
            IL.setlast(endcall.prev(IL.COMMAND));
Line 765... Line 798...
765
            PARS.check(isInt(e2), parser, pos, 66);
798
            PARS.check(isInt(e2), pos, 66);
766
            IF e2.obj = eCONST THEN
799
            IF e2.obj = eCONST THEN
-
 
800
                PARS.check(ARITH.range(e2.value, 0, UTILS.target.maxSet), pos, 56);
-
 
801
                IL.AddCmd(IL.opINCLC + ORD(proc = PROG.stEXCL), ARITH.Int(e2.value))
-
 
802
            ELSE
767
                PARS.check(ARITH.range(e2.value, 0, MACHINE.target.maxSet), parser, pos, 56);
803
                IL.AddCmd0(IL.opINCL + ORD(proc = PROG.stEXCL))
Line 768... Line 804...
768
                CODE.AddCmd(CODE.opINCLC + ORD(proc = PROG.stEXCL), ARITH.Int(e2.value))
804
            END;
769
            ELSE
805
            IL.popBegEnd(begcall, endcall)
770
                CODE.AddCmd0(CODE.opINCL + ORD(proc = PROG.stEXCL))
806
 
Line 771... Line 807...
771
            END;
807
        |PROG.stNEW:
772
            CODE.popBegEnd(begcall, endcall)
808
            varparam(parser, pos, isPtr, TRUE, e);
773
 
809
            IF CPU = cpuMSP430 THEN
774
        |PROG.stNEW:
810
                PARS.check(e.type.base.size + 16 < Options.ram, pos, 63)
775
            varparam(parser, pos, isPtr, TRUE, e);
811
            END;
776
            CODE.New(e.type.base.size, e.type.base.num)
812
            IL.New(e.type.base.size, e.type.base.num)
777
 
813
 
778
        |PROG.stDISPOSE:
814
        |PROG.stDISPOSE:
779
            varparam(parser, pos, isPtr, TRUE, e);
815
            varparam(parser, pos, isPtr, TRUE, e);
780
            CODE.AddCmd0(CODE.opDISP)
816
            IL.AddCmd0(IL.opDISP)
781
 
817
 
Line 782... Line 818...
782
        |PROG.stPACK:
818
        |PROG.stPACK:
783
            varparam(parser, pos, isReal, TRUE, e);
819
            varparam(parser, pos, isReal, TRUE, e);
784
            PARS.checklex(parser, SCAN.lxCOMMA);
820
            PARS.checklex(parser, SCAN.lxCOMMA);
785
            NextPos(parser, pos);
821
            NextPos(parser, pos);
786
            parser.expression(parser, e2);
822
            PExpression(parser, e2);
787
            PARS.check(isInt(e2), parser, pos, 66);
823
            PARS.check(isInt(e2), pos, 66);
Line 788... Line 824...
788
            IF e2.obj = eCONST THEN
824
            IF e2.obj = eCONST THEN
-
 
825
                IL.AddCmd(IL.opPACKC, ARITH.Int(e2.value))
789
                CODE.AddCmd(CODE.opPACKC, ARITH.Int(e2.value))
826
            ELSE
790
            ELSE
827
                IL.AddCmd0(IL.opPACK)
791
                CODE.AddCmd0(CODE.opPACK)
828
            END
792
            END
829
 
793
 
830
        |PROG.stUNPK:
794
        |PROG.stUNPK:
831
            varparam(parser, pos, isReal, TRUE, e);
795
            varparam(parser, pos, isReal, TRUE, e);
832
            PARS.checklex(parser, SCAN.lxCOMMA);
796
            PARS.checklex(parser, SCAN.lxCOMMA);
833
            NextPos(parser, pos);
Line 797... Line 834...
797
            NextPos(parser, pos);
834
            varparam(parser, pos, isInteger, TRUE, e2);
798
            varparam(parser, pos, isInteger, TRUE, e2);
835
            IL.AddCmd0(IL.opUNPK)
799
            CODE.AddCmd0(CODE.opUNPK)
836
 
Line 800... Line 837...
800
 
837
        |PROG.stCOPY:
801
        |PROG.stCOPY:
838
            IL.pushBegEnd(begcall, endcall);
-
 
839
            PExpression(parser, e);
Line 802... Line 840...
802
            parser.expression(parser, e);
840
            IF isString(e) OR isCharArray(e) THEN
803
            IF isString(e) OR isCharArray(e) THEN
841
                wchar := FALSE
804
                wchar := FALSE
842
            ELSIF isStringW(e) OR isCharArrayW(e) THEN
805
            ELSIF isStringW(e) OR isCharArrayW(e) THEN
843
                wchar := TRUE
806
                wchar := TRUE
844
            ELSE
807
            ELSE
845
                PARS.error(pos, 66)
808
                PARS.check(FALSE, parser, pos, 66)
846
            END;
809
            END;
847
 
Line 810... Line 848...
810
 
848
            IF isCharArrayX(e) & ~PROG.isOpenArray(e.type) THEN
811
            IF isCharArrayX(e) & ~PROG.isOpenArray(e.type) THEN
849
                IL.Const(e.type.length)
Line 812... Line 850...
812
                CODE.AddCmd(CODE.opCONST, e.type.length)
850
            END;
813
            END;
851
 
814
 
852
            PARS.checklex(parser, SCAN.lxCOMMA);
Line -... Line 853...
-
 
853
            NextPos(parser, pos);
-
 
854
            IL.setlast(begcall);
815
            PARS.checklex(parser, SCAN.lxCOMMA);
855
 
816
            NextPos(parser, pos);
856
            IF wchar THEN
817
 
857
                varparam(parser, pos, isCharArrayW, TRUE, e1)
818
            IF wchar THEN
858
            ELSE
819
                varparam(parser, pos, isCharArrayW, TRUE, e1)
859
                IF e.obj = eCONST THEN
820
            ELSE
860
                    varparam(parser, pos, isCharArrayX, TRUE, e1)
821
                IF e.obj = eCONST THEN
861
                ELSE
822
                    varparam(parser, pos, isCharArrayX, TRUE, e1)
-
 
823
                ELSE
-
 
824
                    varparam(parser, pos, isCharArray, TRUE, e1)
-
 
825
                END;
-
 
826
 
862
                    varparam(parser, pos, isCharArray, TRUE, e1)
-
 
863
                END;
-
 
864
 
-
 
865
                wchar := e1.type.base = tWCHAR
Line 827... Line 866...
827
                wchar := e1.type.base.typ = PROG.tWCHAR
866
            END;
828
            END;
867
 
829
 
868
            IF ~PROG.isOpenArray(e1.type) THEN
830
            IF ~PROG.isOpenArray(e1.type) THEN
-
 
831
                CODE.AddCmd(CODE.opCONST, e1.type.length)
-
 
832
            END;
-
 
833
 
869
                IL.Const(e1.type.length)
834
            IF e.obj = eCONST THEN
870
            END;
835
                IF wchar THEN
871
 
836
                    CODE.AddCmd(CODE.opSADR, StringW(e));
872
            IL.setlast(endcall.prev(IL.COMMAND));
837
                    CODE.AddCmd(CODE.opCONST, utf8strlen(e) + 1)
873
 
-
 
874
            IF e.obj = eCONST THEN
-
 
875
                IF wchar THEN
-
 
876
                    IL.StrAdr(StringW(e));
838
                ELSE
877
                    IL.Const(utf8strlen(e) + 1)
-
 
878
                ELSE
Line 839... Line 879...
839
                    CODE.AddCmd(CODE.opSADR, String(e));
879
                    IL.StrAdr(String(e));
840
                    CODE.AddCmd(CODE.opCONST, strlen(e) + 1)
880
                    IL.Const(strlen(e) + 1)
841
                END;
881
                END
842
                CODE.AddCmd(CODE.opCOPYS2, e1.type.base.size)
882
            END;
843
            ELSE
883
            IL.AddCmd(IL.opCOPYS, e1.type.base.size);
844
                CODE.AddCmd(CODE.opCOPYS, e1.type.base.size)
884
            IL.popBegEnd(begcall, endcall)
845
            END
885
 
846
 
886
        |PROG.sysGET:
847
        |PROG.sysGET:
887
            PExpression(parser, e);
848
            parser.expression(parser, e);
888
            PARS.check(isInt(e), pos, 66);
849
            PARS.check(isInt(e), parser, pos, 66);
889
            PARS.checklex(parser, SCAN.lxCOMMA);
850
            IF e.obj = eCONST THEN
890
            NextPos(parser, pos);
Line 851... Line 891...
851
                LoadConst(e)
891
            parser.designator(parser, e2);
852
            END;
892
            PARS.check(isVar(e2), pos, 93);
853
            PARS.checklex(parser, SCAN.lxCOMMA);
893
            PARS.check(e2.type.typ IN PROG.BASICTYPES + {PROG.tPOINTER, PROG.tPROCEDURE}, pos, 66);
854
            NextPos(parser, pos);
894
            IF e.obj = eCONST THEN
855
            parser.designator(parser, e2);
895
                IL.AddCmd2(IL.opGETC, ARITH.Int(e.value), e2.type.size)
856
            PARS.check(isVar(e2), parser, pos, 93);
896
            ELSE
857
            PARS.check((e2.type.typ IN PROG.BASICTYPES) OR (e2.type.typ = PROG.tPOINTER) OR (e2.type.typ = PROG.tPROCEDURE), parser, pos, 66);
897
                IL.AddCmd(IL.opGET, e2.type.size)
858
            CODE.SysGet(e2.type.size)
898
            END
859
 
899
 
860
        |PROG.sysPUT, PROG.sysPUT8, PROG.sysPUT16, PROG.sysPUT32:
900
        |PROG.sysPUT, PROG.sysPUT8, PROG.sysPUT16, PROG.sysPUT32:
861
            CODE.pushBegEnd(begcall, endcall);
901
            IL.pushBegEnd(begcall, endcall);
862
            parser.expression(parser, e);
902
            PExpression(parser, e);
863
            PARS.check(isInt(e), parser, pos, 66);
903
            PARS.check(isInt(e), pos, 66);
864
            IF e.obj = eCONST THEN
904
            IF e.obj = eCONST THEN
865
                LoadConst(e)
905
                LoadConst(e)
866
            END;
906
            END;
867
            PARS.checklex(parser, SCAN.lxCOMMA);
907
            PARS.checklex(parser, SCAN.lxCOMMA);
868
            NextPos(parser, pos);
908
            NextPos(parser, pos);
869
            CODE.setlast(begcall);
909
            IL.setlast(begcall);
870
            parser.expression(parser, e2);
910
            PExpression(parser, e2);
871
            PARS.check(isExpr(e2), parser, pos, 66);
911
            PARS.check(isExpr(e2), pos, 66);
872
 
912
 
Line 873... Line 913...
873
            IF proc = PROG.sysPUT THEN
913
            IF proc = PROG.sysPUT THEN
874
                PARS.check((e2.type.typ IN PROG.BASICTYPES) OR (e2.type.typ = PROG.tPOINTER) OR (e2.type.typ = PROG.tPROCEDURE), parser, pos, 66);
914
                PARS.check(e2.type.typ IN PROG.BASICTYPES + {PROG.tPOINTER, PROG.tPROCEDURE}, pos, 66);
875
                IF e2.obj = eCONST THEN
915
                IF e2.obj = eCONST THEN
876
                    IF e2.type.typ = PROG.tREAL THEN
916
                    IF e2.type = tREAL THEN
877
                        CODE.setlast(endcall.prev(CODE.COMMAND));
917
                        IL.setlast(endcall.prev(IL.COMMAND));
878
                        CODE.Float(ARITH.Float(e2.value));
918
                        IL.Float(ARITH.Float(e2.value));
879
                        CODE.savef
919
                        IL.savef
880
                    ELSE
920
                    ELSE
881
                        LoadConst(e2);
-
 
882
                        CODE.setlast(endcall.prev(CODE.COMMAND));
921
                        LoadConst(e2);
883
                        CODE.SysPut(e2.type.size)
-
 
884
                    END
922
                        IL.setlast(endcall.prev(IL.COMMAND));
885
                ELSE
923
                        IL.SysPut(e2.type.size)
Line 886... Line 924...
886
                    CODE.setlast(endcall.prev(CODE.COMMAND));
924
                    END
887
                    IF e2.type.typ = PROG.tREAL THEN
925
                ELSE
Line 888... Line 926...
888
                        CODE.savef
926
                    IL.setlast(endcall.prev(IL.COMMAND));
889
                    ELSIF e2.type.typ = PROG.tBYTE THEN
927
                    IF e2.type = tREAL THEN
890
                        CODE.SysPut(PARS.program.stTypes.tINTEGER.size)
928
                        IL.savef
891
                    ELSE
929
                    ELSIF e2.type = tBYTE THEN
892
                        CODE.SysPut(e2.type.size)
930
                        IL.SysPut(tINTEGER.size)
893
                    END
931
                    ELSE
894
                END
932
                        IL.SysPut(e2.type.size)
895
 
933
                    END
896
            ELSIF (proc = PROG.sysPUT8) OR (proc = PROG.sysPUT16) OR (proc = PROG.sysPUT32) THEN
934
                END
897
                PARS.check(e2.type.typ IN {PROG.tINTEGER, PROG.tBYTE, PROG.tCHAR, PROG.tWCHAR, PROG.tCARD16, PROG.tCARD32}, parser, pos, 66);
935
 
Line 898... Line 936...
898
                IF e2.obj = eCONST THEN
936
            ELSIF (proc = PROG.sysPUT8) OR (proc = PROG.sysPUT16) OR (proc = PROG.sysPUT32) THEN
899
                    LoadConst(e2)
937
                PARS.check(e2.type.typ IN {PROG.tINTEGER, PROG.tBYTE, PROG.tCHAR, PROG.tSET, PROG.tWCHAR, PROG.tCARD16, PROG.tCARD32}, pos, 66);
900
                END;
938
                IF e2.obj = eCONST THEN
901
                CODE.setlast(endcall.prev(CODE.COMMAND));
939
                    LoadConst(e2)
902
                IF proc = PROG.sysPUT8 THEN
940
                END;
903
                    CODE.SysPut(1)
941
                IL.setlast(endcall.prev(IL.COMMAND));
Line 904... Line 942...
904
                ELSIF proc = PROG.sysPUT16 THEN
942
                CASE proc OF
905
                    CODE.SysPut(2)
943
                |PROG.sysPUT8:  IL.SysPut(1)
906
                ELSIF proc = PROG.sysPUT32 THEN
944
                |PROG.sysPUT16: IL.SysPut(2)
907
                    CODE.SysPut(4)
945
                |PROG.sysPUT32: IL.SysPut(4)
908
                END
946
                END
909
 
947
 
910
            END;
948
            END;
911
            CODE.popBegEnd(begcall, endcall)
949
            IL.popBegEnd(begcall, endcall)
912
 
950
 
913
        |PROG.sysMOVE:
951
        |PROG.sysMOVE:
914
            FOR i := 1 TO 2 DO
952
            FOR i := 1 TO 2 DO
915
                parser.expression(parser, e);
953
                PExpression(parser, e);
Line 916... Line 954...
916
                PARS.check(isInt(e), parser, pos, 66);
954
                PARS.check(isInt(e), pos, 66);
917
                IF e.obj = eCONST THEN
955
                IF e.obj = eCONST THEN
918
                    LoadConst(e)
956
                    LoadConst(e)
919
                END;
957
                END;
920
                PARS.checklex(parser, SCAN.lxCOMMA);
958
                PARS.checklex(parser, SCAN.lxCOMMA);
921
                NextPos(parser, pos)
959
                NextPos(parser, pos)
Line 922... Line 960...
922
            END;
960
            END;
923
 
961
 
924
            parser.expression(parser, e);
962
            PExpression(parser, e);
925
            PARS.check(isInt(e), parser, pos, 66);
963
            PARS.check(isInt(e), pos, 66);
926
            IF e.obj = eCONST THEN
964
            IF e.obj = eCONST THEN
-
 
965
                LoadConst(e)
927
                LoadConst(e)
966
            END;
-
 
967
            IL.AddCmd0(IL.opMOVE)
-
 
968
 
928
            END;
969
        |PROG.sysCOPY:
-
 
970
            FOR i := 1 TO 2 DO
929
            CODE.AddCmd0(CODE.opMOVE)
971
                parser.designator(parser, e);
930
 
972
                PARS.check(isVar(e), pos, 93);
931
        |PROG.sysCOPY:
973
                n := PROG.Dim(e.type);
-
 
974
                WHILE n > 0 DO
-
 
975
                    IL.drop;
-
 
976
                    DEC(n)
-
 
977
                END;
-
 
978
                PARS.checklex(parser, SCAN.lxCOMMA);
-
 
979
                NextPos(parser, pos)
-
 
980
            END;
-
 
981
 
932
            FOR i := 1 TO 2 DO
982
            PExpression(parser, e);
-
 
983
            PARS.check(isInt(e), pos, 66);
-
 
984
            IF e.obj = eCONST THEN
933
                parser.designator(parser, e);
985
                LoadConst(e)
-
 
986
            END;
934
                PARS.check(isVar(e), parser, pos, 93);
987
            IL.AddCmd0(IL.opMOVE)
-
 
988
 
935
                n := PROG.Dim(e.type);
989
        |PROG.sysCODE:
936
                WHILE n > 0 DO
990
            REPEAT
Line 937... Line 991...
937
                    CODE.drop;
991
                getpos(parser, pos);
938
                    DEC(n)
992
                PARS.ConstExpression(parser, code);
Line 939... Line 993...
939
                END;
993
                PARS.check(code.typ = ARITH.tINTEGER, pos, 43);
Line 940... Line 994...
940
                PARS.checklex(parser, SCAN.lxCOMMA);
994
                IF CPU # cpuMSP430 THEN
941
                NextPos(parser, pos)
995
                    PARS.check(ARITH.range(code, 0, 255), pos, 42)
942
            END;
996
                END;
943
 
997
                IL.AddCmd(IL.opCODE, ARITH.getInt(code));
944
            parser.expression(parser, e);
998
                comma := parser.sym = SCAN.lxCOMMA;
945
            PARS.check(isInt(e), parser, pos, 66);
999
                IF comma THEN
946
            IF e.obj = eCONST THEN
1000
                    PARS.Next(parser)
947
                LoadConst(e)
1001
                ELSE
948
            END;
1002
                    PARS.checklex(parser, SCAN.lxRROUND)
Line 949... Line 1003...
949
            CODE.AddCmd0(CODE.opMOVE)
1003
                END
950
 
1004
            UNTIL (parser.sym = SCAN.lxRROUND) & ~comma
951
        |PROG.sysCODE:
1005
          (*
952
            REPEAT
1006
        |PROG.sysNOP, PROG.sysDINT, PROG.sysEINT:
953
                getpos(parser, pos);
1007
            IF parser.sym = SCAN.lxLROUND THEN
954
                PARS.ConstExpression(parser, code);
1008
                PARS.Next(parser);
955
                PARS.check(code.typ = ARITH.tINTEGER, parser, pos, 43);
1009
                PARS.checklex(parser, SCAN.lxRROUND);
956
                PARS.check(ARITH.range(code, 0, 255), parser, pos, 42);
1010
                PARS.Next(parser)
957
                IF parser.sym = SCAN.lxCOMMA THEN
1011
            END;
958
                    PARS.Next(parser)
1012
            ASSERT(CPU = cpuMSP430);
959
                ELSE
1013
            CASE proc OF
960
                    PARS.checklex(parser, SCAN.lxRROUND)
1014
            |PROG.sysNOP:  IL.AddCmd(IL.opCODE, 4303H)
961
                END;
1015
            |PROG.sysDINT: IL.AddCmd(IL.opCODE, 0C232H); IL.AddCmd(IL.opCODE, 4303H)
962
                CODE.AddCmd(CODE.opCODE, ARITH.getInt(code))
1016
            |PROG.sysEINT: IL.AddCmd(IL.opCODE, 0D232H)
963
            UNTIL parser.sym = SCAN.lxRROUND
1017
            END
964
 
1018
            *)
965
        END;
1019
        END;
966
 
1020
 
967
        e.obj := eEXPR;
1021
        e.obj := eEXPR;
968
        e.type := NIL
1022
        e.type := NIL
Line 969... Line 1023...
969
 
1023
 
970
    ELSIF e.obj IN {eSTFUNC, eSYSFUNC} THEN
1024
    ELSIF e.obj IN {eSTFUNC, eSYSFUNC} THEN
971
 
1025
 
972
        CASE e.stproc OF
1026
        CASE e.stproc OF
973
        |PROG.stABS:
1027
        |PROG.stABS:
974
            parser.expression(parser, e);
1028
            PExpression(parser, e);
975
            PARS.check(isInt(e) OR isReal(e), parser, pos, 66);
1029
            PARS.check(isInt(e) OR isReal(e), pos, 66);
976
            IF e.obj = eCONST THEN
1030
            IF e.obj = eCONST THEN
977
                PARS.check(ARITH.abs(e.value), parser, pos, 39)
1031
                PARS.check(ARITH.abs(e.value), pos, 39)
978
            ELSE
1032
            ELSE
979
                CODE.abs(isReal(e))
1033
                IL.abs(isReal(e))
980
            END
1034
            END
981
 
1035
 
982
        |PROG.stASR, PROG.stLSL, PROG.stROR, PROG.stLSR, PROG.stMIN, PROG.stMAX:
1036
        |PROG.stASR, PROG.stLSL, PROG.stROR, PROG.stLSR, PROG.stMIN, PROG.stMAX:
Line 983... Line 1037...
983
            parser.expression(parser, e);
1037
            PExpression(parser, e);
984
            PARS.check(isInt(e), parser, pos, 66);
1038
            PARS.check(isInt(e), pos, 66);
985
            PARS.checklex(parser, SCAN.lxCOMMA);
1039
            PARS.checklex(parser, SCAN.lxCOMMA);
986
            NextPos(parser, pos);
1040
            NextPos(parser, pos);
987
            parser.expression(parser, e2);
1041
            PExpression(parser, e2);
988
            PARS.check(isInt(e2), parser, pos, 66);
1042
            PARS.check(isInt(e2), pos, 66);
989
            e.type := PARS.program.stTypes.tINTEGER;
1043
            e.type := tINTEGER;
990
            IF (e.obj = eCONST) & (e2.obj = eCONST) THEN
1044
            IF (e.obj = eCONST) & (e2.obj = eCONST) THEN
991
                ASSERT(ARITH.opInt(e.value, e2.value, shift_minmax(proc)))
1045
                ASSERT(ARITH.opInt(e.value, e2.value, shift_minmax(proc)))
992
            ELSE
1046
            ELSE
993
                IF e.obj = eCONST THEN
1047
                IF e.obj = eCONST THEN
994
                    CODE.shift_minmax1(shift_minmax(proc), ARITH.Int(e.value))
1048
                    IL.shift_minmax1(shift_minmax(proc), ARITH.Int(e.value))
995
                ELSIF e2.obj = eCONST THEN
1049
                ELSIF e2.obj = eCONST THEN
996
                    CODE.shift_minmax2(shift_minmax(proc), ARITH.Int(e2.value))
1050
                    IL.shift_minmax2(shift_minmax(proc), ARITH.Int(e2.value))
Line 997... Line 1051...
997
                ELSE
1051
                ELSE
998
                    CODE.shift_minmax(shift_minmax(proc))
1052
                    IL.shift_minmax(shift_minmax(proc))
999
                END;
1053
                END;
1000
                e.obj := eEXPR
1054
                e.obj := eEXPR
1001
            END
1055
            END
1002
 
1056
 
1003
        |PROG.stCHR:
1057
        |PROG.stCHR:
1004
            parser.expression(parser, e);
1058
            PExpression(parser, e);
1005
            PARS.check(isInt(e), parser, pos, 66);
1059
            PARS.check(isInt(e), pos, 66);
Line 1006... Line 1060...
1006
            e.type := PARS.program.stTypes.tCHAR;
1060
            e.type := tCHAR;
1007
            IF e.obj = eCONST THEN
1061
            IF e.obj = eCONST THEN
1008
                ARITH.setChar(e.value, ARITH.getInt(e.value));
1062
                ARITH.setChar(e.value, ARITH.getInt(e.value));
1009
                PARS.check(ARITH.check(e.value), parser, pos, 107)
1063
                PARS.check(ARITH.check(e.value), pos, 107)
1010
            ELSE
1064
            ELSE
1011
                IF chkCHR IN checking THEN
1065
                IF chkCHR IN Options.checking THEN
1012
                    CheckRange(256, pos.line, errCHR)
1066
                    CheckRange(256, pos.line, errCHR)
1013
                ELSE
1067
                ELSE
1014
                    CODE.AddCmd0(CODE.opCHR)
1068
                    IL.AddCmd0(IL.opCHR)
Line 1015... Line 1069...
1015
                END
1069
                END
1016
            END
1070
            END
1017
 
1071
 
1018
        |PROG.stWCHR:
1072
        |PROG.stWCHR:
1019
            parser.expression(parser, e);
1073
            PExpression(parser, e);
1020
            PARS.check(isInt(e), parser, pos, 66);
1074
            PARS.check(isInt(e), pos, 66);
1021
            e.type := PARS.program.stTypes.tWCHAR;
1075
            e.type := tWCHAR;
1022
            IF e.obj = eCONST THEN
1076
            IF e.obj = eCONST THEN
1023
                ARITH.setWChar(e.value, ARITH.getInt(e.value));
1077
                ARITH.setWChar(e.value, ARITH.getInt(e.value));
1024
                PARS.check(ARITH.check(e.value), parser, pos, 101)
1078
                PARS.check(ARITH.check(e.value), pos, 101)
1025
            ELSE
1079
            ELSE
1026
                IF chkWCHR IN checking THEN
1080
                IF chkWCHR IN Options.checking THEN
1027
                    CheckRange(65536, pos.line, errWCHR)
1081
                    CheckRange(65536, pos.line, errWCHR)
Line 1028... Line 1082...
1028
                ELSE
1082
                ELSE
1029
                    CODE.AddCmd0(CODE.opWCHR)
1083
                    IL.AddCmd0(IL.opWCHR)
1030
                END
1084
                END
1031
            END
1085
            END
1032
 
1086
 
1033
        |PROG.stFLOOR:
1087
        |PROG.stFLOOR:
1034
            parser.expression(parser, e);
1088
            PExpression(parser, e);
1035
            PARS.check(isReal(e), parser, pos, 66);
1089
            PARS.check(isReal(e), pos, 66);
1036
            e.type := PARS.program.stTypes.tINTEGER;
1090
            e.type := tINTEGER;
1037
            IF e.obj = eCONST THEN
1091
            IF e.obj = eCONST THEN
1038
                PARS.check(ARITH.floor(e.value), parser, pos, 39)
1092
                PARS.check(ARITH.floor(e.value), pos, 39)
1039
            ELSE
1093
            ELSE
1040
                CODE.floor
1094
                IL.floor
1041
            END
1095
            END
1042
 
1096
 
1043
        |PROG.stFLT:
1097
        |PROG.stFLT:
Line 1044... Line 1098...
1044
            parser.expression(parser, e);
1098
            PExpression(parser, e);
1045
            PARS.check(isInt(e), parser, pos, 66);
1099
            PARS.check(isInt(e), pos, 66);
1046
            e.type := PARS.program.stTypes.tREAL;
1100
            e.type := tREAL;
1047
            IF e.obj = eCONST THEN
1101
            IF e.obj = eCONST THEN
1048
                ARITH.flt(e.value)
1102
                ARITH.flt(e.value)
1049
            ELSE
1103
            ELSE
1050
                PARS.check(CODE.flt(), parser, pos, 41)
1104
                PARS.check(IL.flt(), pos, 41)
1051
            END
1105
            END
1052
 
1106
 
Line 1053... Line 1107...
1053
        |PROG.stLEN:
1107
        |PROG.stLEN:
1054
            cmd1 := CODE.getlast();
1108
            cmd1 := IL.getlast();
1055
            varparam(parser, pos, isArr, FALSE, e);
1109
            varparam(parser, pos, isArr, FALSE, e);
1056
            IF e.type.length > 0 THEN
1110
            IF e.type.length > 0 THEN
1057
                cmd2 := CODE.getlast();
1111
                cmd2 := IL.getlast();
1058
                CODE.delete2(cmd1.next, cmd2);
1112
                IL.delete2(cmd1.next, cmd2);
1059
                CODE.setlast(cmd1);
1113
                IL.setlast(cmd1);
1060
                ASSERT(ARITH.setInt(e.value, e.type.length));
1114
                ASSERT(ARITH.setInt(e.value, e.type.length));
1061
                e.obj := eCONST
1115
                e.obj := eCONST
1062
            ELSE
1116
            ELSE
1063
                CODE.len(PROG.Dim(e.type))
1117
                IL.len(PROG.Dim(e.type))
1064
            END;
1118
            END;
1065
            e.type := PARS.program.stTypes.tINTEGER
1119
            e.type := tINTEGER
1066
 
1120
 
1067
        |PROG.stLENGTH:
1121
        |PROG.stLENGTH:
Line 1068... Line 1122...
1068
            parser.expression(parser, e);
1122
            PExpression(parser, e);
1069
            IF isCharArray(e) THEN
1123
            IF isCharArray(e) THEN
1070
                IF e.type.length > 0 THEN
1124
                IF e.type.length > 0 THEN
1071
                    CODE.AddCmd(CODE.opCONST, e.type.length)
1125
                    IL.Const(e.type.length)
1072
                END;
1126
                END;
1073
                CODE.AddCmd0(CODE.opLENGTH)
1127
                IL.AddCmd0(IL.opLENGTH)
1074
            ELSIF isCharArrayW(e) THEN
1128
            ELSIF isCharArrayW(e) THEN
Line 1075... Line 1129...
1075
                IF e.type.length > 0 THEN
1129
                IF e.type.length > 0 THEN
1076
                    CODE.AddCmd(CODE.opCONST, e.type.length)
1130
                    IL.Const(e.type.length)
1077
                END;
1131
                END;
1078
                CODE.AddCmd0(CODE.opLENGTHW)
1132
                IL.AddCmd0(IL.opLENGTHW)
1079
            ELSE
1133
            ELSE
1080
                PARS.check(FALSE, parser, pos, 66);
1134
                PARS.error(pos, 66);
1081
            END;
1135
            END;
1082
            e.type := PARS.program.stTypes.tINTEGER
1136
            e.type := tINTEGER
1083
 
1137
 
1084
        |PROG.stODD:
1138
        |PROG.stODD:
1085
            parser.expression(parser, e);
1139
            PExpression(parser, e);
1086
            PARS.check(isInt(e), parser, pos, 66);
1140
            PARS.check(isInt(e), pos, 66);
1087
            e.type := PARS.program.stTypes.tBOOLEAN;
1141
            e.type := tBOOLEAN;
1088
            IF e.obj = eCONST THEN
1142
            IF e.obj = eCONST THEN
1089
                ARITH.odd(e.value)
1143
                ARITH.odd(e.value)
1090
            ELSE
1144
            ELSE
Line 1091... Line 1145...
1091
                CODE.odd
1145
                IL.odd
1092
            END
1146
            END
1093
 
1147
 
1094
        |PROG.stORD:
1148
        |PROG.stORD:
1095
            parser.expression(parser, e);
1149
            PExpression(parser, e);
1096
            PARS.check(isChar(e) OR isBoolean(e) OR isSet(e) OR isCharW(e) OR isStringW1(e), parser, pos, 66);
1150
            PARS.check(isChar(e) OR isBoolean(e) OR isSet(e) OR isCharW(e) OR isStringW1(e), pos, 66);
Line 1097... Line 1151...
1097
            IF e.obj = eCONST THEN
1151
            IF e.obj = eCONST THEN
1098
                IF isStringW1(e) THEN
1152
                IF isStringW1(e) THEN
1099
                    ASSERT(ARITH.setInt(e.value, StrToWChar(e.value.string(SCAN.IDENT).s)))
1153
                    ASSERT(ARITH.setInt(e.value, StrToWChar(e.value.string(SCAN.IDENT).s)))
1100
                ELSE
1154
                ELSE
1101
                    ARITH.ord(e.value)
1155
                    ARITH.ord(e.value)
1102
                END
1156
                END
Line 1103... Line 1157...
1103
            ELSE
1157
            ELSE
1104
                IF isBoolean(e) THEN
1158
                IF isBoolean(e) THEN
1105
                    CODE.ord
1159
                    IL.ord
1106
                END
1160
                END
1107
            END;
1161
            END;
1108
            e.type := PARS.program.stTypes.tINTEGER
1162
            e.type := tINTEGER
1109
 
1163
 
1110
        |PROG.stBITS:
1164
        |PROG.stBITS:
1111
            parser.expression(parser, e);
1165
            PExpression(parser, e);
1112
            PARS.check(isInt(e), parser, pos, 66);
1166
            PARS.check(isInt(e), pos, 66);
1113
            IF e.obj = eCONST THEN
1167
            IF e.obj = eCONST THEN
1114
                ARITH.bits(e.value)
1168
                ARITH.bits(e.value)
Line 1115... Line 1169...
1115
            END;
1169
            END;
1116
            e.type := PARS.program.stTypes.tSET
1170
            e.type := tSET
1117
 
1171
 
1118
        |PROG.sysADR:
1172
        |PROG.sysADR:
Line 1119... Line 1173...
1119
            parser.designator(parser, e);
1173
            parser.designator(parser, e);
1120
            IF isVar(e) THEN
1174
            IF isVar(e) THEN
1121
               n := PROG.Dim(e.type);
1175
               n := PROG.Dim(e.type);
1122
               WHILE n > 0 DO
1176
               WHILE n > 0 DO
1123
                    CODE.drop;
1177
                    IL.drop;
1124
                    DEC(n)
1178
                    DEC(n)
Line 1125... Line 1179...
1125
               END
1179
               END
Line 1126... Line 1180...
1126
            ELSIF e.obj = ePROC THEN
1180
            ELSIF e.obj = ePROC THEN
Line -... Line 1181...
-
 
1181
                IL.PushProc(e.ident.proc.label)
1127
                CODE.PushProc(e.ident.proc.label)
1182
            ELSIF e.obj = eIMP THEN
1128
            ELSIF e.obj = eIMP THEN
1183
                IL.PushImpProc(e.ident.import)
-
 
1184
            ELSE
Line 1129... Line 1185...
1129
                CODE.PushImpProc(e.ident.import)
1185
                PARS.error(pos, 108)
1130
            ELSE
1186
            END;
1131
                PARS.check(FALSE, parser, pos, 108)
1187
            e.type := tINTEGER
Line 1188... Line 1244...
1188
PROCEDURE ActualParameters (parser: PARS.PARSER; VAR e: PARS.EXPR);
1244
PROCEDURE ActualParameters (parser: PARS.PARSER; VAR e: PARS.EXPR);
1189
VAR
1245
VAR
1190
    proc:  PROG.TYPE_;
1246
    proc:  PROG.TYPE_;
1191
    param: LISTS.ITEM;
1247
    param: LISTS.ITEM;
1192
    e1:    PARS.EXPR;
1248
    e1:    PARS.EXPR;
1193
    pos:   SCAN.POSITION;
1249
    pos:   PARS.POSITION;
Line 1194... Line 1250...
1194
 
1250
 
1195
BEGIN
1251
BEGIN
Line 1196... Line 1252...
1196
    ASSERT(parser.sym = SCAN.lxLROUND);
1252
    ASSERT(parser.sym = SCAN.lxLROUND);
Line 1202... Line 1258...
1202
 
1258
 
1203
        param := proc.params.first;
1259
        param := proc.params.first;
1204
        WHILE param # NIL DO
1260
        WHILE param # NIL DO
Line 1205... Line 1261...
1205
            getpos(parser, pos);
1261
            getpos(parser, pos);
Line 1206... Line 1262...
1206
 
1262
 
1207
            CODE.setlast(begcall);
1263
            IL.setlast(begcall);
1208
 
1264
 
1209
            IF param(PROG.PARAM).vPar THEN
1265
            IF param(PROG.PARAM).vPar THEN
1210
                parser.designator(parser, e1)
1266
                parser.designator(parser, e1)
1211
            ELSE
1267
            ELSE
1212
                parser.expression(parser, e1)
1268
                PExpression(parser, e1)
1213
            END;
1269
            END;
1214
            paramcomp(parser, pos, e1, param(PROG.PARAM));
1270
            paramcomp(parser, pos, e1, param(PROG.PARAM));
Line 1224... Line 1280...
1224
 
1280
 
1225
        e.obj := eEXPR;
1281
        e.obj := eEXPR;
Line 1226... Line 1282...
1226
        e.type := proc.base
1282
        e.type := proc.base
1227
 
-
 
1228
    ELSIF e.obj IN {eSTPROC, eSTFUNC, eSYSPROC, eSYSFUNC} THEN
1283
 
1229
        PARS.Next(parser);
1284
    ELSIF e.obj IN {eSTPROC, eSTFUNC, eSYSPROC, eSYSFUNC} THEN
1230
        stProc(parser, e)
1285
        stProc(parser, e)
1231
    ELSE
1286
    ELSE
Line 1237... Line 1292...
1237
 
1292
 
1238
PROCEDURE qualident (parser: PARS.PARSER; VAR e: PARS.EXPR);
1293
PROCEDURE qualident (parser: PARS.PARSER; VAR e: PARS.EXPR);
1239
VAR
1294
VAR
1240
    ident:  PROG.IDENT;
1295
    ident:  PROG.IDENT;
1241
    import: BOOLEAN;
1296
    import: BOOLEAN;
Line 1242... Line 1297...
1242
    pos:    SCAN.POSITION;
1297
    pos:    PARS.POSITION;
1243
 
1298
 
1244
BEGIN
1299
BEGIN
1245
    PARS.checklex(parser, SCAN.lxIDENT);
1300
    PARS.checklex(parser, SCAN.lxIDENT);
1246
    getpos(parser, pos);
1301
    getpos(parser, pos);
1247
    import := FALSE;
1302
    import := FALSE;
1248
    ident := parser.unit.idents.get(parser.unit, parser.lex.ident, FALSE);
1303
    ident := PROG.getIdent(parser.unit, parser.lex.ident, FALSE);
1249
    PARS.check1(ident # NIL, parser, 48);
1304
    PARS.check1(ident # NIL, parser, 48);
1250
    IF ident.typ = PROG.idMODULE THEN
1305
    IF ident.typ = PROG.idMODULE THEN
1251
        PARS.ExpectSym(parser, SCAN.lxPOINT);
1306
        PARS.ExpectSym(parser, SCAN.lxPOINT);
1252
        PARS.ExpectSym(parser, SCAN.lxIDENT);
1307
        PARS.ExpectSym(parser, SCAN.lxIDENT);
1253
        ident := ident.unit.idents.get(ident.unit, parser.lex.ident, FALSE);
1308
        ident := PROG.getIdent(ident.unit, parser.lex.ident, FALSE);
1254
        PARS.check1((ident # NIL) & ident.export, parser, 48);
1309
        PARS.check1((ident # NIL) & ident.export, parser, 48);
1255
        import := TRUE
1310
        import := TRUE
Line 1296... Line 1351...
1296
        e.stproc := ident.stproc
1351
        e.stproc := ident.stproc
1297
    |PROG.idSYSPROC:
1352
    |PROG.idSYSPROC:
1298
        e.obj    := eSYSPROC;
1353
        e.obj    := eSYSPROC;
1299
        e.stproc := ident.stproc
1354
        e.stproc := ident.stproc
1300
    |PROG.idSYSFUNC:
1355
    |PROG.idSYSFUNC:
1301
        PARS.check(~parser.constexp, parser, pos, 109);
1356
        PARS.check(~parser.constexp, pos, 109);
1302
        e.obj    := eSYSFUNC;
1357
        e.obj    := eSYSFUNC;
1303
        e.stproc := ident.stproc
1358
        e.stproc := ident.stproc
1304
    |PROG.idNONE:
1359
    |PROG.idNONE:
1305
        PARS.check(FALSE, parser, pos, 115)
1360
        PARS.error(pos, 115)
1306
    END;
1361
    END;
Line 1307... Line 1362...
1307
 
1362
 
1308
    IF isVar(e) THEN
1363
    IF isVar(e) THEN
1309
        PARS.check(e.ident.global OR (e.ident.scopeLvl = parser.unit.scopeLvl), parser, pos, 105)
1364
        PARS.check(e.ident.global OR (e.ident.scopeLvl = parser.unit.scopeLvl), pos, 105)
Line 1310... Line 1365...
1310
    END
1365
    END
Line 1311... Line 1366...
1311
 
1366
 
1312
END qualident;
1367
END qualident;
1313
 
1368
 
Line 1314... Line 1369...
1314
 
1369
 
1315
PROCEDURE deref (pos: SCAN.POSITION; e: PARS.EXPR; load: BOOLEAN; error: INTEGER);
1370
PROCEDURE deref (pos: PARS.POSITION; e: PARS.EXPR; load: BOOLEAN; error: INTEGER);
1316
VAR
1371
VAR
1317
    label:  INTEGER;
1372
    label:  INTEGER;
Line 1318... Line 1373...
1318
 
1373
 
1319
BEGIN
1374
BEGIN
1320
    IF load THEN
1375
    IF load THEN
1321
        CODE.load(e.type.size)
1376
        IL.load(e.type.size)
1322
    END;
1377
    END;
1323
 
1378
 
1324
    IF chkPTR IN checking THEN
1379
    IF chkPTR IN Options.checking THEN
Line 1325... Line 1380...
1325
        label := CODE.NewLabel();
1380
        label := IL.NewLabel();
1326
        CODE.AddJmpCmd(CODE.opJNZ, label);
1381
        IL.AddJmpCmd(IL.opJNZ, label);
1327
        CODE.OnError(pos.line, error);
1382
        IL.OnError(pos.line, error);
1328
        CODE.SetLabel(label)
1383
        IL.SetLabel(label)
1329
    END
1384
    END
Line 1330... Line 1385...
1330
END deref;
1385
END deref;
1331
 
1386
 
Line 1346... Line 1401...
1346
            offset, n: INTEGER;
1401
            offset, n: INTEGER;
1347
        BEGIN
1402
        BEGIN
1348
            offset := e.ident.offset;
1403
            offset := e.ident.offset;
1349
            n := PROG.Dim(e.type);
1404
            n := PROG.Dim(e.type);
1350
            WHILE n >= 0 DO
1405
            WHILE n >= 0 DO
1351
                CODE.AddCmd(CODE.opVADR, offset);
1406
                IL.AddCmd(IL.opVADR, offset);
1352
                DEC(offset);
1407
                DEC(offset);
1353
                DEC(n)
1408
                DEC(n)
1354
            END
1409
            END
1355
        END OpenArray;
1410
        END OpenArray;
Line 1356... Line 1411...
1356
 
1411
 
1357
 
1412
 
1358
    BEGIN
1413
    BEGIN
1359
        IF e.obj = eVAR THEN
1414
        IF e.obj = eVAR THEN
1360
            offset := PROG.getOffset(PARS.program, e.ident);
1415
            offset := PROG.getOffset(PARS.program, e.ident);
1361
            IF e.ident.global THEN
1416
            IF e.ident.global THEN
1362
                CODE.AddCmd(CODE.opGADR, offset)
1417
                IL.AddCmd(IL.opGADR, offset)
1363
            ELSE
1418
            ELSE
1364
                CODE.AddCmd(CODE.opLADR, -offset)
1419
                IL.AddCmd(IL.opLADR, -offset)
1365
            END
1420
            END
1366
        ELSIF e.obj = ePARAM THEN
1421
        ELSIF e.obj = ePARAM THEN
1367
            IF (e.type.typ = PROG.tRECORD) OR ((e.type.typ = PROG.tARRAY) & (e.type.length > 0)) THEN
1422
            IF (e.type.typ = PROG.tRECORD) OR ((e.type.typ = PROG.tARRAY) & (e.type.length > 0)) THEN
1368
                CODE.AddCmd(CODE.opVADR, e.ident.offset)
1423
                IL.AddCmd(IL.opVADR, e.ident.offset)
1369
            ELSIF PROG.isOpenArray(e.type) THEN
1424
            ELSIF PROG.isOpenArray(e.type) THEN
1370
                OpenArray(e)
1425
                OpenArray(e)
1371
            ELSE
1426
            ELSE
1372
                CODE.AddCmd(CODE.opLADR, e.ident.offset)
1427
                IL.AddCmd(IL.opLADR, e.ident.offset)
1373
            END
1428
            END
1374
        ELSIF e.obj IN {eVPAR, eVREC} THEN
1429
        ELSIF e.obj IN {eVPAR, eVREC} THEN
1375
            IF PROG.isOpenArray(e.type) THEN
1430
            IF PROG.isOpenArray(e.type) THEN
1376
                OpenArray(e)
1431
                OpenArray(e)
1377
            ELSE
1432
            ELSE
1378
                CODE.AddCmd(CODE.opVADR, e.ident.offset)
1433
                IL.AddCmd(IL.opVADR, e.ident.offset)
1379
            END
1434
            END
Line 1380... Line 1435...
1380
        END
1435
        END
1381
    END LoadAdr;
1436
    END LoadAdr;
1382
 
1437
 
1383
 
1438
 
1384
    PROCEDURE OpenIdx (parser: PARS.PARSER; pos: SCAN.POSITION; e: PARS.EXPR);
1439
    PROCEDURE OpenIdx (parser: PARS.PARSER; pos: PARS.POSITION; e: PARS.EXPR);
Line 1385... Line 1440...
1385
    VAR
1440
    VAR
Line 1386... Line 1441...
1386
        label:  INTEGER;
1441
        label:  INTEGER;
1387
        type:   PROG.TYPE_;
1442
        type:   PROG.TYPE_;
1388
        n, offset, k: INTEGER;
1443
        n, offset, k: INTEGER;
1389
 
1444
 
1390
    BEGIN
1445
    BEGIN
1391
 
1446
 
1392
        IF chkIDX IN checking THEN
1447
        IF chkIDX IN Options.checking THEN
1393
            label := CODE.NewLabel();
1448
            label := IL.NewLabel();
Line 1394... Line 1449...
1394
            CODE.AddCmd2(CODE.opCHKIDX2, label, 0);
1449
            IL.AddCmd2(IL.opCHKIDX2, label, 0);
1395
            CODE.OnError(pos.line, errIDX);
1450
            IL.OnError(pos.line, errIDX);
1396
            CODE.SetLabel(label)
1451
            IL.SetLabel(label)
1397
        ELSE
1452
        ELSE
1398
            CODE.AddCmd(CODE.opCHKIDX2, -1)
1453
            IL.AddCmd(IL.opCHKIDX2, -1)
1399
        END;
1454
        END;
1400
 
1455
 
1401
        type := PROG.OpenBase(e.type);
1456
        type := PROG.OpenBase(e.type);
1402
        IF type.size # 1 THEN
1457
        IF type.size # 1 THEN
1403
            CODE.AddCmd(CODE.opMULC, type.size)
1458
            IL.AddCmd(IL.opMULC, type.size)
1404
        END;
1459
        END;
1405
        n := PROG.Dim(e.type) - 1;
1460
        n := PROG.Dim(e.type) - 1;
1406
        k := n;
1461
        k := n;
1407
        WHILE n > 0 DO
1462
        WHILE n > 0 DO
1408
            CODE.AddCmd0(CODE.opMUL);
1463
            IL.AddCmd0(IL.opMUL);
1409
            DEC(n)
1464
            DEC(n)
1410
        END;
1465
        END;
1411
        CODE.AddCmd0(CODE.opADD);
1466
        IL.AddCmd0(IL.opADD);
1412
        offset := e.ident.offset - 1;
1467
        offset := e.ident.offset - 1;
Line 1439... Line 1494...
1439
        PARS.ExpectSym(parser, SCAN.lxIDENT);
1494
        PARS.ExpectSym(parser, SCAN.lxIDENT);
1440
        IF e.type.typ = PROG.tPOINTER THEN
1495
        IF e.type.typ = PROG.tPOINTER THEN
1441
            e.type := e.type.base;
1496
            e.type := e.type.base;
1442
            e.readOnly := FALSE
1497
            e.readOnly := FALSE
1443
        END;
1498
        END;
1444
        field := e.type.fields.get(e.type, parser.lex.ident, parser.unit);
1499
        field := PROG.getField(e.type, parser.lex.ident, parser.unit);
1445
        PARS.check1(field # NIL, parser, 74);
1500
        PARS.check1(field # NIL, parser, 74);
1446
        e.type := field.type;
1501
        e.type := field.type;
1447
        IF e.obj = eVREC THEN
1502
        IF e.obj = eVREC THEN
1448
            e.obj := eVPAR
1503
            e.obj := eVPAR
1449
        END;
1504
        END;
1450
        IF field.offset # 0 THEN
1505
        IF field.offset # 0 THEN
1451
            CODE.AddCmd(CODE.opADDR, field.offset)
1506
            IL.AddCmd(IL.opADDR, field.offset)
1452
        END;
1507
        END;
1453
        PARS.Next(parser);
1508
        PARS.Next(parser);
1454
        e.ident := NIL
1509
        e.ident := NIL
Line 1455... Line 1510...
1455
 
1510
 
Line 1456... Line 1511...
1456
    ELSIF parser.sym = SCAN.lxLSQUARE DO
1511
    ELSIF parser.sym = SCAN.lxLSQUARE DO
Line 1457... Line 1512...
1457
 
1512
 
1458
        REPEAT
1513
        REPEAT
1459
 
1514
 
1460
            PARS.check1(isArr(e), parser, 75);
1515
            PARS.check1(isArr(e), parser, 75);
Line 1461... Line 1516...
1461
            NextPos(parser, pos);
1516
            NextPos(parser, pos);
1462
            parser.expression(parser, idx);
1517
            PExpression(parser, idx);
1463
            PARS.check(isInt(idx), parser, pos, 76);
1518
            PARS.check(isInt(idx), pos, 76);
1464
 
1519
 
1465
            IF idx.obj = eCONST THEN
1520
            IF idx.obj = eCONST THEN
1466
                IF e.type.length > 0 THEN
1521
                IF e.type.length > 0 THEN
1467
                    PARS.check(ARITH.range(idx.value, 0, e.type.length - 1), parser, pos, 83);
1522
                    PARS.check(ARITH.range(idx.value, 0, e.type.length - 1), pos, 83);
1468
                    IF ARITH.Int(idx.value) > 0 THEN
1523
                    IF ARITH.Int(idx.value) > 0 THEN
1469
                        CODE.AddCmd(CODE.opADDR, ARITH.Int(idx.value) * e.type.base.size)
1524
                        IL.AddCmd(IL.opADDR, ARITH.Int(idx.value) * e.type.base.size)
1470
                    END
1525
                    END
1471
                ELSE
1526
                ELSE
1472
                    PARS.check(ARITH.range(idx.value, 0, MACHINE.target.maxInt), parser, pos, 83);
1527
                    PARS.check(ARITH.range(idx.value, 0, UTILS.target.maxInt), pos, 83);
1473
                    LoadConst(idx);
1528
                    LoadConst(idx);
1474
                    OpenIdx(parser, pos, e)
1529
                    OpenIdx(parser, pos, e)
1475
                END
1530
                END
1476
            ELSE
1531
            ELSE
1477
                IF e.type.length > 0 THEN
1532
                IF e.type.length > 0 THEN
1478
                    IF chkIDX IN checking THEN
1533
                    IF chkIDX IN Options.checking THEN
1479
                        CheckRange(e.type.length, pos.line, errIDX)
1534
                        CheckRange(e.type.length, pos.line, errIDX)
1480
                    END;
1535
                    END;
1481
                    IF e.type.base.size # 1 THEN
1536
                    IF e.type.base.size # 1 THEN
1482
                        CODE.AddCmd(CODE.opMULC, e.type.base.size)
1537
                        IL.AddCmd(IL.opMULC, e.type.base.size)
1483
                    END;
1538
                    END;
1484
                    CODE.AddCmd0(CODE.opADD)
1539
                    IL.AddCmd0(IL.opADD)
Line 1510... Line 1565...
1510
        IF e.type.typ = PROG.tRECORD THEN
1565
        IF e.type.typ = PROG.tRECORD THEN
1511
            PARS.check1(e.obj = eVREC, parser, 78)
1566
            PARS.check1(e.obj = eVREC, parser, 78)
1512
        END;
1567
        END;
1513
        NextPos(parser, pos);
1568
        NextPos(parser, pos);
1514
        qualident(parser, t);
1569
        qualident(parser, t);
1515
        PARS.check(t.obj = eTYPE, parser, pos, 79);
1570
        PARS.check(t.obj = eTYPE, pos, 79);
Line 1516... Line 1571...
1516
 
1571
 
1517
        IF e.type.typ = PROG.tRECORD THEN
1572
        IF e.type.typ = PROG.tRECORD THEN
1518
            PARS.check(t.type.typ = PROG.tRECORD, parser, pos, 80);
1573
            PARS.check(t.type.typ = PROG.tRECORD, pos, 80);
1519
            IF chkGUARD IN checking THEN
1574
            IF chkGUARD IN Options.checking THEN
1520
                IF e.ident = NIL THEN
1575
                IF e.ident = NIL THEN
1521
                    CODE.TypeGuard(CODE.opTYPEGD, t.type.num, pos.line, errGUARD)
1576
                    IL.TypeGuard(IL.opTYPEGD, t.type.num, pos.line, errGUARD)
1522
                ELSE
1577
                ELSE
1523
                    CODE.AddCmd(CODE.opVADR, e.ident.offset - 1);
1578
                    IL.AddCmd(IL.opVADR, e.ident.offset - 1);
1524
                    CODE.TypeGuard(CODE.opTYPEGR, t.type.num, pos.line, errGUARD)
1579
                    IL.TypeGuard(IL.opTYPEGR, t.type.num, pos.line, errGUARD)
1525
                END
1580
                END
1526
            END;
1581
            END;
1527
        ELSE
1582
        ELSE
1528
            PARS.check(t.type.typ = PROG.tPOINTER, parser, pos, 81);
1583
            PARS.check(t.type.typ = PROG.tPOINTER, pos, 81);
1529
            IF chkGUARD IN checking THEN
1584
            IF chkGUARD IN Options.checking THEN
1530
                CODE.TypeGuard(CODE.opTYPEGP, t.type.base.num, pos.line, errGUARD)
1585
                IL.TypeGuard(IL.opTYPEGP, t.type.base.num, pos.line, errGUARD)
1531
            END
1586
            END
Line 1532... Line 1587...
1532
        END;
1587
        END;
Line 1533... Line 1588...
1533
 
1588
 
Line 1534... Line 1589...
1534
        PARS.check(PROG.isBaseOf(e.type, t.type), parser, pos, 82);
1589
        PARS.check(PROG.isBaseOf(e.type, t.type), pos, 82);
1535
 
1590
 
Line 1541... Line 1596...
1541
    END
1596
    END
Line 1542... Line 1597...
1542
 
1597
 
Line 1543... Line 1598...
1543
END designator;
1598
END designator;
1544
 
1599
 
1545
 
1600
 
1546
PROCEDURE ProcCall (e: PARS.EXPR; procType: PROG.TYPE_; isfloat: BOOLEAN; VAR fregs: INTEGER; parser: PARS.PARSER; pos: SCAN.POSITION; CallStat: BOOLEAN);
1601
PROCEDURE ProcCall (e: PARS.EXPR; procType: PROG.TYPE_; isfloat: BOOLEAN; VAR fregs: INTEGER; parser: PARS.PARSER; pos: PARS.POSITION; CallStat: BOOLEAN);
1547
VAR
1602
VAR
1548
    cconv:    INTEGER;
1603
    cconv:     INTEGER;
1549
    params:   INTEGER;
1604
    parSize:   INTEGER;
1550
    callconv: INTEGER;
1605
    callconv:  INTEGER;
Line 1551... Line 1606...
1551
    fparams:  INTEGER;
1606
    fparSize:  INTEGER;
1552
    int, flt: INTEGER;
1607
    int, flt:  INTEGER;
1553
    stk_par:  INTEGER;
1608
    stk_par:   INTEGER;
Line 1554... Line 1609...
1554
 
1609
 
1555
BEGIN
1610
BEGIN
1556
    cconv := procType.call;
1611
    cconv := procType.call;
1557
    params := procType.params.size;
1612
    parSize := procType.parSize;
1558
 
1613
 
1559
    IF cconv IN {PROG._win64, PROG.win64} THEN
1614
    IF cconv IN {PROG._win64, PROG.win64} THEN
1560
        callconv := CODE.call_win64;
1615
        callconv := IL.call_win64;
1561
        fparams := LSL(ORD(procType.params.getfparams(procType, 3, int, flt)), 5) + MIN(params, 4)
1616
        fparSize := LSL(ORD(PROG.getFloatParamsPos(procType, 3, int, flt)), 5) + MIN(parSize, 4)
1562
    ELSIF cconv IN {PROG._systemv, PROG.systemv} THEN
1617
    ELSIF cconv IN {PROG._systemv, PROG.systemv} THEN
1563
        callconv := CODE.call_sysv;
1618
        callconv := IL.call_sysv;
1564
        fparams := LSL(ORD(procType.params.getfparams(procType, PROG.MAXSYSVPARAM - 1, int, flt)), 5) + params;
1619
        fparSize := LSL(ORD(PROG.getFloatParamsPos(procType, PROG.MAXSYSVPARAM - 1, int, flt)), 5) + parSize;
1565
        stk_par := MAX(0, int - 6) + MAX(0, flt - 8)
1620
        stk_par := MAX(0, int - 6) + MAX(0, flt - 8)
1566
    ELSE
1621
    ELSE
Line 1567... Line 1622...
1567
        callconv := CODE.call_stack;
1622
        callconv := IL.call_stack;
1568
        fparams := 0
1623
        fparSize := 0
1569
    END;
1624
    END;
1570
    CODE.setlast(begcall);
1625
    IL.setlast(begcall);
1571
    fregs := CODE.precall(isfloat);
1626
    fregs := IL.precall(isfloat);
1572
 
1627
 
1573
    IF cconv IN {PROG._ccall16, PROG.ccall16} THEN
1628
    IF cconv IN {PROG._ccall16, PROG.ccall16} THEN
1574
        CODE.AddCmd(CODE.opALIGN16, params)
1629
        IL.AddCmd(IL.opALIGN16, parSize)
Line 1575... Line 1630...
1575
    ELSIF cconv IN {PROG._win64, PROG.win64} THEN
1630
    ELSIF cconv IN {PROG._win64, PROG.win64} THEN
1576
        CODE.AddCmd(CODE.opWIN64ALIGN16, params)
1631
        IL.AddCmd(IL.opWIN64ALIGN16, parSize)
1577
    ELSIF cconv IN {PROG._systemv, PROG.systemv} THEN
1632
    ELSIF cconv IN {PROG._systemv, PROG.systemv} THEN
1578
        CODE.AddCmd(CODE.opSYSVALIGN16, params + stk_par)
1633
        IL.AddCmd(IL.opSYSVALIGN16, parSize + stk_par)
1579
    END;
1634
    END;
1580
    CODE.setlast(endcall.prev(CODE.COMMAND));
1635
    IL.setlast(endcall.prev(IL.COMMAND));
1581
 
1636
 
1582
    IF e.obj = eIMP THEN
1637
    IF e.obj = eIMP THEN
Line 1583... Line 1638...
1583
        CODE.CallImp(e.ident.import, callconv, fparams)
1638
        IL.CallImp(e.ident.import, callconv, fparSize)
1584
    ELSIF e.obj = ePROC THEN
1639
    ELSIF e.obj = ePROC THEN
1585
        CODE.Call(e.ident.proc.label, callconv, fparams)
1640
        IL.Call(e.ident.proc.label, callconv, fparSize)
1586
    ELSIF isExpr(e) THEN
1641
    ELSIF isExpr(e) THEN
1587
        deref(pos, e, CallStat, errPROC);
1642
        deref(pos, e, CallStat, errPROC);
1588
        CODE.CallP(callconv, fparams)
1643
        IL.CallP(callconv, fparSize)
1589
    END;
1644
    END;
1590
 
1645
 
1591
    IF cconv IN {PROG._ccall16, PROG.ccall16} THEN
1646
    IF cconv IN {PROG._ccall16, PROG.ccall16} THEN
1592
        CODE.AddCmd(CODE.opCLEANUP, params);
1647
        IL.AddCmd(IL.opCLEANUP, parSize);
1593
        CODE.AddCmd0(CODE.opPOPSP)
1648
        IL.AddCmd0(IL.opPOPSP)
1594
    ELSIF cconv IN {PROG._win64, PROG.win64} THEN
1649
    ELSIF cconv IN {PROG._win64, PROG.win64} THEN
Line 1595... Line 1650...
1595
        CODE.AddCmd(CODE.opCLEANUP, MAX(params + params MOD 2, 4) + 1);
1650
        IL.AddCmd(IL.opCLEANUP, MAX(parSize + parSize MOD 2, 4) + 1);
1596
        CODE.AddCmd0(CODE.opPOPSP)
1651
        IL.AddCmd0(IL.opPOPSP)
1597
    ELSIF cconv IN {PROG._systemv, PROG.systemv} THEN
1652
    ELSIF cconv IN {PROG._systemv, PROG.systemv} THEN
1598
        CODE.AddCmd(CODE.opCLEANUP, params + stk_par);
1653
        IL.AddCmd(IL.opCLEANUP, parSize + stk_par);
1599
        CODE.AddCmd0(CODE.opPOPSP)
1654
        IL.AddCmd0(IL.opPOPSP)
1600
    ELSIF cconv IN {PROG._ccall, PROG.ccall} THEN
1655
    ELSIF cconv IN {PROG._ccall, PROG.ccall, PROG.default16, PROG.code, PROG._code} THEN
1601
        CODE.AddCmd(CODE.opCLEANUP, params)
1656
        IL.AddCmd(IL.opCLEANUP, parSize)
1602
    END;
1657
    END;
Line 1603... Line 1658...
1603
 
1658
 
1604
    IF ~CallStat THEN
1659
    IF ~CallStat THEN
1605
        IF isfloat THEN
1660
        IF isfloat THEN
Line 1606... Line 1661...
1606
            PARS.check(CODE.resf(fregs), parser, pos, 41)
1661
            PARS.check(IL.resf(fregs), pos, 41)
1607
        ELSE
1662
        ELSE
1608
            CODE.res(fregs)
1663
            IL.res(fregs)
1609
        END
1664
        END
Line 1644... Line 1699...
1644
 
1699
 
1645
 
1700
 
1646
    PROCEDURE element (parser: PARS.PARSER; VAR e: PARS.EXPR);
1701
    PROCEDURE element (parser: PARS.PARSER; VAR e: PARS.EXPR);
1647
    VAR
1702
    VAR
1648
        e1, e2: PARS.EXPR;
1703
        e1, e2: PARS.EXPR;
Line 1649... Line 1704...
1649
        pos:    SCAN.POSITION;
1704
        pos:    PARS.POSITION;
1650
        range:  BOOLEAN;
1705
        range:  BOOLEAN;
1651
 
1706
 
1652
    BEGIN
1707
    BEGIN
1653
        range := FALSE;
1708
        range := FALSE;
Line 1654... Line 1709...
1654
        getpos(parser, pos);
1709
        getpos(parser, pos);
1655
        expression(parser, e1);
1710
        expression(parser, e1);
1656
        PARS.check(isInt(e1), parser, pos, 76);
1711
        PARS.check(isInt(e1), pos, 76);
Line 1657... Line 1712...
1657
 
1712
 
Line 1658... Line 1713...
1658
        IF e1.obj = eCONST THEN
1713
        IF e1.obj = eCONST THEN
1659
            PARS.check(ARITH.range(e1.value, 0, MACHINE.target.maxSet), parser, pos, 44)
1714
            PARS.check(ARITH.range(e1.value, 0, UTILS.target.maxSet), pos, 44)
1660
        END;
1715
        END;
1661
 
1716
 
Line 1662... Line 1717...
1662
        range := parser.sym = SCAN.lxRANGE;
1717
        range := parser.sym = SCAN.lxRANGE;
1663
 
1718
 
1664
        IF range THEN
1719
        IF range THEN
1665
            NextPos(parser, pos);
1720
            NextPos(parser, pos);
1666
            expression(parser, e2);
1721
            expression(parser, e2);
1667
            PARS.check(isInt(e2), parser, pos, 76);
1722
            PARS.check(isInt(e2), pos, 76);
1668
 
1723
 
1669
            IF e2.obj = eCONST THEN
1724
            IF e2.obj = eCONST THEN
Line 1670... Line 1725...
1670
                PARS.check(ARITH.range(e2.value, 0, MACHINE.target.maxSet), parser, pos, 44)
1725
                PARS.check(ARITH.range(e2.value, 0, UTILS.target.maxSet), pos, 44)
Line 1671... Line 1726...
1671
            END
1726
            END
1672
        ELSE
1727
        ELSE
1673
            IF e1.obj = eCONST THEN
1728
            IF e1.obj = eCONST THEN
1674
                e2 := e1
1729
                e2 := e1
1675
            END
1730
            END
1676
        END;
1731
        END;
1677
 
1732
 
1678
        e.type := PARS.program.stTypes.tSET;
1733
        e.type := tSET;
1679
 
1734
 
1680
        IF (e1.obj = eCONST) & (e2.obj = eCONST) THEN
1735
        IF (e1.obj = eCONST) & (e2.obj = eCONST) THEN
1681
            ARITH.constrSet(e.value, e1.value, e2.value);
1736
            ARITH.constrSet(e.value, e1.value, e2.value);
1682
            e.obj := eCONST
1737
            e.obj := eCONST
1683
        ELSE
1738
        ELSE
1684
            IF range THEN
1739
            IF range THEN
1685
                IF e1.obj = eCONST THEN
1740
                IF e1.obj = eCONST THEN
1686
                    CODE.AddCmd(CODE.opRSETL, ARITH.Int(e1.value))
1741
                    IL.AddCmd(IL.opRSETL, ARITH.Int(e1.value))
1687
                ELSIF e2.obj = eCONST THEN
1742
                ELSIF e2.obj = eCONST THEN
Line 1688... Line 1743...
1688
                    CODE.AddCmd(CODE.opRSETR, ARITH.Int(e2.value))
1743
                    IL.AddCmd(IL.opRSETR, ARITH.Int(e2.value))
Line 1704... Line 1759...
1704
 
1759
 
1705
    BEGIN
1760
    BEGIN
Line 1706... Line 1761...
1706
        ASSERT(parser.sym = SCAN.lxLCURLY);
1761
        ASSERT(parser.sym = SCAN.lxLCURLY);
1707
 
1762
 
1708
        e.obj := eCONST;
1763
        e.obj := eCONST;
Line 1709... Line 1764...
1709
        e.type := PARS.program.stTypes.tSET;
1764
        e.type := tSET;
1710
        ARITH.emptySet(e.value);
1765
        ARITH.emptySet(e.value);
1711
 
1766
 
Line 1724... Line 1779...
1724
                element(parser, e1);
1779
                element(parser, e1);
1725
                IF (e.obj = eCONST) & (e1.obj = eCONST) THEN
1780
                IF (e.obj = eCONST) & (e1.obj = eCONST) THEN
1726
                    ARITH.opSet(e.value, e1.value, "+")
1781
                    ARITH.opSet(e.value, e1.value, "+")
1727
                ELSE
1782
                ELSE
1728
                    IF e.obj = eCONST THEN
1783
                    IF e.obj = eCONST THEN
1729
                        CODE.AddCmd(CODE.opADDSL, ARITH.Int(e.value))
1784
                        IL.AddCmd(IL.opADDSL, ARITH.Int(e.value))
1730
                    ELSIF e1.obj = eCONST THEN
1785
                    ELSIF e1.obj = eCONST THEN
1731
                        CODE.AddCmd(CODE.opADDSR, ARITH.Int(e1.value))
1786
                        IL.AddCmd(IL.opADDSR, ARITH.Int(e1.value))
1732
                    ELSE
1787
                    ELSE
1733
                        CODE.AddCmd0(CODE.opADDS)
1788
                        IL.AddCmd0(IL.opADDS)
1734
                    END;
1789
                    END;
1735
                    e.obj := eEXPR
1790
                    e.obj := eEXPR
1736
                END
1791
                END
1737
            END;
1792
            END;
1738
            PARS.checklex(parser, SCAN.lxRCURLY)
1793
            PARS.checklex(parser, SCAN.lxRCURLY)
Line 1742... Line 1797...
1742
 
1797
 
1743
 
1798
 
1744
    PROCEDURE factor (parser: PARS.PARSER; VAR e: PARS.EXPR);
1799
    PROCEDURE factor (parser: PARS.PARSER; VAR e: PARS.EXPR);
1745
    VAR
1800
    VAR
1746
        sym:      INTEGER;
1801
        sym:      INTEGER;
1747
        pos:      SCAN.POSITION;
1802
        pos:      PARS.POSITION;
1748
        e1:       PARS.EXPR;
1803
        e1:       PARS.EXPR;
Line 1749... Line 1804...
1749
        isfloat:  BOOLEAN;
1804
        isfloat:  BOOLEAN;
1750
        fregs:    INTEGER;
1805
        fregs:    INTEGER;
1751
 
1806
 
1752
 
1807
 
1753
        PROCEDURE LoadVar (e: PARS.EXPR; parser: PARS.PARSER; pos: SCAN.POSITION);
1808
        PROCEDURE LoadVar (e: PARS.EXPR; parser: PARS.PARSER; pos: PARS.POSITION);
1754
        BEGIN
1809
        BEGIN
1755
            IF ~(e.type.typ IN {PROG.tRECORD, PROG.tARRAY}) THEN
1810
            IF ~(e.type.typ IN {PROG.tRECORD, PROG.tARRAY}) THEN
1756
                IF e.type.typ = PROG.tREAL THEN
1811
                IF e.type = tREAL THEN
1757
                    PARS.check(CODE.loadf(), parser, pos, 41)
1812
                    PARS.check(IL.loadf(), pos, 41)
1758
                ELSE
1813
                ELSE
Line 1766... Line 1821...
1766
        sym := parser.sym;
1821
        sym := parser.sym;
Line 1767... Line 1822...
1767
 
1822
 
1768
        IF (sym = SCAN.lxINTEGER) OR (sym = SCAN.lxHEX) OR (sym = SCAN.lxFLOAT) OR (sym = SCAN.lxCHAR) OR (sym = SCAN.lxSTRING) THEN
1823
        IF (sym = SCAN.lxINTEGER) OR (sym = SCAN.lxHEX) OR (sym = SCAN.lxFLOAT) OR (sym = SCAN.lxCHAR) OR (sym = SCAN.lxSTRING) THEN
1769
            e.obj := eCONST;
1824
            e.obj := eCONST;
1770
            e.value := parser.lex.value;
1825
            e.value := parser.lex.value;
1771
            e.type := PARS.program.getType(PARS.program, e.value.typ);
1826
            e.type := PROG.getType(PARS.program, e.value.typ);
Line 1772... Line 1827...
1772
            PARS.Next(parser)
1827
            PARS.Next(parser)
1773
 
1828
 
1774
        ELSIF sym = SCAN.lxNIL THEN
1829
        ELSIF sym = SCAN.lxNIL THEN
1775
            e.obj   := eCONST;
1830
            e.obj  := eCONST;
Line 1776... Line 1831...
1776
            e.type  := PARS.program.stTypes.tNIL;
1831
            e.type := PARS.program.stTypes.tNIL;
1777
            PARS.Next(parser)
1832
            PARS.Next(parser)
1778
 
1833
 
1779
        ELSIF (sym = SCAN.lxTRUE) OR (sym = SCAN.lxFALSE) THEN
1834
        ELSIF (sym = SCAN.lxTRUE) OR (sym = SCAN.lxFALSE) THEN
1780
            e.obj   := eCONST;
1835
            e.obj := eCONST;
Line 1781... Line 1836...
1781
            ARITH.setbool(e.value, sym = SCAN.lxTRUE);
1836
            ARITH.setbool(e.value, sym = SCAN.lxTRUE);
1782
            e.type  := PARS.program.stTypes.tBOOLEAN;
1837
            e.type := tBOOLEAN;
Line 1783... Line 1838...
1783
            PARS.Next(parser)
1838
            PARS.Next(parser)
1784
 
1839
 
Line 1785... Line 1840...
1785
        ELSIF sym = SCAN.lxLCURLY THEN
1840
        ELSIF sym = SCAN.lxLCURLY THEN
Line 1786... Line 1841...
1786
            set(parser, e)
1841
            set(parser, e)
1787
 
1842
 
1788
        ELSIF sym = SCAN.lxIDENT THEN
1843
        ELSIF sym = SCAN.lxIDENT THEN
1789
            getpos(parser, pos);
1844
            getpos(parser, pos);
1790
 
1845
 
1791
            CODE.pushBegEnd(begcall, endcall);
1846
            IL.pushBegEnd(begcall, endcall);
1792
 
1847
 
1793
            designator(parser, e);
1848
            designator(parser, e);
1794
            IF isVar(e) THEN
1849
            IF isVar(e) THEN
1795
                LoadVar(e, parser, pos)
1850
                LoadVar(e, parser, pos)
1796
            END;
1851
            END;
1797
            IF parser.sym = SCAN.lxLROUND THEN
1852
            IF parser.sym = SCAN.lxLROUND THEN
1798
                e1 := e;
1853
                e1 := e;
1799
                ActualParameters(parser, e);
1854
                ActualParameters(parser, e);
1800
                PARS.check(e.type # NIL, parser, pos, 59);
1855
                PARS.check(e.type # NIL, pos, 59);
1801
                isfloat := e.type.typ = PROG.tREAL;
1856
                isfloat := e.type = tREAL;
Line 1802... Line 1857...
1802
                IF e1.obj IN {ePROC, eIMP} THEN
1857
                IF e1.obj IN {ePROC, eIMP} THEN
1803
                    ProcCall(e1, e1.ident.type, isfloat, fregs, parser, pos, FALSE)
1858
                    ProcCall(e1, e1.ident.type, isfloat, fregs, parser, pos, FALSE)
1804
                ELSIF isExpr(e1) THEN
1859
                ELSIF isExpr(e1) THEN
1805
                    ProcCall(e1, e1.type, isfloat, fregs, parser, pos, FALSE)
1860
                    ProcCall(e1, e1.type, isfloat, fregs, parser, pos, FALSE)
Line 1817... Line 1872...
1817
            END
1872
            END
Line 1818... Line 1873...
1818
 
1873
 
1819
        ELSIF sym = SCAN.lxNOT THEN
1874
        ELSIF sym = SCAN.lxNOT THEN
1820
            NextPos(parser, pos);
1875
            NextPos(parser, pos);
1821
            factor(parser, e);
1876
            factor(parser, e);
1822
            PARS.check(isBoolean(e), parser, pos, 72);
1877
            PARS.check(isBoolean(e), pos, 72);
1823
            IF e.obj # eCONST THEN
1878
            IF e.obj # eCONST THEN
1824
                CODE.not;
1879
                IL.not;
1825
                e.obj := eEXPR
1880
                e.obj := eEXPR
1826
            ELSE
1881
            ELSE
1827
                ASSERT(ARITH.neg(e.value))
1882
                ASSERT(ARITH.neg(e.value))
Line 1833... Line 1888...
1833
    END factor;
1888
    END factor;
Line 1834... Line 1889...
1834
 
1889
 
1835
 
1890
 
1836
    PROCEDURE term (parser: PARS.PARSER; VAR e: PARS.EXPR);
1891
    PROCEDURE term (parser: PARS.PARSER; VAR e: PARS.EXPR);
1837
    VAR
1892
    VAR
1838
        pos: SCAN.POSITION;
1893
        pos: PARS.POSITION;
Line 1839... Line 1894...
1839
        op:  INTEGER;
1894
        op:  INTEGER;
1840
        e1:  PARS.EXPR;
1895
        e1:  PARS.EXPR;
Line 1853... Line 1908...
1853
 
1908
 
1854
            IF op = SCAN.lxAND THEN
1909
            IF op = SCAN.lxAND THEN
Line 1855... Line 1910...
1855
                IF ~parser.constexp THEN
1910
                IF ~parser.constexp THEN
1856
 
1911
 
1857
                    IF label = -1 THEN
1912
                    IF label = -1 THEN
Line 1858... Line 1913...
1858
                        label := CODE.NewLabel()
1913
                        label := IL.NewLabel()
1859
                    END;
1914
                    END;
1860
 
1915
 
1861
                    IF e.obj = eCONST THEN
1916
                    IF e.obj = eCONST THEN
1862
                        CODE.AddCmd(CODE.opCONST, ORD(ARITH.getBool(e.value)))
1917
                        IL.Const(ORD(ARITH.getBool(e.value)))
1863
                    END;            
1918
                    END;
1864
                    CODE.AddCmd0(CODE.opACC);
1919
                    IL.AddCmd0(IL.opACC);
1865
                    CODE.AddJmpCmd(CODE.opJZ, label);
1920
                    IL.AddJmpCmd(IL.opJZ, label);
Line 1866... Line 1921...
1866
                    CODE.drop
1921
                    IL.drop
Line 1867... Line 1922...
1867
                END
1922
                END
1868
            END;
1923
            END;
1869
 
1924
 
1870
            factor(parser, e1);
1925
            factor(parser, e1);
Line 1871... Line 1926...
1871
 
1926
 
1872
            CASE op OF
1927
            CASE op OF
1873
            |SCAN.lxMUL:
1928
            |SCAN.lxMUL:
1874
                PARS.check(isInt(e) & isInt(e1) OR isReal(e) & isReal(e1) OR isSet(e) & isSet(e1), parser, pos, 37);
1929
                PARS.check(isInt(e) & isInt(e1) OR isReal(e) & isReal(e1) OR isSet(e) & isSet(e1), pos, 37);
1875
                IF (e.obj = eCONST) & (e1.obj = eCONST) THEN
1930
                IF (e.obj = eCONST) & (e1.obj = eCONST) THEN
Line 1876... Line 1931...
1876
 
1931
 
1877
                   CASE e.value.typ OF
1932
                   CASE e.value.typ OF
1878
                   |ARITH.tINTEGER: PARS.check(ARITH.opInt(e.value, e1.value, "*"),   parser, pos, 39)
1933
                   |ARITH.tINTEGER: PARS.check(ARITH.opInt(e.value, e1.value, "*"),   pos, 39)
1879
                   |ARITH.tREAL:    PARS.check(ARITH.opFloat(e.value, e1.value, "*"), parser, pos, 40)
1934
                   |ARITH.tREAL:    PARS.check(ARITH.opFloat(e.value, e1.value, "*"), pos, 40)
1880
                   |ARITH.tSET:     ARITH.opSet(e.value, e1.value, "*")
1935
                   |ARITH.tSET:     ARITH.opSet(e.value, e1.value, "*")
1881
                   END
1936
                   END
1882
 
1937
 
1883
                ELSE
1938
                ELSE
1884
                    IF isInt(e) THEN
1939
                    IF isInt(e) THEN
1885
                        IF e.obj = eCONST THEN
1940
                        IF e.obj = eCONST THEN
1886
                            CODE.AddCmd(CODE.opMULC, ARITH.Int(e.value))
1941
                            IL.AddCmd(IL.opMULC, ARITH.Int(e.value))
1887
                        ELSIF e1.obj = eCONST THEN
1942
                        ELSIF e1.obj = eCONST THEN
1888
                            CODE.AddCmd(CODE.opMULC, ARITH.Int(e1.value))
1943
                            IL.AddCmd(IL.opMULC, ARITH.Int(e1.value))
1889
                        ELSE
1944
                        ELSE
1890
                            CODE.AddCmd0(CODE.opMUL)
1945
                            IL.AddCmd0(IL.opMUL)
1891
                        END
1946
                        END
1892
                    ELSIF isReal(e) THEN
1947
                    ELSIF isReal(e) THEN
1893
                        IF e.obj = eCONST THEN
1948
                        IF e.obj = eCONST THEN
1894
                            CODE.Float(ARITH.Float(e.value))
1949
                            IL.Float(ARITH.Float(e.value))
1895
                        ELSIF e1.obj = eCONST THEN
1950
                        ELSIF e1.obj = eCONST THEN
1896
                            CODE.Float(ARITH.Float(e1.value))
1951
                            IL.Float(ARITH.Float(e1.value))
1897
                        END;
1952
                        END;
1898
                        CODE.fbinop(CODE.opMULF)
1953
                        IL.fbinop(IL.opMULF)
1899
                    ELSIF isSet(e) THEN
1954
                    ELSIF isSet(e) THEN
1900
                        IF e.obj = eCONST THEN
1955
                        IF e.obj = eCONST THEN
1901
                            CODE.AddCmd(CODE.opMULSC, ARITH.Int(e.value))
1956
                            IL.AddCmd(IL.opMULSC, ARITH.Int(e.value))
1902
                        ELSIF e1.obj = eCONST THEN
1957
                        ELSIF e1.obj = eCONST THEN
Line 1903... Line 1958...
1903
                            CODE.AddCmd(CODE.opMULSC, ARITH.Int(e1.value))
1958
                            IL.AddCmd(IL.opMULSC, ARITH.Int(e1.value))
1904
                        ELSE
1959
                        ELSE
1905
                            CODE.AddCmd0(CODE.opMULS)
1960
                            IL.AddCmd0(IL.opMULS)
1906
                        END
1961
                        END
1907
                    END;
1962
                    END;
1908
                    e.obj := eEXPR
1963
                    e.obj := eEXPR
Line 1909... Line 1964...
1909
                END
1964
                END
1910
 
1965
 
1911
            |SCAN.lxSLASH:
1966
            |SCAN.lxSLASH:
1912
                PARS.check(isReal(e) & isReal(e1) OR isSet(e) & isSet(e1), parser, pos, 37);
1967
                PARS.check(isReal(e) & isReal(e1) OR isSet(e) & isSet(e1), pos, 37);
Line 1913... Line 1968...
1913
                IF (e1.obj = eCONST) & isReal(e1) THEN
1968
                IF (e1.obj = eCONST) & isReal(e1) THEN
1914
                    PARS.check(~ARITH.isZero(e1.value), parser, pos, 45)
1969
                    PARS.check(~ARITH.isZero(e1.value), pos, 45)
1915
                END;
1970
                END;
1916
                IF (e.obj = eCONST) & (e1.obj = eCONST) THEN
1971
                IF (e.obj = eCONST) & (e1.obj = eCONST) THEN
1917
 
1972
 
1918
                    CASE e.value.typ OF
1973
                    CASE e.value.typ OF
1919
                    |ARITH.tREAL: PARS.check(ARITH.opFloat(e.value, e1.value, "/"), parser, pos, 40)
1974
                    |ARITH.tREAL: PARS.check(ARITH.opFloat(e.value, e1.value, "/"), pos, 40)
1920
                    |ARITH.tSET:  ARITH.opSet(e.value, e1.value, "/")
1975
                    |ARITH.tSET:  ARITH.opSet(e.value, e1.value, "/")
1921
                    END
1976
                    END
1922
 
1977
 
1923
                ELSE
1978
                ELSE
1924
                    IF isReal(e) THEN
1979
                    IF isReal(e) THEN
1925
                        IF e.obj = eCONST THEN
1980
                        IF e.obj = eCONST THEN
1926
                            CODE.Float(ARITH.Float(e.value));
1981
                            IL.Float(ARITH.Float(e.value));
1927
                            CODE.fbinop(CODE.opDIVFI)
1982
                            IL.fbinop(IL.opDIVFI)
1928
                        ELSIF e1.obj = eCONST THEN
1983
                        ELSIF e1.obj = eCONST THEN
1929
                            CODE.Float(ARITH.Float(e1.value));
1984
                            IL.Float(ARITH.Float(e1.value));
1930
                            CODE.fbinop(CODE.opDIVF)
1985
                            IL.fbinop(IL.opDIVF)
1931
                        ELSE
1986
                        ELSE
1932
                            CODE.fbinop(CODE.opDIVF)
1987
                            IL.fbinop(IL.opDIVF)
1933
                        END
1988
                        END
1934
                    ELSIF isSet(e) THEN
1989
                    ELSIF isSet(e) THEN
Line 1935... Line 1990...
1935
                        IF e.obj = eCONST THEN
1990
                        IF e.obj = eCONST THEN
1936
                            CODE.AddCmd(CODE.opDIVSC, ARITH.Int(e.value))
1991
                            IL.AddCmd(IL.opDIVSC, ARITH.Int(e.value))
1937
                        ELSIF e1.obj = eCONST THEN
1992
                        ELSIF e1.obj = eCONST THEN
1938
                            CODE.AddCmd(CODE.opDIVSC, ARITH.Int(e1.value))
1993
                            IL.AddCmd(IL.opDIVSC, ARITH.Int(e1.value))
-
 
1994
                        ELSE
-
 
1995
                            IL.AddCmd0(IL.opDIVS)
-
 
1996
                        END
1939
                        ELSE
1997
                    END;
1940
                            CODE.AddCmd0(CODE.opDIVS)
1998
                    e.obj := eEXPR
Line 1941... Line 1999...
1941
                        END
1999
                END
1942
                    END;
2000
 
1943
                    e.obj := eEXPR
2001
            |SCAN.lxDIV, SCAN.lxMOD:
1944
                END
2002
                PARS.check(isInt(e) & isInt(e1), pos, 37);
1945
 
2003
                IF e1.obj = eCONST THEN
Line 1946... Line 2004...
1946
            |SCAN.lxDIV, SCAN.lxMOD:
2004
                    PARS.check(~ARITH.isZero(e1.value), pos, 46);
1947
                PARS.check(isInt(e) & isInt(e1), parser, pos, 37);
2005
                    IF CPU = cpuMSP430 THEN
1948
                IF e1.obj = eCONST THEN
2006
                        PARS.check(ARITH.Int(e1.value) > 0, pos, 122)
-
 
2007
                    END
-
 
2008
                END;
-
 
2009
                IF (e.obj = eCONST) & (e1.obj = eCONST) THEN
1949
                    PARS.check(~ARITH.isZero(e1.value), parser, pos, 46)
2010
 
-
 
2011
                    IF op = SCAN.lxDIV THEN
1950
                END;
2012
                        PARS.check(ARITH.opInt(e.value, e1.value, "D"), pos, 39)
1951
                IF (e.obj = eCONST) & (e1.obj = eCONST) THEN
2013
                    ELSE
1952
 
2014
                        ASSERT(ARITH.opInt(e.value, e1.value, "M"))
1953
                    IF op = SCAN.lxDIV THEN
2015
                    END
1954
                        PARS.check(ARITH.opInt(e.value, e1.value, "D"), parser, pos, 39)
2016
 
1955
                    ELSE
2017
                ELSE
1956
                        ASSERT(ARITH.opInt(e.value, e1.value, "M"))
2018
                    IF e1.obj # eCONST THEN
1957
                    END
2019
                        label1 := IL.NewLabel();
1958
 
2020
                        IF CPU = cpuMSP430 THEN
1959
                ELSE
2021
                            IL.AddJmpCmd(IL.opJG, label1)
1960
                    IF e1.obj # eCONST THEN
2022
                        ELSE
1961
                        label1 := CODE.NewLabel();
2023
                            IL.AddJmpCmd(IL.opJNZ, label1)
1962
                        CODE.AddJmpCmd(CODE.opJNZ, label1)
2024
                        END
1963
                    END;
2025
                    END;
Line 1964... Line 2026...
1964
                    IF e.obj = eCONST THEN
2026
                    IF e.obj = eCONST THEN
1965
                        CODE.OnError(pos.line, errDIV);
2027
                        IL.OnError(pos.line, errDIV);
Line 1966... Line 2028...
1966
                        CODE.SetLabel(label1);
2028
                        IL.SetLabel(label1);
1967
                        CODE.AddCmd(CODE.opDIVL + ORD(op = SCAN.lxMOD), ARITH.Int(e.value))
2029
                        IL.AddCmd(IL.opDIVL + ORD(op = SCAN.lxMOD), ARITH.Int(e.value))
1968
                    ELSIF e1.obj = eCONST THEN
2030
                    ELSIF e1.obj = eCONST THEN
1969
                        CODE.AddCmd(CODE.opDIVR + ORD(op = SCAN.lxMOD), ARITH.Int(e1.value))
2031
                        IL.AddCmd(IL.opDIVR + ORD(op = SCAN.lxMOD), ARITH.Int(e1.value))
1970
                    ELSE
2032
                    ELSE
1971
                        CODE.OnError(pos.line, errDIV);
2033
                        IL.OnError(pos.line, errDIV);
1972
                        CODE.SetLabel(label1);
2034
                        IL.SetLabel(label1);
1973
                        CODE.AddCmd0(CODE.opDIV  + ORD(op = SCAN.lxMOD))
2035
                        IL.AddCmd0(IL.opDIV  + ORD(op = SCAN.lxMOD))
1974
                    END;
2036
                    END;
Line 1975... Line 2037...
1975
                    e.obj := eEXPR
2037
                    e.obj := eEXPR
1976
                END
2038
                END
Line 1977... Line 2039...
1977
 
2039
 
1978
            |SCAN.lxAND:
2040
            |SCAN.lxAND:
1979
                PARS.check(isBoolean(e) & isBoolean(e1), parser, pos, 37);
2041
                PARS.check(isBoolean(e) & isBoolean(e1), pos, 37);
1980
 
2042
 
Line 1981... Line 2043...
1981
                IF (e.obj = eCONST) & (e1.obj = eCONST) THEN
2043
                IF (e.obj = eCONST) & (e1.obj = eCONST) THEN
1982
                    ARITH.opBoolean(e.value, e1.value, "&")
2044
                    ARITH.opBoolean(e.value, e1.value, "&")
1983
                ELSE
2045
                ELSE
1984
                    e.obj := eEXPR;
2046
                    e.obj := eEXPR;
1985
                    IF e1.obj = eCONST THEN
2047
                    IF e1.obj = eCONST THEN
Line 1986... Line 2048...
1986
                        CODE.AddCmd(CODE.opCONST, ORD(ARITH.getBool(e1.value)))
2048
                        IL.Const(ORD(ARITH.getBool(e1.value)))
Line 2017... Line 2079...
2017
        END;
2079
        END;
Line 2018... Line 2080...
2018
 
2080
 
Line 2019... Line 2081...
2019
        term(parser, e);
2081
        term(parser, e);
2020
 
2082
 
Line 2021... Line 2083...
2021
        IF plus OR minus THEN
2083
        IF plus OR minus THEN
2022
            PARS.check(isInt(e) OR isReal(e) OR isSet(e), parser, pos, 36);
2084
            PARS.check(isInt(e) OR isReal(e) OR isSet(e), pos, 36);
2023
 
2085
 
Line 2024... Line 2086...
2024
            IF minus & (e.obj = eCONST) THEN
2086
            IF minus & (e.obj = eCONST) THEN
2025
                PARS.check(ARITH.neg(e.value), parser, pos, 39)
2087
                PARS.check(ARITH.neg(e.value), pos, 39)
2026
            END;
2088
            END;
2027
 
2089
 
2028
            IF e.obj # eCONST THEN
2090
            IF e.obj # eCONST THEN
2029
                IF minus THEN
2091
                IF minus THEN
2030
                    IF isInt(e) THEN
2092
                    IF isInt(e) THEN
2031
                        CODE.AddCmd0(CODE.opUMINUS)
2093
                        IL.AddCmd0(IL.opUMINUS)
2032
                    ELSIF isReal(e) THEN
2094
                    ELSIF isReal(e) THEN
2033
                        CODE.AddCmd0(CODE.opUMINF)
2095
                        IL.AddCmd0(IL.opUMINF)
2034
                    ELSIF isSet(e) THEN
2096
                    ELSIF isSet(e) THEN
2035
                        CODE.AddCmd0(CODE.opUMINS)
2097
                        IL.AddCmd0(IL.opUMINS)
2036
                    END
2098
                    END
Line 2050... Line 2112...
2050
            IF op = SCAN.lxOR THEN
2112
            IF op = SCAN.lxOR THEN
Line 2051... Line 2113...
2051
 
2113
 
Line 2052... Line 2114...
2052
                IF ~parser.constexp THEN
2114
                IF ~parser.constexp THEN
2053
 
2115
 
2054
                    IF label = -1 THEN
2116
                    IF label = -1 THEN
Line 2055... Line 2117...
2055
                        label := CODE.NewLabel()
2117
                        label := IL.NewLabel()
2056
                    END;
2118
                    END;
2057
 
2119
 
2058
                    IF e.obj = eCONST THEN
2120
                    IF e.obj = eCONST THEN
2059
                        CODE.AddCmd(CODE.opCONST, ORD(ARITH.getBool(e.value)))
2121
                        IL.Const(ORD(ARITH.getBool(e.value)))
2060
                    END;         
2122
                    END;
2061
                    CODE.AddCmd0(CODE.opACC);
2123
                    IL.AddCmd0(IL.opACC);
Line 2062... Line 2124...
2062
                    CODE.AddJmpCmd(CODE.opJNZ, label);
2124
                    IL.AddJmpCmd(IL.opJNZ, label);
Line 2063... Line 2125...
2063
                    CODE.drop
2125
                    IL.drop
Line 2074... Line 2136...
2074
                    op := ORD("+")
2136
                    op := ORD("+")
2075
                ELSE
2137
                ELSE
2076
                    op := ORD("-")
2138
                    op := ORD("-")
2077
                END;
2139
                END;
Line 2078... Line 2140...
2078
 
2140
 
2079
                PARS.check(isInt(e) & isInt(e1) OR isReal(e) & isReal(e1) OR isSet(e) & isSet(e1), parser, pos, 37);
2141
                PARS.check(isInt(e) & isInt(e1) OR isReal(e) & isReal(e1) OR isSet(e) & isSet(e1), pos, 37);
Line 2080... Line 2142...
2080
                IF (e.obj = eCONST) & (e1.obj = eCONST) THEN
2142
                IF (e.obj = eCONST) & (e1.obj = eCONST) THEN
2081
 
2143
 
2082
                   CASE e.value.typ OF
2144
                   CASE e.value.typ OF
2083
                   |ARITH.tINTEGER: PARS.check(ARITH.opInt(e.value, e1.value, CHR(op)),   parser, pos, 39)
2145
                   |ARITH.tINTEGER: PARS.check(ARITH.opInt(e.value, e1.value, CHR(op)),   pos, 39)
2084
                   |ARITH.tREAL:    PARS.check(ARITH.opFloat(e.value, e1.value, CHR(op)), parser, pos, 40)
2146
                   |ARITH.tREAL:    PARS.check(ARITH.opFloat(e.value, e1.value, CHR(op)), pos, 40)
Line 2085... Line 2147...
2085
                   |ARITH.tSET:     ARITH.opSet(e.value, e1.value, CHR(op))
2147
                   |ARITH.tSET:     ARITH.opSet(e.value, e1.value, CHR(op))
2086
                   END
2148
                   END
2087
 
2149
 
2088
                ELSE
2150
                ELSE
2089
                    IF isInt(e) THEN
2151
                    IF isInt(e) THEN
2090
                        IF e.obj = eCONST THEN
2152
                        IF e.obj = eCONST THEN
2091
                            CODE.AddCmd(CODE.opADDL + ORD(op = ORD("-")), ARITH.Int(e.value))
2153
                            IL.AddCmd(IL.opADDL + ORD(op = ORD("-")), ARITH.Int(e.value))
2092
                        ELSIF e1.obj = eCONST THEN
2154
                        ELSIF e1.obj = eCONST THEN
2093
                            CODE.AddCmd(CODE.opADDR + ORD(op = ORD("-")), ARITH.Int(e1.value))
2155
                            IL.AddCmd(IL.opADDR + ORD(op = ORD("-")), ARITH.Int(e1.value))
2094
                        ELSE
2156
                        ELSE
2095
                            CODE.AddCmd0(CODE.opADD  + ORD(op = ORD("-")))
2157
                            IL.AddCmd0(IL.opADD  + ORD(op = ORD("-")))
2096
                        END
2158
                        END
2097
                    ELSIF isReal(e) THEN
2159
                    ELSIF isReal(e) THEN
2098
                        IF e.obj = eCONST THEN
2160
                        IF e.obj = eCONST THEN
2099
                            CODE.Float(ARITH.Float(e.value));
2161
                            IL.Float(ARITH.Float(e.value));
2100
                            CODE.fbinop(CODE.opADDFI + ORD(op = ORD("-")))
2162
                            IL.fbinop(IL.opADDFI + ORD(op = ORD("-")))
2101
                        ELSIF e1.obj = eCONST THEN
2163
                        ELSIF e1.obj = eCONST THEN
2102
                            CODE.Float(ARITH.Float(e1.value));
2164
                            IL.Float(ARITH.Float(e1.value));
2103
                            CODE.fbinop(CODE.opADDF  + ORD(op = ORD("-")))
2165
                            IL.fbinop(IL.opADDF  + ORD(op = ORD("-")))
2104
                        ELSE
2166
                        ELSE
2105
                            CODE.fbinop(CODE.opADDF  + ORD(op = ORD("-")))
2167
                            IL.fbinop(IL.opADDF  + ORD(op = ORD("-")))
2106
                        END
2168
                        END
2107
                    ELSIF isSet(e) THEN
2169
                    ELSIF isSet(e) THEN
2108
                        IF e.obj = eCONST THEN
2170
                        IF e.obj = eCONST THEN
2109
                            CODE.AddCmd(CODE.opADDSL + ORD(op = ORD("-")), ARITH.Int(e.value))
2171
                            IL.AddCmd(IL.opADDSL + ORD(op = ORD("-")), ARITH.Int(e.value))
2110
                        ELSIF e1.obj = eCONST THEN
2172
                        ELSIF e1.obj = eCONST THEN
2111
                            CODE.AddCmd(CODE.opADDSR + ORD(op = ORD("-")), ARITH.Int(e1.value))
2173
                            IL.AddCmd(IL.opADDSR + ORD(op = ORD("-")), ARITH.Int(e1.value))
2112
                        ELSE
2174
                        ELSE
2113
                            CODE.AddCmd0(CODE.opADDS  + ORD(op = ORD("-")))
2175
                            IL.AddCmd0(IL.opADDS  + ORD(op = ORD("-")))
2114
                        END
2176
                        END
Line 2115... Line 2177...
2115
                    END;
2177
                    END;
2116
                    e.obj := eEXPR
2178
                    e.obj := eEXPR
Line 2117... Line 2179...
2117
                END
2179
                END
2118
 
2180
 
2119
            |SCAN.lxOR:
2181
            |SCAN.lxOR:
2120
                PARS.check(isBoolean(e) & isBoolean(e1), parser, pos, 37);
2182
                PARS.check(isBoolean(e) & isBoolean(e1), pos, 37);
2121
 
2183
 
2122
                IF (e.obj = eCONST) & (e1.obj = eCONST) THEN
2184
                IF (e.obj = eCONST) & (e1.obj = eCONST) THEN
2123
                    ARITH.opBoolean(e.value, e1.value, "|")
2185
                    ARITH.opBoolean(e.value, e1.value, "|")
2124
                ELSE
2186
                ELSE
2125
                    e.obj := eEXPR;
2187
                    e.obj := eEXPR;
Line 2126... Line 2188...
2126
                    IF e1.obj = eCONST THEN
2188
                    IF e1.obj = eCONST THEN
2127
                        CODE.AddCmd(CODE.opCONST, ORD(ARITH.getBool(e1.value)))
2189
                        IL.Const(ORD(ARITH.getBool(e1.value)))
Line 2128... Line 2190...
2128
                    END;
2190
                    END;
2129
                    CODE.AddCmd0(CODE.opACC)
2191
                    IL.AddCmd0(IL.opACC)
2130
                END
2192
                END
Line 2131... Line 2193...
2131
 
2193
 
Line 2132... Line 2194...
2132
            END
2194
            END
2133
        END;
2195
        END;
2134
 
2196
 
-
 
2197
        IF label # -1 THEN
2135
        IF label # -1 THEN
2198
            IL.SetLabel(label)
2136
            CODE.SetLabel(label)
2199
        END
2137
        END
2200
 
2138
 
2201
    END SimpleExpression;
2139
    END SimpleExpression;
2202
 
Line 2154... Line 2217...
2154
 
2217
 
2155
        RETURN res
2218
        RETURN res
Line -... Line 2219...
-
 
2219
    END cmpcode;
-
 
2220
 
-
 
2221
 
-
 
2222
    PROCEDURE invcmpcode (op: INTEGER): INTEGER;
-
 
2223
    VAR
-
 
2224
        res: INTEGER;
-
 
2225
 
-
 
2226
    BEGIN
-
 
2227
        CASE op OF
-
 
2228
        |SCAN.lxEQ: res := 0
-
 
2229
        |SCAN.lxNE: res := 1
-
 
2230
        |SCAN.lxLT: res := 4
-
 
2231
        |SCAN.lxLE: res := 5
-
 
2232
        |SCAN.lxGT: res := 2
-
 
2233
        |SCAN.lxGE: res := 3
-
 
2234
        END
-
 
2235
 
-
 
2236
        RETURN res
2156
    END cmpcode;
2237
    END invcmpcode;
2157
 
2238
 
2158
 
2239
 
2159
    PROCEDURE BoolCmp (eq, val: BOOLEAN);
2240
    PROCEDURE BoolCmp (eq, val: BOOLEAN);
2160
    BEGIN
2241
    BEGIN
2161
       IF eq = val THEN
2242
       IF eq = val THEN
2162
           CODE.AddCmd0(CODE.opNER)
2243
           IL.AddCmd0(IL.opNEC)
2163
       ELSE
2244
       ELSE
Line 2164... Line 2245...
2164
           CODE.AddCmd0(CODE.opEQR)
2245
           IL.AddCmd0(IL.opEQC)
Line 2173... Line 2254...
2173
    BEGIN
2254
    BEGIN
Line 2174... Line 2255...
2174
 
2255
 
Line 2175... Line 2256...
2175
        res := TRUE;
2256
        res := TRUE;
2176
 
2257
 
2177
        IF isString(e) & isCharArray(e1) THEN
2258
        IF isString(e) & isCharArray(e1) THEN
2178
            CODE.AddCmd(CODE.opSADR, String(e));
2259
            IL.StrAdr(String(e));
Line 2179... Line 2260...
2179
            CODE.AddCmd(CODE.opCONST, strlen(e) + 1);
2260
            IL.Const(strlen(e) + 1);
2180
            CODE.AddCmd0(CODE.opEQS2 + cmpcode(op))
2261
            IL.AddCmd0(IL.opEQS + invcmpcode(op))
2181
 
2262
 
2182
        ELSIF isString(e) & isCharArrayW(e1) THEN
2263
        ELSIF isString(e) & isCharArrayW(e1) THEN
Line 2183... Line 2264...
2183
            CODE.AddCmd(CODE.opSADR, StringW(e));
2264
            IL.StrAdr(StringW(e));
2184
            CODE.AddCmd(CODE.opCONST, utf8strlen(e) + 1);
2265
            IL.Const(utf8strlen(e) + 1);
2185
            CODE.AddCmd0(CODE.opEQSW2 + cmpcode(op))
2266
            IL.AddCmd0(IL.opEQSW + invcmpcode(op))
2186
 
2267
 
Line 2187... Line 2268...
2187
        ELSIF isStringW(e) & isCharArrayW(e1) THEN
2268
        ELSIF isStringW(e) & isCharArrayW(e1) THEN
2188
            CODE.AddCmd(CODE.opSADR, StringW(e));
2269
            IL.StrAdr(StringW(e));
2189
            CODE.AddCmd(CODE.opCONST, utf8strlen(e) + 1);
2270
            IL.Const(utf8strlen(e) + 1);
2190
            CODE.AddCmd0(CODE.opEQSW2 + cmpcode(op))
2271
            IL.AddCmd0(IL.opEQSW + invcmpcode(op))
Line 2191... Line 2272...
2191
 
2272
 
2192
        ELSIF isCharArray(e) & isString(e1) THEN
2273
        ELSIF isCharArray(e) & isString(e1) THEN
2193
            CODE.AddCmd(CODE.opSADR, String(e1));
2274
            IL.StrAdr(String(e1));
2194
            CODE.AddCmd(CODE.opCONST, strlen(e1) + 1);
2275
            IL.Const(strlen(e1) + 1);
Line 2195... Line 2276...
2195
            CODE.AddCmd0(CODE.opEQS + cmpcode(op))
2276
            IL.AddCmd0(IL.opEQS + cmpcode(op))
2196
 
2277
 
2197
        ELSIF isCharArrayW(e) & isString(e1) THEN
2278
        ELSIF isCharArrayW(e) & isString(e1) THEN
2198
            CODE.AddCmd(CODE.opSADR, StringW(e1));
2279
            IL.StrAdr(StringW(e1));
Line 2199... Line 2280...
2199
            CODE.AddCmd(CODE.opCONST, utf8strlen(e1) + 1);
2280
            IL.Const(utf8strlen(e1) + 1);
2200
            CODE.AddCmd0(CODE.opEQSW + cmpcode(op))
2281
            IL.AddCmd0(IL.opEQSW + cmpcode(op))
Line 2201... Line 2282...
2201
 
2282
 
2202
        ELSIF isCharArrayW(e) & isStringW(e1) THEN
2283
        ELSIF isCharArrayW(e) & isStringW(e1) THEN
Line 2203... Line 2284...
2203
            CODE.AddCmd(CODE.opSADR, StringW(e1));
2284
            IL.StrAdr(StringW(e1));
2204
            CODE.AddCmd(CODE.opCONST, utf8strlen(e1) + 1);
2285
            IL.Const(utf8strlen(e1) + 1);
Line 2205... Line 2286...
2205
            CODE.AddCmd0(CODE.opEQSW + cmpcode(op))
2286
            IL.AddCmd0(IL.opEQSW + cmpcode(op))
Line 2225... Line 2306...
2225
BEGIN
2306
BEGIN
2226
    getpos(parser, pos0);
2307
    getpos(parser, pos0);
2227
    SimpleExpression(parser, e);
2308
    SimpleExpression(parser, e);
2228
    IF relation(parser.sym) THEN
2309
    IF relation(parser.sym) THEN
2229
        IF (isCharArray(e) OR isCharArrayW(e)) & (e.type.length # 0) THEN
2310
        IF (isCharArray(e) OR isCharArrayW(e)) & (e.type.length # 0) THEN
2230
            CODE.AddCmd(CODE.opCONST, e.type.length)
2311
            IL.Const(e.type.length)
2231
        END;
2312
        END;
2232
        op  := parser.sym;
2313
        op  := parser.sym;
2233
        getpos(parser, pos);
2314
        getpos(parser, pos);
2234
        PARS.Next(parser);
2315
        PARS.Next(parser);
Line 2235... Line 2316...
2235
 
2316
 
2236
        pos1 := parser.lex.pos;
2317
        getpos(parser, pos1);
Line 2237... Line 2318...
2237
        SimpleExpression(parser, e1);
2318
        SimpleExpression(parser, e1);
2238
 
2319
 
2239
        IF (isCharArray(e1) OR isCharArrayW(e1)) & (e1.type.length # 0) THEN
2320
        IF (isCharArray(e1) OR isCharArrayW(e1)) & (e1.type.length # 0) THEN
Line 2240... Line 2321...
2240
            CODE.AddCmd(CODE.opCONST, e1.type.length)
2321
            IL.Const(e1.type.length)
Line 2241... Line 2322...
2241
        END;
2322
        END;
Line 2265... Line 2346...
2265
            isPtr(e) & isPtr(e1) & (PROG.isBaseOf(e.type, e1.type) OR PROG.isBaseOf(e1.type, e.type)) THEN
2346
            isPtr(e) & isPtr(e1) & (PROG.isBaseOf(e.type, e1.type) OR PROG.isBaseOf(e1.type, e.type)) THEN
2266
                IF constant THEN
2347
                IF constant THEN
2267
                    ARITH.relation(e.value, e1.value, operator, error)
2348
                    ARITH.relation(e.value, e1.value, operator, error)
2268
                ELSE
2349
                ELSE
2269
                    IF e.obj = eCONST THEN
2350
                    IF e.obj = eCONST THEN
2270
                        CODE.AddCmd(CODE.opEQ + cmpcode(op) + 6,  ARITH.Int(e.value))
2351
                        IL.AddCmd(IL.opEQC + cmpcode(op), ARITH.Int(e.value))
2271
                    ELSIF e1.obj = eCONST THEN
2352
                    ELSIF e1.obj = eCONST THEN
2272
                        CODE.AddCmd(CODE.opEQ + cmpcode(op) + 12, ARITH.Int(e1.value))
2353
                        IL.AddCmd(IL.opEQC + cmpcode(op), ARITH.Int(e1.value))
2273
                    ELSE
2354
                    ELSE
2274
                        CODE.AddCmd0(CODE.opEQ + cmpcode(op))
2355
                        IL.AddCmd0(IL.opEQ + cmpcode(op))
2275
                    END
2356
                    END
2276
                END
2357
                END
Line 2277... Line 2358...
2277
 
2358
 
2278
            ELSIF isStringW1(e) & isCharW(e1) THEN
2359
            ELSIF isStringW1(e) & isCharW(e1) THEN
Line 2279... Line 2360...
2279
                CODE.AddCmd(CODE.opEQ + cmpcode(op) + 6, StrToWChar(e.value.string(SCAN.IDENT).s))
2360
                IL.AddCmd(IL.opEQC + cmpcode(op), StrToWChar(e.value.string(SCAN.IDENT).s))
2280
 
2361
 
Line 2281... Line 2362...
2281
            ELSIF isStringW1(e1) & isCharW(e) THEN
2362
            ELSIF isStringW1(e1) & isCharW(e) THEN
2282
                CODE.AddCmd(CODE.opEQ + cmpcode(op) + 12, StrToWChar(e1.value.string(SCAN.IDENT).s))
2363
                IL.AddCmd(IL.opEQC + cmpcode(op), StrToWChar(e1.value.string(SCAN.IDENT).s))
2283
 
2364
 
2284
            ELSIF isBoolean(e) & isBoolean(e1) THEN
2365
            ELSIF isBoolean(e) & isBoolean(e1) THEN
Line 2289... Line 2370...
2289
                        BoolCmp(op = SCAN.lxEQ, ARITH.Int(e.value) # 0)
2370
                        BoolCmp(op = SCAN.lxEQ, ARITH.Int(e.value) # 0)
2290
                    ELSIF e1.obj = eCONST THEN
2371
                    ELSIF e1.obj = eCONST THEN
2291
                        BoolCmp(op = SCAN.lxEQ, ARITH.Int(e1.value) # 0)
2372
                        BoolCmp(op = SCAN.lxEQ, ARITH.Int(e1.value) # 0)
2292
                    ELSE
2373
                    ELSE
2293
                        IF op = SCAN.lxEQ THEN
2374
                        IF op = SCAN.lxEQ THEN
2294
                            CODE.AddCmd0(CODE.opEQB)
2375
                            IL.AddCmd0(IL.opEQB)
2295
                        ELSE
2376
                        ELSE
2296
                            CODE.AddCmd0(CODE.opNEB)
2377
                            IL.AddCmd0(IL.opNEB)
2297
                        END
2378
                        END
2298
                    END
2379
                    END
2299
                END
2380
                END
Line 2300... Line 2381...
2300
 
2381
 
2301
            ELSIF isReal(e) & isReal(e1) THEN
2382
            ELSIF isReal(e) & isReal(e1) THEN
2302
                IF constant THEN
2383
                IF constant THEN
2303
                    ARITH.relation(e.value, e1.value, operator, error)
2384
                    ARITH.relation(e.value, e1.value, operator, error)
2304
                ELSE
2385
                ELSE
2305
                    IF e.obj = eCONST THEN
2386
                    IF e.obj = eCONST THEN
2306
                        CODE.Float(ARITH.Float(e.value));
-
 
2307
                        CODE.fcmp(CODE.opEQF + cmpcode(op) + 6)
2387
                        IL.Float(ARITH.Float(e.value))
2308
                    ELSIF e1.obj = eCONST THEN
2388
                    ELSIF e1.obj = eCONST THEN
2309
                        CODE.Float(ARITH.Float(e1.value));
-
 
2310
                        CODE.fcmp(CODE.opEQF + cmpcode(op))
2389
                        IL.Float(ARITH.Float(e1.value))
2311
                    ELSE
2390
                    END;
2312
                        CODE.fcmp(CODE.opEQF + cmpcode(op))
-
 
2313
                    END
2391
                    IL.fcmp(IL.opEQF + cmpcode(op))
Line 2314... Line 2392...
2314
                END
2392
                END
2315
 
2393
 
2316
            ELSIF (isStringW(e) OR isCharArrayX(e)) & (isStringW(e1) OR isCharArrayX(e1)) THEN
2394
            ELSIF (isStringW(e) OR isCharArrayX(e)) & (isStringW(e1) OR isCharArrayX(e1)) THEN
2317
                IF ~strcmp(e, e1, op) THEN
2395
                IF ~strcmp(e, e1, op) THEN
Line 2318... Line 2396...
2318
                    PARS.error(parser, pos, 37)
2396
                    PARS.error(pos, 37)
2319
                END
2397
                END
Line 2320... Line 2398...
2320
 
2398
 
2321
            ELSIF isPtr(e) & isNil(e1) OR isNil(e) & isPtr(e1) THEN
2399
            ELSIF isPtr(e) & isNil(e1) OR isNil(e) & isPtr(e1) THEN
2322
                CODE.AddCmd0(CODE.opEQ + cmpcode(op) + 6)
2400
                IL.AddCmd0(IL.opEQC + cmpcode(op))
2323
 
2401
 
2324
            ELSIF isProc(e) & isNil(e1) THEN
2402
            ELSIF isProc(e) & isNil(e1) THEN
2325
                IF e.obj IN {ePROC, eIMP} THEN
2403
                IF e.obj IN {ePROC, eIMP} THEN
2326
                    PARS.check(e.ident.global, parser, pos0, 85);
2404
                    PARS.check(e.ident.global, pos0, 85);
2327
                    constant := TRUE;
2405
                    constant := TRUE;
2328
                    e.obj := eCONST;
2406
                    e.obj := eCONST;
Line 2329... Line 2407...
2329
                    ARITH.setbool(e.value, op = SCAN.lxNE)
2407
                    ARITH.setbool(e.value, op = SCAN.lxNE)
2330
                ELSE
2408
                ELSE
2331
                    CODE.AddCmd0(CODE.opEQ + cmpcode(op) + 6)
2409
                    IL.AddCmd0(IL.opEQC + cmpcode(op))
2332
                END
2410
                END
2333
 
2411
 
2334
            ELSIF isNil(e) & isProc(e1) THEN
2412
            ELSIF isNil(e) & isProc(e1) THEN
2335
                IF e1.obj IN {ePROC, eIMP} THEN
2413
                IF e1.obj IN {ePROC, eIMP} THEN
2336
                    PARS.check(e1.ident.global, parser, pos1, 85);
2414
                    PARS.check(e1.ident.global, pos1, 85);
2337
                    constant := TRUE;
2415
                    constant := TRUE;
Line 2338... Line 2416...
2338
                    e.obj := eCONST;
2416
                    e.obj := eCONST;
2339
                    ARITH.setbool(e.value, op = SCAN.lxNE)
2417
                    ARITH.setbool(e.value, op = SCAN.lxNE)
2340
                ELSE
2418
                ELSE
2341
                    CODE.AddCmd0(CODE.opEQ + cmpcode(op) + 6)
2419
                    IL.AddCmd0(IL.opEQC + cmpcode(op))
2342
                END
2420
                END
2343
 
2421
 
2344
            ELSIF isProc(e) & isProc(e1) & PROG.isTypeEq(e.type, e1.type) THEN
2422
            ELSIF isProc(e) & isProc(e1) & PROG.isTypeEq(e.type, e1.type) THEN
2345
                IF e.obj = ePROC THEN
2423
                IF e.obj = ePROC THEN
2346
                    PARS.check(e.ident.global, parser, pos0, 85)
2424
                    PARS.check(e.ident.global, pos0, 85)
2347
                END;
2425
                END;
2348
                IF e1.obj = ePROC THEN
2426
                IF e1.obj = ePROC THEN
2349
                    PARS.check(e1.ident.global, parser, pos1, 85)
2427
                    PARS.check(e1.ident.global, pos1, 85)
2350
                END;
2428
                END;
2351
                IF (e.obj IN {ePROC, eIMP}) & (e1.obj IN {ePROC, eIMP}) THEN
2429
                IF (e.obj IN {ePROC, eIMP}) & (e1.obj IN {ePROC, eIMP}) THEN
2352
                    constant := TRUE;
2430
                    constant := TRUE;
2353
                    e.obj := eCONST;
2431
                    e.obj := eCONST;
2354
                    IF op = SCAN.lxEQ THEN
2432
                    IF op = SCAN.lxEQ THEN
2355
                        ARITH.setbool(e.value, e.ident = e1.ident)
2433
                        ARITH.setbool(e.value, e.ident = e1.ident)
2356
                    ELSE
2434
                    ELSE
2357
                        ARITH.setbool(e.value, e.ident # e1.ident)
2435
                        ARITH.setbool(e.value, e.ident # e1.ident)
2358
                    END
2436
                    END
2359
                ELSIF e.obj = ePROC THEN
2437
                ELSIF e.obj = ePROC THEN
2360
                    CODE.ProcCmp(e.ident.proc.label, cmpcode(op) = 0)
2438
                    IL.ProcCmp(e.ident.proc.label, op = SCAN.lxEQ)
2361
                ELSIF e1.obj = ePROC THEN
2439
                ELSIF e1.obj = ePROC THEN
2362
                    CODE.ProcCmp(e1.ident.proc.label, cmpcode(op) = 0)
2440
                    IL.ProcCmp(e1.ident.proc.label, op = SCAN.lxEQ)
2363
                ELSIF e.obj = eIMP THEN
2441
                ELSIF e.obj = eIMP THEN
Line 2364... Line 2442...
2364
                    CODE.ProcImpCmp(e.ident.import, cmpcode(op) = 0)
2442
                    IL.ProcImpCmp(e.ident.import, op = SCAN.lxEQ)
2365
                ELSIF e1.obj = eIMP THEN
2443
                ELSIF e1.obj = eIMP THEN
2366
                    CODE.ProcImpCmp(e1.ident.import, cmpcode(op) = 0)
2444
                    IL.ProcImpCmp(e1.ident.import, op = SCAN.lxEQ)
2367
                ELSE
2445
                ELSE
Line 2368... Line 2446...
2368
                    CODE.AddCmd0(CODE.opEQ + cmpcode(op))
2446
                    IL.AddCmd0(IL.opEQ + cmpcode(op))
2369
                END
2447
                END
2370
 
2448
 
Line 2371... Line 2449...
2371
            ELSIF isNil(e) & isNil(e1) THEN
2449
            ELSIF isNil(e) & isNil(e1) THEN
2372
                constant := TRUE;
2450
                constant := TRUE;
2373
                e.obj := eCONST;
2451
                e.obj := eCONST;
Line 2385... Line 2463...
2385
 
2463
 
2386
                IF constant THEN
2464
                IF constant THEN
2387
                    ARITH.relation(e.value, e1.value, operator, error)
2465
                    ARITH.relation(e.value, e1.value, operator, error)
2388
                ELSE
2466
                ELSE
2389
                    IF e.obj = eCONST THEN
2467
                    IF e.obj = eCONST THEN
2390
                        CODE.AddCmd(CODE.opEQ + cmpcode(op) + 6, ARITH.Int(e.value))
2468
                        IL.AddCmd(IL.opEQC + invcmpcode(op), ARITH.Int(e.value))
2391
                    ELSIF e1.obj = eCONST THEN
2469
                    ELSIF e1.obj = eCONST THEN
2392
                        CODE.AddCmd(CODE.opEQ + cmpcode(op) + 12, ARITH.Int(e1.value))
2470
                        IL.AddCmd(IL.opEQC + cmpcode(op), ARITH.Int(e1.value))
2393
                    ELSE
2471
                    ELSE
2394
                        CODE.AddCmd0(CODE.opEQ + cmpcode(op))
2472
                        IL.AddCmd0(IL.opEQ + cmpcode(op))
2395
                    END
2473
                    END
Line 2396... Line 2474...
2396
                END
2474
                END
2397
 
2475
 
Line 2398... Line 2476...
2398
            ELSIF isStringW1(e) & isCharW(e1) THEN
2476
            ELSIF isStringW1(e) & isCharW(e1) THEN
2399
                CODE.AddCmd(CODE.opEQ + cmpcode(op) + 6, StrToWChar(e.value.string(SCAN.IDENT).s))
2477
                IL.AddCmd(IL.opEQC + invcmpcode(op), StrToWChar(e.value.string(SCAN.IDENT).s))
Line 2400... Line 2478...
2400
 
2478
 
2401
            ELSIF isStringW1(e1) & isCharW(e) THEN
2479
            ELSIF isStringW1(e1) & isCharW(e) THEN
2402
                CODE.AddCmd(CODE.opEQ + cmpcode(op) + 12, StrToWChar(e1.value.string(SCAN.IDENT).s))
2480
                IL.AddCmd(IL.opEQC + cmpcode(op), StrToWChar(e1.value.string(SCAN.IDENT).s))
2403
 
2481
 
2404
            ELSIF isReal(e) & isReal(e1) THEN
2482
            ELSIF isReal(e) & isReal(e1) THEN
2405
                IF constant THEN
2483
                IF constant THEN
2406
                    ARITH.relation(e.value, e1.value, operator, error)
2484
                    ARITH.relation(e.value, e1.value, operator, error)
2407
                ELSE
2485
                ELSE
2408
                    IF e.obj = eCONST THEN
2486
                    IF e.obj = eCONST THEN
2409
                        CODE.Float(ARITH.Float(e.value));
2487
                        IL.Float(ARITH.Float(e.value));
2410
                        CODE.fcmp(CODE.opEQF + cmpcode(op) + 6)
2488
                        IL.fcmp(IL.opEQF + invcmpcode(op))
2411
                    ELSIF e1.obj = eCONST THEN
2489
                    ELSIF e1.obj = eCONST THEN
2412
                        CODE.Float(ARITH.Float(e1.value));
2490
                        IL.Float(ARITH.Float(e1.value));
2413
                        CODE.fcmp(CODE.opEQF + cmpcode(op))
2491
                        IL.fcmp(IL.opEQF + cmpcode(op))
Line 2414... Line 2492...
2414
                    ELSE
2492
                    ELSE
2415
                        CODE.fcmp(CODE.opEQF + cmpcode(op))
2493
                        IL.fcmp(IL.opEQF + cmpcode(op))
2416
                    END
2494
                    END
2417
                END
2495
                END
Line 2418... Line 2496...
2418
 
2496
 
2419
            ELSIF (isStringW(e) OR isCharArrayX(e)) & (isStringW(e1) OR isCharArrayX(e1)) THEN
2497
            ELSIF (isStringW(e) OR isCharArrayX(e)) & (isStringW(e1) OR isCharArrayX(e1)) THEN
2420
                IF ~strcmp(e, e1, op) THEN
2498
                IF ~strcmp(e, e1, op) THEN
Line 2421... Line 2499...
2421
                    PARS.error(parser, pos, 37)
2499
                    PARS.error(pos, 37)
2422
                END
2500
                END
2423
 
2501
 
2424
            ELSE
2502
            ELSE
2425
                PARS.error(parser, pos, 37)
2503
                PARS.error(pos, 37)
2426
            END
2504
            END
2427
 
2505
 
2428
        |SCAN.lxIN:
2506
        |SCAN.lxIN:
2429
            PARS.check(isInt(e) & isSet(e1), parser, pos, 37);
2507
            PARS.check(isInt(e) & isSet(e1), pos, 37);
2430
            IF e.obj = eCONST THEN
2508
            IF e.obj = eCONST THEN
2431
                PARS.check(ARITH.range(e.value, 0, MACHINE.target.maxSet), parser, pos0, 56)
2509
                PARS.check(ARITH.range(e.value, 0, UTILS.target.maxSet), pos0, 56)
2432
            END;
2510
            END;
2433
            IF constant THEN
2511
            IF constant THEN
2434
                ARITH.relation(e.value, e1.value, operator, error)
2512
                ARITH.relation(e.value, e1.value, operator, error)
2435
            ELSE
2513
            ELSE
2436
                IF e.obj = eCONST THEN
2514
                IF e.obj = eCONST THEN
Line 2437... Line 2515...
2437
                    CODE.AddCmd(CODE.opINL, ARITH.Int(e.value))
2515
                    IL.AddCmd(IL.opINL, ARITH.Int(e.value))
2438
                ELSIF e1.obj = eCONST THEN
-
 
2439
                    CODE.AddCmd(CODE.opINR, ARITH.Int(e1.value))
-
 
2440
                ELSE
2516
                ELSIF e1.obj = eCONST THEN
2441
                    CODE.AddCmd0(CODE.opIN)
-
 
2442
                END
2517
                    IL.AddCmd(IL.opINR, ARITH.Int(e1.value))
Line 2443... Line 2518...
2443
            END
2518
                ELSE
-
 
2519
                    IL.AddCmd0(IL.opIN)
2444
 
2520
                END
2445
        |SCAN.lxIS:
2521
            END
2446
            PARS.check(isExpr(e) & (e.type.typ IN {PROG.tRECORD, PROG.tPOINTER}), parser, pos, 73);
2522
 
2447
            IF e.type.typ = PROG.tRECORD THEN
2523
        |SCAN.lxIS:
2448
                PARS.check(e.obj = eVREC, parser, pos0, 78)
2524
            PARS.check(isRecPtr(e), pos, 73);
2449
            END;
2525
            PARS.check(e1.obj = eTYPE, pos1, 79);
2450
            PARS.check(e1.obj = eTYPE, parser, pos1, 79);
2526
 
2451
 
2527
            IF isRec(e) THEN
2452
            IF e.type.typ = PROG.tRECORD THEN
2528
                PARS.check(e.obj = eVREC, pos0, 78);
2453
                PARS.check(e1.type.typ = PROG.tRECORD,  parser, pos1, 80);
2529
                PARS.check(e1.type.typ = PROG.tRECORD, pos1, 80);
2454
                IF e.ident = NIL THEN
2530
                IF e.ident = NIL THEN
Line 2455... Line 2531...
2455
                    CODE.TypeCheck(e1.type.num)
2531
                    IL.TypeCheck(e1.type.num)
Line 2456... Line 2532...
2456
                ELSE
2532
                ELSE
Line 2457... Line 2533...
2457
                    CODE.AddCmd(CODE.opVADR, e.ident.offset - 1);
2533
                    IL.AddCmd(IL.opVADR, e.ident.offset - 1);
Line 2458... Line 2534...
2458
                    CODE.TypeCheckRec(e1.type.num)
2534
                    IL.TypeCheckRec(e1.type.num)
Line 2459... Line 2535...
2459
                END
2535
                END
2460
            ELSE
2536
            ELSE
2461
                PARS.check(e1.type.typ = PROG.tPOINTER, parser, pos1, 81);
2537
                PARS.check(e1.type.typ = PROG.tPOINTER, pos1, 81);
Line 2479... Line 2555...
2479
 
2555
 
2480
 
2556
 
2481
PROCEDURE ElementaryStatement (parser: PARS.PARSER);
2557
PROCEDURE ElementaryStatement (parser: PARS.PARSER);
2482
VAR
2558
VAR
2483
    e, e1:    PARS.EXPR;
2559
    e, e1:    PARS.EXPR;
2484
    pos:      SCAN.POSITION;
2560
    pos:      PARS.POSITION;
2485
    line:     INTEGER;
2561
    line:     INTEGER;
Line 2486... Line 2562...
2486
    call:     BOOLEAN;
2562
    call:     BOOLEAN;
2487
    fregs:    INTEGER;
2563
    fregs:    INTEGER;
Line 2488... Line 2564...
2488
 
2564
 
Line 2489... Line 2565...
2489
BEGIN
2565
BEGIN
Line 2490... Line 2566...
2490
    getpos(parser, pos);
2566
    getpos(parser, pos);
2491
 
2567
 
2492
    CODE.pushBegEnd(begcall, endcall);
2568
    IL.pushBegEnd(begcall, endcall);
2493
 
2569
 
Line 2494... Line 2570...
2494
    designator(parser, e);
2570
    designator(parser, e);
Line 2495... Line 2571...
2495
 
2571
 
2496
    IF parser.sym = SCAN.lxASSIGN THEN
2572
    IF parser.sym = SCAN.lxASSIGN THEN
Line 2497... Line 2573...
2497
        line := parser.lex.pos.line;
2573
        line := parser.lex.pos.line;
Line 2498... Line 2574...
2498
        PARS.check(isVar(e), parser, pos, 93);
2574
        PARS.check(isVar(e), pos, 93);
2499
        PARS.check(~e.readOnly, parser, pos, 94);
2575
        PARS.check(~e.readOnly, pos, 94);
2500
 
2576
 
2501
        CODE.setlast(begcall);
2577
        IL.setlast(begcall);
2502
 
2578
 
2503
        NextPos(parser, pos);
2579
        NextPos(parser, pos);
2504
        expression(parser, e1);
2580
        expression(parser, e1);
2505
 
2581
 
2506
        CODE.setlast(endcall.prev(CODE.COMMAND));
2582
        IL.setlast(endcall.prev(IL.COMMAND));
2507
 
2583
 
2508
        PARS.check(assign(e1, e.type, line), parser, pos, 91);
2584
        PARS.check(assign(e1, e.type, line), pos, 91);
2509
        IF e1.obj = ePROC THEN
2585
        IF e1.obj = ePROC THEN
2510
            PARS.check(e1.ident.global, parser, pos, 85)
2586
            PARS.check(e1.ident.global, pos, 85)
-
 
2587
        END;
-
 
2588
        call := FALSE
-
 
2589
    ELSIF parser.sym = SCAN.lxEQ THEN
-
 
2590
        PARS.check1(FALSE, parser, 96)
2511
        END;
2591
    ELSIF parser.sym = SCAN.lxLROUND THEN
2512
        call := FALSE
2592
        e1 := e;
2513
    ELSIF parser.sym = SCAN.lxEQ THEN
2593
        ActualParameters(parser, e1);
2514
        PARS.check1(FALSE, parser, 96)
2594
        PARS.check((e1.type = NIL) OR ODD(e.type.call), pos, 92);
-
 
2595
        call := TRUE
2515
    ELSIF parser.sym = SCAN.lxLROUND THEN
2596
    ELSE
Line 2516... Line 2597...
2516
        e1 := e;
2597
        IF e.obj IN {eSYSPROC, eSTPROC} THEN
2517
        ActualParameters(parser, e1);
2598
            stProc(parser, e);
2518
        PARS.check((e1.type = NIL) OR ODD(e.type.call), parser, pos, 92);
2599
            call := FALSE
2519
        call := TRUE
2600
        ELSE
2520
    ELSE
2601
            PARS.check(isProc(e), pos, 86);
2521
        PARS.check(isProc(e), parser, pos, 86);
2602
            PARS.check((e.type.base = NIL) OR ODD(e.type.call), pos, 92);
2522
        PARS.check((e.type.base = NIL) OR ODD(e.type.call), parser, pos, 92);
2603
            PARS.check1(e.type.params.first = NIL, parser, 64);
Line 2523... Line 2604...
2523
        PARS.check1(e.type.params.first = NIL, parser, 64);
2604
            call := TRUE
2524
        call := TRUE
2605
        END
Line 2525... Line 2606...
2525
    END;
2606
    END;
2526
 
2607
 
2527
    IF call THEN
2608
    IF call THEN
2528
        IF e.obj IN {ePROC, eIMP} THEN
2609
        IF e.obj IN {ePROC, eIMP} THEN
Line 2529... Line 2610...
2529
            ProcCall(e, e.ident.type, FALSE, fregs, parser, pos, TRUE)
2610
            ProcCall(e, e.ident.type, FALSE, fregs, parser, pos, TRUE)
Line 2530... Line 2611...
2530
        ELSIF isExpr(e) THEN
2611
        ELSIF isExpr(e) THEN
2531
            ProcCall(e, e.type, FALSE, fregs, parser, pos, TRUE)
2612
            ProcCall(e, e.type, FALSE, fregs, parser, pos, TRUE)
Line 2532... Line 2613...
2532
        END
2613
        END
2533
    END;
2614
    END;
2534
 
2615
 
2535
    CODE.popBegEnd(begcall, endcall)
2616
    IL.popBegEnd(begcall, endcall)
Line 2536... Line 2617...
2536
END ElementaryStatement;
2617
END ElementaryStatement;
2537
 
2618
 
Line 2538... Line 2619...
2538
 
2619
 
Line 2539... Line 2620...
2539
PROCEDURE IfStatement (parser: PARS.PARSER; if: BOOLEAN);
2620
PROCEDURE IfStatement (parser: PARS.PARSER; if: BOOLEAN);
2540
VAR
2621
VAR
Line 2541... Line 2622...
2541
    e:     PARS.EXPR;
2622
    e:     PARS.EXPR;
2542
    pos:   SCAN.POSITION;
2623
    pos:   PARS.POSITION;
2543
 
2624
 
2544
    label, L: INTEGER;
2625
    label, L: INTEGER;
2545
 
2626
 
2546
BEGIN
2627
BEGIN
2547
    L := CODE.NewLabel();
2628
    L := IL.NewLabel();
Line 2548... Line 2629...
2548
 
2629
 
2549
    IF ~if THEN
2630
    IF ~if THEN
2550
        CODE.AddCmd0(CODE.opLOOP);
2631
        IL.AddCmd0(IL.opLOOP);
Line 2574... Line 2655...
2574
        END;
2655
        END;
Line 2575... Line 2656...
2575
 
2656
 
2576
        PARS.Next(parser);
2657
        PARS.Next(parser);
Line 2577... Line 2658...
2577
        parser.StatSeq(parser);
2658
        parser.StatSeq(parser);
2578
 
2659
 
Line 2579... Line 2660...
2579
        CODE.AddJmpCmd(CODE.opJMP, L);
2660
        IL.AddJmpCmd(IL.opJMP, L);
Line 2580... Line 2661...
2580
        CODE.SetLabel(label)
2661
        IL.SetLabel(label)
2581
 
2662
 
2582
    UNTIL parser.sym # SCAN.lxELSIF;
2663
    UNTIL parser.sym # SCAN.lxELSIF;
2583
 
2664
 
2584
    IF if THEN
2665
    IF if THEN
2585
        IF parser.sym = SCAN.lxELSE THEN
2666
        IF parser.sym = SCAN.lxELSE THEN
2586
            PARS.Next(parser);
2667
            PARS.Next(parser);
Line 2587... Line 2668...
2587
            parser.StatSeq(parser)
2668
            parser.StatSeq(parser)
Line 2588... Line 2669...
2588
        END;
2669
        END;
2589
        CODE.SetLabel(L)
2670
        IL.SetLabel(L)
2590
    END;
2671
    END;
Line 2591... Line 2672...
2591
 
2672
 
2592
    PARS.checklex(parser, SCAN.lxEND);
2673
    PARS.checklex(parser, SCAN.lxEND);
Line 2593... Line 2674...
2593
 
2674
 
2594
    IF ~if THEN
2675
    IF ~if THEN
2595
        CODE.AddCmd0(CODE.opENDLOOP)
2676
        IL.AddCmd0(IL.opENDLOOP)
2596
    END;
2677
    END;
2597
 
2678
 
Line 2598... Line 2679...
2598
    PARS.Next(parser)
2679
    PARS.Next(parser)
2599
END IfStatement;
2680
END IfStatement;
Line 2600... Line 2681...
2600
 
2681
 
2601
 
2682
 
Line 2602... Line 2683...
2602
PROCEDURE RepeatStatement (parser: PARS.PARSER);
2683
PROCEDURE RepeatStatement (parser: PARS.PARSER);
2603
VAR
2684
VAR
2604
    e:     PARS.EXPR;
2685
    e:     PARS.EXPR;
2605
    pos:   SCAN.POSITION;
2686
    pos:   PARS.POSITION;
2606
    label: INTEGER;
2687
    label: INTEGER;
2607
 
2688
 
Line 2608... Line 2689...
2608
BEGIN
2689
BEGIN
2609
    CODE.AddCmd0(CODE.opLOOP);
2690
    IL.AddCmd0(IL.opLOOP);
2610
 
2691
 
2611
    label := CODE.NewLabel();
2692
    label := IL.NewLabel();
2612
    CODE.SetLabel(label);
2693
    IL.SetLabel(label);
2613
 
2694
 
2614
    PARS.Next(parser);
2695
    PARS.Next(parser);
Line 2615... Line 2696...
2615
    parser.StatSeq(parser);
2696
    parser.StatSeq(parser);
2616
    PARS.checklex(parser, SCAN.lxUNTIL);
2697
    PARS.checklex(parser, SCAN.lxUNTIL);
Line 2617... Line 2698...
2617
    NextPos(parser, pos);
2698
    NextPos(parser, pos);
2618
    expression(parser, e);
2699
    expression(parser, e);
Line 2654... Line 2735...
2654
    C.push(CaseLabels, label);
2735
    C.push(CaseLabels, label);
2655
    label := NIL
2736
    label := NIL
2656
END DestroyLabel;
2737
END DestroyLabel;
Line 2657... Line 2738...
2657
 
2738
 
2658
 
2739
 
2659
PROCEDURE NewVariant (label: INTEGER; cmd: CODE.COMMAND): CASE_VARIANT;
2740
PROCEDURE NewVariant (label: INTEGER; cmd: IL.COMMAND): CASE_VARIANT;
2660
VAR
2741
VAR
Line 2661... Line 2742...
2661
    res:   CASE_VARIANT;
2742
    res:   CASE_VARIANT;
Line 2678... Line 2759...
2678
 
2759
 
2679
 
2760
 
2680
PROCEDURE CaseStatement (parser: PARS.PARSER);
2761
PROCEDURE CaseStatement (parser: PARS.PARSER);
2681
VAR
2762
VAR
2682
    e:      PARS.EXPR;
-
 
2683
    pos:    SCAN.POSITION;
-
 
2684
 
-
 
2685
 
-
 
2686
    PROCEDURE isRecPtr (caseExpr: PARS.EXPR): BOOLEAN;
-
 
Line 2687... Line 2763...
2687
        RETURN isRec(caseExpr) OR isPtr(caseExpr)
2763
    e:      PARS.EXPR;
2688
    END isRecPtr;
2764
    pos:    PARS.POSITION;
2689
 
2765
 
2690
 
2766
 
2691
    PROCEDURE Label (parser: PARS.PARSER; caseExpr: PARS.EXPR; VAR type: PROG.TYPE_): INTEGER;
2767
    PROCEDURE Label (parser: PARS.PARSER; caseExpr: PARS.EXPR; VAR type: PROG.TYPE_): INTEGER;
2692
    VAR
2768
    VAR
Line 2693... Line 2769...
2693
        a:      INTEGER;
2769
        a:      INTEGER;
2694
        label:  PARS.EXPR;
2770
        label:  PARS.EXPR;
2695
        pos:    SCAN.POSITION;
2771
        pos:    PARS.POSITION;
Line 2696... Line 2772...
2696
        value:  ARITH.VALUE;
2772
        value:  ARITH.VALUE;
2697
 
2773
 
2698
    BEGIN
2774
    BEGIN
2699
        getpos(parser, pos);
2775
        getpos(parser, pos);
2700
        type := NIL;
2776
        type := NIL;
2701
 
2777
 
2702
        IF isChar(caseExpr) THEN
2778
        IF isChar(caseExpr) THEN
2703
            PARS.ConstExpression(parser, value);
2779
            PARS.ConstExpression(parser, value);
2704
            PARS.check(value.typ = ARITH.tCHAR, parser, pos, 99);
2780
            PARS.check(value.typ = ARITH.tCHAR, pos, 99);
2705
            a := ARITH.getInt(value)
2781
            a := ARITH.getInt(value)
2706
        ELSIF isCharW(caseExpr) THEN
2782
        ELSIF isCharW(caseExpr) THEN
2707
            PARS.ConstExpression(parser, value);
2783
            PARS.ConstExpression(parser, value);
2708
            IF (value.typ = ARITH.tSTRING) & (_length(value.string(SCAN.IDENT).s) = 1) & (LENGTH(value.string(SCAN.IDENT).s) > 1) THEN
2784
            IF (value.typ = ARITH.tSTRING) & (_length(value.string(SCAN.IDENT).s) = 1) & (LENGTH(value.string(SCAN.IDENT).s) > 1) THEN
2709
                ASSERT(ARITH.setInt(value, StrToWChar(value.string(SCAN.IDENT).s)))
2785
                ASSERT(ARITH.setInt(value, StrToWChar(value.string(SCAN.IDENT).s)))
2710
            ELSE
2786
            ELSE
2711
                PARS.check(value.typ IN {ARITH.tWCHAR, ARITH.tCHAR}, parser, pos, 99)
2787
                PARS.check(value.typ IN {ARITH.tWCHAR, ARITH.tCHAR}, pos, 99)
2712
            END;
2788
            END;
2713
            a := ARITH.getInt(value)
2789
            a := ARITH.getInt(value)
2714
        ELSIF isInt(caseExpr) THEN
2790
        ELSIF isInt(caseExpr) THEN
2715
            PARS.ConstExpression(parser, value);
2791
            PARS.ConstExpression(parser, value);
2716
            PARS.check(value.typ = ARITH.tINTEGER, parser, pos, 99);
2792
            PARS.check(value.typ = ARITH.tINTEGER, pos, 99);
2717
            a := ARITH.getInt(value)
2793
            a := ARITH.getInt(value)
2718
        ELSIF isRecPtr(caseExpr) THEN
2794
        ELSIF isRecPtr(caseExpr) THEN
2719
            qualident(parser, label);
2795
            qualident(parser, label);
2720
            PARS.check(label.obj = eTYPE, parser, pos, 79);
2796
            PARS.check(label.obj = eTYPE, pos, 79);
Line 2729... Line 2805...
2729
 
2805
 
2730
        RETURN a
2806
        RETURN a
Line 2731... Line 2807...
2731
    END Label;
2807
    END Label;
2732
 
2808
 
2733
 
2809
 
2734
    PROCEDURE CheckType (node: AVL.NODE; type: PROG.TYPE_; parser: PARS.PARSER; pos: SCAN.POSITION);
2810
    PROCEDURE CheckType (node: AVL.NODE; type: PROG.TYPE_; parser: PARS.PARSER; pos: PARS.POSITION);
2735
    BEGIN
2811
    BEGIN
2736
        IF node # NIL THEN
2812
        IF node # NIL THEN
2737
            PARS.check(~(PROG.isBaseOf(node.data(CASE_LABEL).type, type) OR PROG.isBaseOf(type, node.data(CASE_LABEL).type)), parser, pos, 100);
2813
            PARS.check(~(PROG.isBaseOf(node.data(CASE_LABEL).type, type) OR PROG.isBaseOf(type, node.data(CASE_LABEL).type)), pos, 100);
2738
            CheckType(node.left, type, parser, pos);
2814
            CheckType(node.left, type, parser, pos);
Line 2739... Line 2815...
2739
            CheckType(node.right, type, parser, pos)
2815
            CheckType(node.right, type, parser, pos)
2740
        END
2816
        END
2741
    END CheckType;
2817
    END CheckType;
2742
 
2818
 
2743
 
2819
 
2744
    PROCEDURE LabelRange (parser: PARS.PARSER; caseExpr: PARS.EXPR; VAR tree: AVL.NODE; variant: INTEGER): AVL.NODE;
2820
    PROCEDURE LabelRange (parser: PARS.PARSER; caseExpr: PARS.EXPR; VAR tree: AVL.NODE; variant: INTEGER): AVL.NODE;
2745
    VAR
2821
    VAR
2746
        label:     CASE_LABEL;
2822
        label:     CASE_LABEL;
Line 2747... Line 2823...
2747
        citem:     C.ITEM;
2823
        citem:     C.ITEM;
Line 2757... Line 2833...
2757
        ELSE
2833
        ELSE
2758
            label := citem(CASE_LABEL)
2834
            label := citem(CASE_LABEL)
2759
        END;
2835
        END;
Line 2760... Line 2836...
2760
 
2836
 
2761
        label.variant := variant;
2837
        label.variant := variant;
Line 2762... Line 2838...
2762
        label.self := CODE.NewLabel();
2838
        label.self := IL.NewLabel();
2763
 
2839
 
Line 2764... Line 2840...
2764
        getpos(parser, pos1);
2840
        getpos(parser, pos1);
2765
        range.a := Label(parser, caseExpr, label.type);
2841
        range.a := Label(parser, caseExpr, label.type);
2766
 
2842
 
2767
        IF parser.sym = SCAN.lxRANGE THEN
2843
        IF parser.sym = SCAN.lxRANGE THEN
2768
            PARS.check1(~isRecPtr(caseExpr), parser, 53);
2844
            PARS.check1(~isRecPtr(caseExpr), parser, 53);
2769
            NextPos(parser, pos);
2845
            NextPos(parser, pos);
2770
            range.b := Label(parser, caseExpr, label.type);
2846
            range.b := Label(parser, caseExpr, label.type);
2771
            PARS.check(range.a <= range.b, parser, pos, 103)
2847
            PARS.check(range.a <= range.b, pos, 103)
Line 2772... Line 2848...
2772
        ELSE
2848
        ELSE
Line 2773... Line 2849...
2773
            range.b := range.a
2849
            range.b := range.a
2774
        END;
2850
        END;
2775
 
2851
 
2776
        label.range := range;
2852
        label.range := range;
2777
 
2853
 
Line 2778... Line 2854...
2778
        IF isRecPtr(caseExpr) THEN
2854
        IF isRecPtr(caseExpr) THEN
Line 2779... Line 2855...
2779
            CheckType(tree, label.type, parser, pos1)
2855
            CheckType(tree, label.type, parser, pos1)
Line 2811... Line 2887...
2811
    VAR
2887
    VAR
2812
        sym:      INTEGER;
2888
        sym:      INTEGER;
2813
        t:        PROG.TYPE_;
2889
        t:        PROG.TYPE_;
2814
        variant:  INTEGER;
2890
        variant:  INTEGER;
2815
        node:     AVL.NODE;
2891
        node:     AVL.NODE;
2816
        last:     CODE.COMMAND;
2892
        last:     IL.COMMAND;
Line 2817... Line 2893...
2817
 
2893
 
2818
    BEGIN
2894
    BEGIN
2819
        sym := parser.sym;
2895
        sym := parser.sym;
2820
        IF sym # SCAN.lxBAR THEN
2896
        IF sym # SCAN.lxBAR THEN
2821
            variant := CODE.NewLabel();
2897
            variant := IL.NewLabel();
2822
            node := CaseLabelList(parser, caseExpr, tree, variant);
2898
            node := CaseLabelList(parser, caseExpr, tree, variant);
2823
            PARS.checklex(parser, SCAN.lxCOLON);
2899
            PARS.checklex(parser, SCAN.lxCOLON);
2824
            PARS.Next(parser);
2900
            PARS.Next(parser);
2825
            IF isRecPtr(caseExpr) THEN
2901
            IF isRecPtr(caseExpr) THEN
2826
                t := caseExpr.type;
2902
                t := caseExpr.type;
2827
                caseExpr.ident.type := node.data(CASE_LABEL).type
2903
                caseExpr.ident.type := node.data(CASE_LABEL).type
Line 2828... Line 2904...
2828
            END;
2904
            END;
2829
 
2905
 
Line 2830... Line 2906...
2830
            last := CODE.getlast();
2906
            last := IL.getlast();
2831
            CODE.SetLabel(variant);
2907
            IL.SetLabel(variant);
2832
 
2908
 
Line 2833... Line 2909...
2833
            IF ~isRecPtr(caseExpr) THEN
2909
            IF ~isRecPtr(caseExpr) THEN
2834
                LISTS.push(CaseVariants, NewVariant(variant, last))
2910
                LISTS.push(CaseVariants, NewVariant(variant, last))
Line 2835... Line 2911...
2835
            END;
2911
            END;
2836
 
2912
 
2837
            parser.StatSeq(parser);
2913
            parser.StatSeq(parser);
2838
            CODE.AddJmpCmd(CODE.opJMP, end);
2914
            IL.AddJmpCmd(IL.opJMP, end);
Line 2847... Line 2923...
2847
    PROCEDURE Table (node: AVL.NODE; else: INTEGER);
2923
    PROCEDURE Table (node: AVL.NODE; else: INTEGER);
2848
    VAR
2924
    VAR
2849
        L, R: INTEGER;
2925
        L, R: INTEGER;
2850
        range: RANGE;
2926
        range: RANGE;
2851
        left, right: AVL.NODE;
2927
        left, right: AVL.NODE;
2852
        last: CODE.COMMAND;
2928
        last: IL.COMMAND;
2853
        v: CASE_VARIANT;
2929
        v: CASE_VARIANT;
Line 2854... Line 2930...
2854
 
2930
 
2855
    BEGIN
2931
    BEGIN
Line 2869... Line 2945...
2869
                R := right.data(CASE_LABEL).self
2945
                R := right.data(CASE_LABEL).self
2870
            ELSE
2946
            ELSE
2871
                R := else
2947
                R := else
2872
            END;
2948
            END;
Line 2873... Line 2949...
2873
 
2949
 
Line 2874... Line 2950...
2874
            last := CODE.getlast();
2950
            last := IL.getlast();
2875
 
2951
 
2876
            v := CaseVariants.last(CASE_VARIANT);
2952
            v := CaseVariants.last(CASE_VARIANT);
2877
            WHILE (v # NIL) & (v.label # 0) & (v.label # node.data(CASE_LABEL).variant) DO
2953
            WHILE (v # NIL) & (v.label # 0) & (v.label # node.data(CASE_LABEL).variant) DO
Line 2878... Line 2954...
2878
                v := v.prev(CASE_VARIANT)
2954
                v := v.prev(CASE_VARIANT)
2879
            END;
2955
            END;
Line 2880... Line 2956...
2880
 
2956
 
2881
            ASSERT((v # NIL) & (v.label # 0));
2957
            ASSERT((v # NIL) & (v.label # 0));
2882
            CODE.setlast(v.cmd);
2958
            IL.setlast(v.cmd);
2883
 
2959
 
2884
            CODE.SetLabel(node.data(CASE_LABEL).self);
2960
            IL.SetLabel(node.data(CASE_LABEL).self);
2885
            CODE.case(range.a, range.b, L, R);
2961
            IL.case(range.a, range.b, L, R);
Line 2886... Line 2962...
2886
            IF v.processed THEN
2962
            IF v.processed THEN
Line 2887... Line 2963...
2887
                CODE.AddJmpCmd(CODE.opJMP, node.data(CASE_LABEL).variant)
2963
                IL.AddJmpCmd(IL.opJMP, node.data(CASE_LABEL).variant)
2888
            END;
2964
            END;
2889
            v.processed := TRUE;
2965
            v.processed := TRUE;
2890
 
2966
 
Line 2891... Line 2967...
2891
            CODE.setlast(last);
2967
            IL.setlast(last);
2892
 
2968
 
2893
            Table(left, else);
2969
            Table(left, else);
2894
            Table(right, else)
2970
            Table(right, else)
Line 2895... Line 2971...
2895
        END
2971
        END
2896
    END Table;
2972
    END Table;
2897
 
2973
 
2898
 
2974
 
Line 2899... Line 2975...
2899
    PROCEDURE TableT (node: AVL.NODE);
2975
    PROCEDURE TableT (node: AVL.NODE);
2900
    BEGIN
2976
    BEGIN
2901
        IF node # NIL THEN
2977
        IF node # NIL THEN
2902
            CODE.caset(node.data(CASE_LABEL).range.a, node.data(CASE_LABEL).variant);
2978
            IL.caset(node.data(CASE_LABEL).range.a, node.data(CASE_LABEL).variant);
2903
 
2979
 
Line 2904... Line 2980...
2904
            TableT(node.left);
2980
            TableT(node.left);
2905
            TableT(node.right)
2981
            TableT(node.right)
2906
        END
2982
        END
2907
    END TableT;
2983
    END TableT;
2908
 
2984
 
2909
 
2985
 
2910
    PROCEDURE ParseCase (parser: PARS.PARSER; e: PARS.EXPR; pos: SCAN.POSITION);
2986
    PROCEDURE ParseCase (parser: PARS.PARSER; e: PARS.EXPR; pos: PARS.POSITION);
Line 2911... Line 2987...
2911
    VAR
2987
    VAR
Line 2912... Line 2988...
2912
        table, end, else: INTEGER;
2988
        table, end, else: INTEGER;
2913
        tree: AVL.NODE;
2989
        tree: AVL.NODE;
2914
        item:  LISTS.ITEM;
2990
        item:  LISTS.ITEM;
2915
 
2991
 
2916
    BEGIN
2992
    BEGIN
Line 2917... Line 2993...
2917
        LISTS.push(CaseVariants, NewVariant(0, NIL));
2993
        LISTS.push(CaseVariants, NewVariant(0, NIL));
2918
        end   := CODE.NewLabel();
2994
        end   := IL.NewLabel();
2919
        else  := CODE.NewLabel();
2995
        else  := IL.NewLabel();
2920
        table := CODE.NewLabel();
2996
        table := IL.NewLabel();
2921
        CODE.AddCmd(CODE.opSWITCH, ORD(isRecPtr(e)));
2997
        IL.AddCmd(IL.opSWITCH, ORD(isRecPtr(e)));
2922
        CODE.AddJmpCmd(CODE.opJMP, table);
2998
        IL.AddJmpCmd(IL.opJMP, table);
2923
 
2999
 
2924
        tree := NIL;
3000
        tree := NIL;
Line 2925... Line 3001...
2925
 
3001
 
2926
        case(parser, e, tree, end);
3002
        case(parser, e, tree, end);
Line 2927... Line 3003...
2927
        WHILE parser.sym = SCAN.lxBAR DO
3003
        WHILE parser.sym = SCAN.lxBAR DO
2928
            PARS.Next(parser);
3004
            PARS.Next(parser);
2929
            case(parser, e, tree, end)
3005
            case(parser, e, tree, end)
2930
        END;
3006
        END;
2931
 
3007
 
2932
        CODE.SetLabel(else);
3008
        IL.SetLabel(else);
2933
        IF parser.sym = SCAN.lxELSE THEN
3009
        IF parser.sym = SCAN.lxELSE THEN
2934
            PARS.Next(parser);
3010
            PARS.Next(parser);
Line 2935... Line 3011...
2935
            parser.StatSeq(parser);
3011
            parser.StatSeq(parser);
2936
            CODE.AddJmpCmd(CODE.opJMP, end)
3012
            IL.AddJmpCmd(IL.opJMP, end)
2937
        ELSE
3013
        ELSE
Line 2938... Line 3014...
2938
            CODE.OnError(pos.line, errCASE)
3014
            IL.OnError(pos.line, errCASE)
2939
        END;
3015
        END;
2940
 
3016
 
2941
        PARS.checklex(parser, SCAN.lxEND);
3017
        PARS.checklex(parser, SCAN.lxEND);
Line 2963... Line 3039...
2963
 
3039
 
2964
 
3040
 
2965
BEGIN
3041
BEGIN
2966
    NextPos(parser, pos);
3042
    NextPos(parser, pos);
2967
    expression(parser, e);
3043
    expression(parser, e);
2968
    PARS.check(isInt(e) OR isChar(e) OR isCharW(e) OR isPtr(e) OR isRec(e), parser, pos, 95);
3044
    PARS.check(isInt(e) OR isChar(e) OR isCharW(e) OR isPtr(e) OR isRec(e), pos, 95);
2969
    IF isRecPtr(e) THEN
3045
    IF isRecPtr(e) THEN
2970
        PARS.check(isVar(e), parser, pos, 93);
3046
        PARS.check(isVar(e), pos, 93);
2971
        PARS.check(e.ident # NIL, parser, pos, 106)
3047
        PARS.check(e.ident # NIL, pos, 106)
2972
    END;
3048
    END;
2973
    IF isRec(e) THEN
3049
    IF isRec(e) THEN
Line 2974... Line 3050...
2974
        PARS.check(e.obj = eVREC, parser, pos, 78)
3050
        PARS.check(e.obj = eVREC, pos, 78)
2975
    END;
3051
    END;
2976
 
3052
 
2977
    IF e.obj = eCONST THEN
3053
    IF e.obj = eCONST THEN
2978
        LoadConst(e)
3054
        LoadConst(e)
2979
    ELSIF isRec(e) THEN
3055
    ELSIF isRec(e) THEN
2980
        CODE.drop;
3056
        IL.drop;
2981
        CODE.AddCmd(CODE.opLADR, e.ident.offset - 1);
3057
        IL.AddCmd(IL.opLADR, e.ident.offset - 1);
2982
        CODE.load(PARS.program.target.word)
3058
        IL.load(PARS.program.target.word)
2983
    ELSIF isPtr(e) THEN
3059
    ELSIF isPtr(e) THEN
2984
        deref(pos, e, FALSE, errPTR);
3060
        deref(pos, e, FALSE, errPTR);
Line 2985... Line 3061...
2985
        CODE.AddCmd(CODE.opSUBR, PARS.program.target.word);
3061
        IL.AddCmd(IL.opSUBR, PARS.program.target.word);
2986
        CODE.load(PARS.program.target.word)
3062
        IL.load(PARS.program.target.word)
2987
    END;
3063
    END;
Line 2993... Line 3069...
2993
 
3069
 
2994
 
3070
 
2995
PROCEDURE ForStatement (parser: PARS.PARSER);
3071
PROCEDURE ForStatement (parser: PARS.PARSER);
2996
VAR
3072
VAR
2997
    e:       PARS.EXPR;
3073
    e:         PARS.EXPR;
2998
    pos:     SCAN.POSITION;
3074
    pos, pos2: PARS.POSITION;
2999
    step:    ARITH.VALUE;
3075
    step:      ARITH.VALUE;
3000
    st:      INTEGER;
3076
    st:        INTEGER;
3001
    ident:   PROG.IDENT;
3077
    ident:     PROG.IDENT;
Line 3002... Line 3078...
3002
    offset:  INTEGER;
3078
    offset:    INTEGER;
3003
    L1, L2:  INTEGER;
3079
    L1, L2:    INTEGER;
Line 3004... Line 3080...
3004
 
3080
 
3005
BEGIN
3081
BEGIN
Line 3006... Line 3082...
3006
    CODE.AddCmd0(CODE.opLOOP);
3082
    IL.AddCmd0(IL.opLOOP);
3007
 
3083
 
3008
    L1 := CODE.NewLabel();
3084
    L1 := IL.NewLabel();
3009
    L2 := CODE.NewLabel();
3085
    L2 := IL.NewLabel();
3010
 
3086
 
3011
    PARS.ExpectSym(parser, SCAN.lxIDENT);
3087
    PARS.ExpectSym(parser, SCAN.lxIDENT);
3012
    ident := parser.unit.idents.get(parser.unit, parser.lex.ident, TRUE);
3088
    ident := PROG.getIdent(parser.unit, parser.lex.ident, TRUE);
3013
    PARS.check1(ident # NIL, parser, 48);
3089
    PARS.check1(ident # NIL, parser, 48);
3014
    PARS.check1(ident.typ = PROG.idVAR, parser, 93);
3090
    PARS.check1(ident.typ = PROG.idVAR, parser, 93);
Line 3015... Line 3091...
3015
    PARS.check1(ident.type.typ = PROG.tINTEGER, parser, 97);
3091
    PARS.check1(ident.type = tINTEGER, parser, 97);
Line 3016... Line 3092...
3016
    PARS.ExpectSym(parser, SCAN.lxASSIGN);
3092
    PARS.ExpectSym(parser, SCAN.lxASSIGN);
3017
    NextPos(parser, pos);
3093
    NextPos(parser, pos);
3018
    expression(parser, e);
3094
    expression(parser, e);
3019
    PARS.check(isInt(e), parser, pos, 76);
3095
    PARS.check(isInt(e), pos, 76);
3020
 
3096
 
Line 3021... Line 3097...
3021
    offset := PROG.getOffset(PARS.program, ident);
3097
    offset := PROG.getOffset(PARS.program, ident);
3022
 
3098
 
3023
    IF ident.global THEN
3099
    IF ident.global THEN
3024
        CODE.AddCmd(CODE.opGADR, offset)
3100
        IL.AddCmd(IL.opGADR, offset)
3025
    ELSE
3101
    ELSE
Line 3026... Line 3102...
3026
        CODE.AddCmd(CODE.opLADR, -offset)
3102
        IL.AddCmd(IL.opLADR, -offset)
Line 3027... Line 3103...
3027
    END;
3103
    END;
3028
 
3104
 
3029
    IF e.obj = eCONST THEN
3105
    IF e.obj = eCONST THEN
3030
        CODE.AddCmd(CODE.opSAVEC, ARITH.Int(e.value))
3106
        IL.AddCmd(IL.opSAVEC, ARITH.Int(e.value))
3031
    ELSE
3107
    ELSE
3032
        CODE.AddCmd0(CODE.opSAVE)
3108
        IL.AddCmd0(IL.opSAVE)
Line 3033... Line 3109...
3033
    END;
3109
    END;
3034
 
3110
 
3035
    CODE.SetLabel(L1);
3111
    IL.SetLabel(L1);
3036
 
3112
 
Line 3037... Line 3113...
3037
    IF ident.global THEN
3113
    IF ident.global THEN
3038
        CODE.AddCmd(CODE.opGADR, offset)
3114
        IL.AddCmd(IL.opGADR, offset)
3039
    ELSE
3115
    ELSE
3040
        CODE.AddCmd(CODE.opLADR, -offset)
3116
        IL.AddCmd(IL.opLADR, -offset)
3041
    END;
3117
    END;
3042
    CODE.load(ident.type.size);
3118
    IL.load(ident.type.size);
3043
 
3119
 
3044
    PARS.checklex(parser, SCAN.lxTO);
3120
    PARS.checklex(parser, SCAN.lxTO);
3045
    NextPos(parser, pos);
3121
    NextPos(parser, pos2);
Line 3046... Line 3122...
3046
    expression(parser, e);
3122
    expression(parser, e);
3047
    PARS.check(isInt(e), parser, pos, 76);
3123
    PARS.check(isInt(e), pos2, 76);
3048
 
3124
 
-
 
3125
    IF parser.sym = SCAN.lxBY THEN
-
 
3126
        NextPos(parser, pos);
-
 
3127
        PARS.ConstExpression(parser, step);
3049
    IF parser.sym = SCAN.lxBY THEN
3128
        PARS.check(step.typ = ARITH.tINTEGER, pos, 76);
3050
        NextPos(parser, pos);
3129
        st := ARITH.getInt(step);
-
 
3130
        PARS.check(st # 0, pos, 98)
-
 
3131
    ELSE
-
 
3132
        st := 1
3051
        PARS.ConstExpression(parser, step);
3133
    END;
3052
        PARS.check(step.typ = ARITH.tINTEGER, parser, pos, 76);
3134
 
3053
        st := ARITH.getInt(step);
3135
    IF e.obj = eCONST THEN
3054
        PARS.check(st # 0, parser, pos, 98)
3136
        IF st > 0 THEN
3055
    ELSE
3137
            IL.AddCmd(IL.opLEC, ARITH.Int(e.value));
3056
        st := 1
3138
            IF ARITH.Int(e.value) = UTILS.target.maxInt THEN
3057
    END;
3139
                ERRORS.WarningMsg(pos2.line, pos2.col, 1)
3058
 
3140
            END
Line 3059... Line 3141...
3059
    IF e.obj = eCONST THEN
3141
        ELSE
Line 3060... Line 3142...
3060
        IF st > 0 THEN
3142
            IL.AddCmd(IL.opGEC, ARITH.Int(e.value));
3061
            CODE.AddCmd(CODE.opLER, ARITH.Int(e.value))
3143
            IF ARITH.Int(e.value) = UTILS.target.minInt THEN
3062
        ELSE
3144
                ERRORS.WarningMsg(pos2.line, pos2.col, 1)
Line 3063... Line 3145...
3063
            CODE.AddCmd(CODE.opGER, ARITH.Int(e.value))
3145
            END
3064
        END
3146
        END
3065
    ELSE
3147
    ELSE
3066
        IF st > 0 THEN
3148
        IF st > 0 THEN
3067
            CODE.AddCmd0(CODE.opLE)
3149
            IL.AddCmd0(IL.opLE)
Line 3068... Line -...
3068
        ELSE
-
 
3069
            CODE.AddCmd0(CODE.opGE)
-
 
3070
        END
-
 
3071
    END;
-
 
3072
 
-
 
3073
    CODE.AddJmpCmd(CODE.opJNE, L2);
-
 
3074
 
3150
        ELSE
3075
    PARS.checklex(parser, SCAN.lxDO);
-
 
3076
    PARS.Next(parser);
-
 
3077
    parser.StatSeq(parser);
-
 
3078
 
-
 
Line 3079... Line 3151...
3079
    IF ident.global THEN
3151
            IL.AddCmd0(IL.opGE)
Line 3080... Line 3152...
3080
        CODE.AddCmd(CODE.opGADR, offset)
3152
        END
3081
    ELSE
3153
    END;
Line 3082... Line 3154...
3082
        CODE.AddCmd(CODE.opLADR, -offset)
3154
 
Line 3083... Line 3155...
3083
    END;
3155
    IL.AddJmpCmd(IL.opJNE, L2);
Line 3084... Line 3156...
3084
 
3156
 
Line 3085... Line 3157...
3085
    IF st = 1 THEN
3157
    PARS.checklex(parser, SCAN.lxDO);
Line 3137... Line 3209...
3137
        statement(parser)
3209
        statement(parser)
3138
    END
3210
    END
3139
END StatSeq;
3211
END StatSeq;
Line 3140... Line 3212...
3140
 
3212
 
3141
 
3213
 
3142
PROCEDURE chkreturn (parser: PARS.PARSER; e: PARS.EXPR; t: PROG.TYPE_; pos: SCAN.POSITION): BOOLEAN;
3214
PROCEDURE chkreturn (parser: PARS.PARSER; e: PARS.EXPR; t: PROG.TYPE_; pos: PARS.POSITION): BOOLEAN;
Line 3143... Line 3215...
3143
VAR
3215
VAR
3144
    res: BOOLEAN;
3216
    res: BOOLEAN;
3145
 
3217
 
3146
BEGIN
3218
BEGIN
3147
    res := assigncomp(e, t);
3219
    res := assigncomp(e, t);
3148
    IF res THEN
3220
    IF res THEN
3149
        IF e.obj = eCONST THEN
3221
        IF e.obj = eCONST THEN
3150
            IF e.type.typ = PROG.tREAL THEN
3222
            IF e.type = tREAL THEN
3151
                CODE.Float(ARITH.Float(e.value))
3223
                IL.Float(ARITH.Float(e.value))
3152
            ELSIF e.type.typ = PROG.tNIL THEN
3224
            ELSIF e.type.typ = PROG.tNIL THEN
3153
                CODE.AddCmd(CODE.opCONST, 0)
3225
                IL.Const(0)
3154
            ELSE
3226
            ELSE
3155
                LoadConst(e)
3227
                LoadConst(e)
3156
            END
3228
            END
3157
        ELSIF (e.type.typ = PROG.tINTEGER) & (t.typ = PROG.tBYTE) & (chkBYTE IN checking) THEN
3229
        ELSIF (e.type = tINTEGER) & (t = tBYTE) & (chkBYTE IN Options.checking) THEN
3158
            CheckRange(256, pos.line, errBYTE)
3230
            CheckRange(256, pos.line, errBYTE)
3159
        ELSIF e.obj = ePROC THEN
3231
        ELSIF e.obj = ePROC THEN
3160
            PARS.check(e.ident.global, parser, pos, 85);
3232
            PARS.check(e.ident.global, pos, 85);
3161
            CODE.PushProc(e.ident.proc.label)
3233
            IL.PushProc(e.ident.proc.label)
Line 3162... Line 3234...
3162
        ELSIF e.obj = eIMP THEN
3234
        ELSIF e.obj = eIMP THEN
3163
            CODE.PushImpProc(e.ident.import)
3235
            IL.PushImpProc(e.ident.import)
3164
        END;
3236
        END;
3165
 
3237
 
Line 3166... Line 3238...
3166
        IF e.type.typ = PROG.tREAL THEN
3238
        IF e.type = tREAL THEN
3167
            CODE.retf
3239
            IL.retf
Line 3180... Line 3252...
3180
    PROCEDURE getproc (rtl: PROG.UNIT; name: SCAN.LEXSTR; idx: INTEGER);
3252
    PROCEDURE getproc (rtl: PROG.UNIT; name: SCAN.LEXSTR; idx: INTEGER);
3181
    VAR
3253
    VAR
3182
        id:    PROG.IDENT;
3254
        id:    PROG.IDENT;
Line 3183... Line 3255...
3183
 
3255
 
3184
    BEGIN
3256
    BEGIN
Line 3185... Line 3257...
3185
        id := rtl.idents.get(rtl, SCAN.enterid(name), FALSE);
3257
        id := PROG.getIdent(rtl, SCAN.enterid(name), FALSE);
3186
 
3258
 
3187
        IF (id # NIL) & (id.import # NIL) THEN
3259
        IF (id # NIL) & (id.import # NIL) THEN
3188
            CODE.codes.rtl[idx] := -id.import(CODE.IMPORT_PROC).label;
3260
            IL.codes.rtl[idx] := -id.import(IL.IMPORT_PROC).label;
3189
            id.proc.used := TRUE
3261
            id.proc.used := TRUE
3190
        ELSIF (id # NIL) & (id.proc # NIL) THEN
3262
        ELSIF (id # NIL) & (id.proc # NIL) THEN
3191
            CODE.codes.rtl[idx] := id.proc.label;
3263
            IL.codes.rtl[idx] := id.proc.label;
3192
            id.proc.used := TRUE
3264
            id.proc.used := TRUE
3193
        ELSE
3265
        ELSE
3194
            ERRORS.error5("procedure ", mConst.RTL_NAME, ".", name, " not found")
3266
            ERRORS.WrongRTL(name)
Line 3195... Line 3267...
3195
        END
3267
        END
3196
    END getproc;
3268
    END getproc;
3197
 
3269
 
Line 3198... Line 3270...
3198
 
3270
 
3199
BEGIN
3271
BEGIN
3200
    rtl := PARS.program.rtl;
3272
    rtl := PARS.program.rtl;
3201
    ASSERT(rtl # NIL);
3273
    ASSERT(rtl # NIL);
3202
 
3274
 
3203
    getproc(rtl,  "_move",      CODE._move);
3275
    IF CPU IN {cpuX86, cpuAMD64} THEN
3204
    getproc(rtl,  "_move2",     CODE._move2);
3276
        getproc(rtl,  "_strcmp",    IL._strcmp);
3205
    getproc(rtl,  "_set",       CODE._set);
3277
        getproc(rtl,  "_length",    IL._length);
3206
    getproc(rtl,  "_set2",      CODE._set2);
3278
        getproc(rtl,  "_arrcpy",    IL._arrcpy);
3207
    getproc(rtl,  "_div",       CODE._div);
3279
        getproc(rtl,  "_move",      IL._move);
3208
    getproc(rtl,  "_mod",       CODE._mod);
3280
        getproc(rtl,  "_is",        IL._is);
3209
    getproc(rtl,  "_div2",      CODE._div2);
3281
        getproc(rtl,  "_guard",     IL._guard);
3210
    getproc(rtl,  "_mod2",      CODE._mod2);
3282
        getproc(rtl,  "_guardrec",  IL._guardrec);
3211
    getproc(rtl,  "_arrcpy",    CODE._arrcpy);
3283
        getproc(rtl,  "_error",     IL._error);
3212
    getproc(rtl,  "_rot",       CODE._rot);
3284
        getproc(rtl,  "_new",       IL._new);
3213
    getproc(rtl,  "_new",       CODE._new);
3285
        getproc(rtl,  "_rot",       IL._rot);
3214
    getproc(rtl,  "_dispose",   CODE._dispose);
3286
        getproc(rtl,  "_strcpy",    IL._strcpy);
3215
    getproc(rtl,  "_strcmp",    CODE._strcmp);
3287
        getproc(rtl,  "_move2",     IL._move2);
3216
    getproc(rtl,  "_error",     CODE._error);
3288
        getproc(rtl,  "_div2",      IL._div2);
3217
    getproc(rtl,  "_is",        CODE._is);
3289
        getproc(rtl,  "_mod2",      IL._mod2);
3218
    getproc(rtl,  "_isrec",     CODE._isrec);
3290
        getproc(rtl,  "_div",       IL._div);
3219
    getproc(rtl,  "_guard",     CODE._guard);
3291
        getproc(rtl,  "_mod",       IL._mod);
3220
    getproc(rtl,  "_guardrec",  CODE._guardrec);
3292
        getproc(rtl,  "_set",       IL._set);
3221
    getproc(rtl,  "_length",    CODE._length);
3293
        getproc(rtl,  "_set2",      IL._set2);
3222
    getproc(rtl,  "_init",      CODE._init);
3294
        getproc(rtl,  "_isrec",     IL._isrec);
3223
    getproc(rtl,  "_dllentry",  CODE._dllentry);
3295
        getproc(rtl,  "_lengthw",   IL._lengthw);
3224
    getproc(rtl,  "_strcpy",    CODE._strcpy);
3296
        getproc(rtl,  "_strcmpw",   IL._strcmpw);
3225
    getproc(rtl,  "_exit",      CODE._exit);
3297
        getproc(rtl,  "_dllentry",  IL._dllentry);
Line 3226... Line 3298...
3226
    getproc(rtl,  "_strcpy2",   CODE._strcpy2);
3298
        getproc(rtl,  "_dispose",   IL._dispose);
Line 3227... Line 3299...
3227
    getproc(rtl,  "_lengthw",   CODE._lengthw);
3299
        getproc(rtl,  "_exit",      IL._exit);
3228
    getproc(rtl,  "_strcmp2",   CODE._strcmp2);
3300
        getproc(rtl,  "_init",      IL._init);
3229
    getproc(rtl,  "_strcmpw",   CODE._strcmpw);
3301
        getproc(rtl,  "_sofinit",   IL._sofinit)
3230
    getproc(rtl,  "_strcmpw2",  CODE._strcmpw2);
3302
    END
3231
 
-
 
Line 3232... Line 3303...
3232
END setrtl;
3303
 
-
 
3304
END setrtl;
-
 
3305
 
-
 
3306
 
-
 
3307
PROCEDURE compile* (path, lib_path, modname, outname: PARS.PATH; target: INTEGER; options: PROG.OPTIONS);
-
 
3308
VAR
-
 
3309
    parser: PARS.PARSER;
-
 
3310
    ext: PARS.PATH;
-
 
3311
 
-
 
3312
BEGIN
-
 
3313
    tINTEGER := PARS.program.stTypes.tINTEGER;
-
 
3314
    tBYTE    := PARS.program.stTypes.tBYTE;
3233
 
3315
    tCHAR    := PARS.program.stTypes.tCHAR;
-
 
3316
    tSET     := PARS.program.stTypes.tSET;
-
 
3317
    tBOOLEAN := PARS.program.stTypes.tBOOLEAN;
-
 
3318
    tWCHAR   := PARS.program.stTypes.tWCHAR;
-
 
3319
    tREAL    := PARS.program.stTypes.tREAL;
-
 
3320
 
-
 
3321
    Options := options;
-
 
3322
 
-
 
3323
    CASE target OF
-
 
3324
    |mConst.Target_iConsole64, mConst.Target_iGUI64, mConst.Target_iDLL64, mConst.Target_iELF64, mConst.Target_iELFSO64:
3234
 
3325
        CPU := cpuAMD64
3235
PROCEDURE compile* (path, lib_path, modname, outname: PARS.PATH; target, version, stack, base: INTEGER; pic: BOOLEAN; chk: SET);
3326
    |mConst.Target_iConsole, mConst.Target_iGUI, mConst.Target_iDLL,
3236
VAR
3327
     mConst.Target_iKolibri, mConst.Target_iObject, mConst.Target_iELF32,
Line 3237... Line 3328...
3237
    parser:  PARS.PARSER;
3328
     mConst.Target_iELFSO32:
3238
    ext: PARS.PATH;
3329
        CPU := cpuX86
Line 3239... Line 3330...
3239
    amd64: BOOLEAN;
3330
    |mConst.Target_iMSP430:
3240
 
-
 
3241
BEGIN
3331
        CPU := cpuMSP430
3242
    amd64 := target IN {mConst.Target_iConsole64, mConst.Target_iGUI64, mConst.Target_iDLL64, mConst.Target_iELF64};
3332
    END;
3243
    ext := mConst.FILE_EXT;
-
 
3244
    CaseLabels := C.create();
3333
 
3245
    CaseVar := C.create();
3334
    ext := mConst.FILE_EXT;
Line -... Line 3335...
-
 
3335
    CaseLabels := C.create();
3246
 
3336
    CaseVar := C.create();
3247
    CaseVariants := LISTS.create(NIL);
3337
 
3248
    LISTS.push(CaseVariants, NewVariant(0, NIL));
3338
    CaseVariants := LISTS.create(NIL);
3249
 
3339
    LISTS.push(CaseVariants, NewVariant(0, NIL));
3250
    checking := chk;
3340
 
Line 3264... Line 3354...
3264
        parser := PARS.create(lib_path, lib_path, StatSeq, expression, designator, chkreturn);
3354
            parser := PARS.create(lib_path, lib_path, StatSeq, expression, designator, chkreturn);
3265
        IF parser.open(parser, mConst.RTL_NAME) THEN
3355
            IF parser.open(parser, mConst.RTL_NAME) THEN
3266
            parser.parse(parser);
3356
                parser.parse(parser);
3267
            PARS.destroy(parser)
3357
                PARS.destroy(parser)
3268
        ELSE
3358
            ELSE
3269
            ERRORS.error5("file ", lib_path, mConst.RTL_NAME, mConst.FILE_EXT, " not found")
3359
                ERRORS.FileNotFound(lib_path, mConst.RTL_NAME, mConst.FILE_EXT)
-
 
3360
            END
3270
        END
3361
        END
3271
    END;
3362
    END;
Line 3272... Line 3363...
3272
 
3363
 
3273
    parser := PARS.create(path, lib_path, StatSeq, expression, designator, chkreturn);
3364
    parser := PARS.create(path, lib_path, StatSeq, expression, designator, chkreturn);
Line 3274... Line 3365...
3274
    parser.main := TRUE;
3365
    parser.main := TRUE;
3275
 
3366
 
3276
    IF parser.open(parser, modname) THEN
3367
    IF parser.open(parser, modname) THEN
3277
        parser.parse(parser)
3368
        parser.parse(parser)
3278
    ELSE
3369
    ELSE
Line 3279... Line 3370...
3279
        ERRORS.error5("file ", path, modname, mConst.FILE_EXT, " not found")
3370
        ERRORS.FileNotFound(path, modname, mConst.FILE_EXT)
Line 3280... Line 3371...
3280
    END;
3371
    END;
3281
 
3372
 
-
 
3373
    PARS.destroy(parser);
-
 
3374
 
-
 
3375
    IF PARS.program.bss > mConst.MAX_GLOBAL_SIZE THEN
-
 
3376
        ERRORS.Error(204)
3282
    PARS.destroy(parser);
3377
    END;
Line 3283... Line 3378...
3283
 
3378
 
Line 3284... Line 3379...
3284
    IF PARS.program.bss > mConst.MAX_GLOBAL_SIZE THEN
3379
    IF CPU # cpuMSP430 THEN
Line 3285... Line -...
3285
        ERRORS.error1("size of global variables is too large")
-
 
3286
    END;
3380
        setrtl
3287
 
3381
    END;
3288
    setrtl;
-
 
3289
 
3382
 
-
 
3383
    PROG.DelUnused(PARS.program, IL.DelImport);
3290
    PROG.DelUnused(PARS.program, CODE.DelImport);
3384
 
-
 
3385
    IL.codes.bss := PARS.program.bss;
3291
 
3386
 
Line 3292... Line 3387...
3292
    CODE.codes.bss := PARS.program.bss;
3387
    CASE CPU OF
3293
    IF amd64 THEN
3388
    | cpuAMD64:   AMD64.CodeGen(IL.codes, outname, target, options)