Subversion Repositories Kolibri OS

Rev

Rev 7983 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 7983 Rev 8097
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 46... Line 46...
46
 
46
 
Line 47... Line 47...
47
        range: RANGE;
47
        range: RANGE;
Line 48... Line 48...
48
 
48
 
Line 49... Line 49...
49
        variant, self: INTEGER;
49
        variant, self: INTEGER;
Line 50... Line 50...
50
 
50
 
Line 73... Line 73...
73
 
73
 
Line 74... Line 74...
74
    CaseVariants: LISTS.LIST;
74
    CaseVariants: LISTS.LIST;
Line 75... Line 75...
75
 
75
 
Line 76... Line 76...
76
    CPU: INTEGER;
76
    CPU: INTEGER;
77
 
77
 
78
    tINTEGER, tBYTE, tCHAR, tWCHAR, tSET, tBOOLEAN, tREAL: PROG.TYPE_;
78
    tINTEGER, tBYTE, tCHAR, tWCHAR, tSET, tBOOLEAN, tREAL: PROG._TYPE;
Line 87... Line 87...
87
    RETURN e.obj IN {eVAR, eVPAR, ePARAM, eVREC}
87
    RETURN e.obj IN {eVAR, eVPAR, ePARAM, eVREC}
88
END isVar;
88
END isVar;
Line 89... Line 89...
89
 
89
 
90
 
90
 
91
PROCEDURE isBoolean (e: PARS.EXPR): BOOLEAN;
91
PROCEDURE isBoolean (e: PARS.EXPR): BOOLEAN;
Line 92... Line 92...
92
    RETURN isExpr(e) & (e.type = tBOOLEAN)
92
    RETURN isExpr(e) & (e._type = tBOOLEAN)
93
END isBoolean;
93
END isBoolean;
94
 
94
 
Line 95... Line 95...
95
 
95
 
96
PROCEDURE isInteger (e: PARS.EXPR): BOOLEAN;
96
PROCEDURE isInteger (e: PARS.EXPR): BOOLEAN;
97
    RETURN isExpr(e) & (e.type = tINTEGER)
97
    RETURN isExpr(e) & (e._type = tINTEGER)
Line 98... Line 98...
98
END isInteger;
98
END isInteger;
99
 
99
 
100
 
100
 
Line 101... Line 101...
101
PROCEDURE isByte (e: PARS.EXPR): BOOLEAN;
101
PROCEDURE isByte (e: PARS.EXPR): BOOLEAN;
102
    RETURN isExpr(e) & (e.type = tBYTE)
102
    RETURN isExpr(e) & (e._type = tBYTE)
103
END isByte;
103
END isByte;
Line 104... Line 104...
104
 
104
 
105
 
105
 
106
PROCEDURE isInt (e: PARS.EXPR): BOOLEAN;
106
PROCEDURE isInt (e: PARS.EXPR): BOOLEAN;
Line 107... Line 107...
107
    RETURN isByte(e) OR isInteger(e)
107
    RETURN isByte(e) OR isInteger(e)
108
END isInt;
108
END isInt;
109
 
109
 
Line 110... Line 110...
110
 
110
 
111
PROCEDURE isReal (e: PARS.EXPR): BOOLEAN;
111
PROCEDURE isReal (e: PARS.EXPR): BOOLEAN;
112
    RETURN isExpr(e) & (e.type = tREAL)
112
    RETURN isExpr(e) & (e._type = tREAL)
Line 113... Line 113...
113
END isReal;
113
END isReal;
114
 
114
 
115
 
115
 
Line 116... Line 116...
116
PROCEDURE isSet (e: PARS.EXPR): BOOLEAN;
116
PROCEDURE isSet (e: PARS.EXPR): BOOLEAN;
117
    RETURN isExpr(e) & (e.type = tSET)
117
    RETURN isExpr(e) & (e._type = tSET)
118
END isSet;
118
END isSet;
Line 119... Line 119...
119
 
119
 
120
 
120
 
121
PROCEDURE isString (e: PARS.EXPR): BOOLEAN;
121
PROCEDURE isString (e: PARS.EXPR): BOOLEAN;
Line 122... Line 122...
122
    RETURN (e.obj = eCONST) & (e.type.typ IN {PROG.tSTRING, PROG.tCHAR})
122
    RETURN (e.obj = eCONST) & (e._type.typ IN {PROG.tSTRING, PROG.tCHAR})
123
END isString;
123
END isString;
124
 
124
 
Line 125... Line 125...
125
 
125
 
126
PROCEDURE isStringW (e: PARS.EXPR): BOOLEAN;
126
PROCEDURE isStringW (e: PARS.EXPR): BOOLEAN;
127
    RETURN (e.obj = eCONST) & (e.type.typ IN {PROG.tSTRING, PROG.tCHAR, PROG.tWCHAR})
127
    RETURN (e.obj = eCONST) & (e._type.typ IN {PROG.tSTRING, PROG.tCHAR, PROG.tWCHAR})
Line 128... Line 128...
128
END isStringW;
128
END isStringW;
129
 
129
 
130
 
130
 
Line 131... Line 131...
131
PROCEDURE isChar (e: PARS.EXPR): BOOLEAN;
131
PROCEDURE isChar (e: PARS.EXPR): BOOLEAN;
132
    RETURN isExpr(e) & (e.type = tCHAR)
132
    RETURN isExpr(e) & (e._type = tCHAR)
133
END isChar;
133
END isChar;
Line 134... Line 134...
134
 
134
 
135
 
135
 
136
PROCEDURE isCharW (e: PARS.EXPR): BOOLEAN;
136
PROCEDURE isCharW (e: PARS.EXPR): BOOLEAN;
Line 137... Line 137...
137
    RETURN isExpr(e) & (e.type = tWCHAR)
137
    RETURN isExpr(e) & (e._type = tWCHAR)
138
END isCharW;
138
END isCharW;
139
 
139
 
Line 140... Line 140...
140
 
140
 
141
PROCEDURE isPtr (e: PARS.EXPR): BOOLEAN;
141
PROCEDURE isPtr (e: PARS.EXPR): BOOLEAN;
142
    RETURN isExpr(e) & (e.type.typ = PROG.tPOINTER)
142
    RETURN isExpr(e) & (e._type.typ = PROG.tPOINTER)
Line 143... Line 143...
143
END isPtr;
143
END isPtr;
144
 
144
 
Line 202... Line 202...
202
VAR
202
VAR
203
    res: INTEGER;
203
    res: INTEGER;
Line 204... Line 204...
204
 
204
 
205
BEGIN
205
BEGIN
206
    ASSERT(isString(e));
206
    ASSERT(isString(e));
207
    IF e.type = tCHAR THEN
207
    IF e._type = tCHAR THEN
208
        res := 1
208
        res := 1
209
    ELSE
209
    ELSE
210
        res := LENGTH(e.value.string(SCAN.IDENT).s)
210
        res := LENGTH(e.value.string(SCAN.IDENT).s)
211
    END
211
    END
Line 235... Line 235...
235
VAR
235
VAR
236
    res: INTEGER;
236
    res: INTEGER;
Line 237... Line 237...
237
 
237
 
238
BEGIN
238
BEGIN
239
    ASSERT(isStringW(e));
239
    ASSERT(isStringW(e));
240
    IF e.type.typ IN {PROG.tCHAR, PROG.tWCHAR} THEN
240
    IF e._type.typ IN {PROG.tCHAR, PROG.tWCHAR} THEN
241
        res := 1
241
        res := 1
242
    ELSE
242
    ELSE
243
        res := _length(e.value.string(SCAN.IDENT).s)
243
        res := _length(e.value.string(SCAN.IDENT).s)
244
    END
244
    END
Line 255... Line 255...
255
    RETURN ORD(res[0])
255
    RETURN ORD(res[0])
256
END StrToWChar;
256
END StrToWChar;
Line 257... Line 257...
257
 
257
 
258
 
258
 
259
PROCEDURE isStringW1 (e: PARS.EXPR): BOOLEAN;
259
PROCEDURE isStringW1 (e: PARS.EXPR): BOOLEAN;
Line 260... Line 260...
260
    RETURN (e.obj = eCONST) & isString(e) & (utf8strlen(e) = 1) & (strlen(e) > 1)
260
    RETURN isString(e) & (utf8strlen(e) = 1) & (strlen(e) > 1)
261
END isStringW1;
261
END isStringW1;
262
 
262
 
Line 263... Line 263...
263
 
263
 
264
PROCEDURE assigncomp (e: PARS.EXPR; t: PROG.TYPE_): BOOLEAN;
264
PROCEDURE assigncomp (e: PARS.EXPR; t: PROG._TYPE): BOOLEAN;
Line 265... Line 265...
265
VAR
265
VAR
266
    res: BOOLEAN;
266
    res: BOOLEAN;
267
 
267
 
268
BEGIN
268
BEGIN
269
    IF isExpr(e) OR (e.obj IN {ePROC, eIMP}) THEN
269
    IF isExpr(e) OR (e.obj IN {ePROC, eIMP}) THEN
270
 
270
 
271
        IF t = e.type THEN
271
        IF t = e._type THEN
272
            res := TRUE
272
            res := TRUE
273
        ELSIF isInt(e) & (t.typ IN {PROG.tBYTE, PROG.tINTEGER}) THEN
273
        ELSIF isInt(e) & (t.typ IN {PROG.tBYTE, PROG.tINTEGER}) THEN
274
            IF (e.obj = eCONST) & (t = tBYTE) THEN
274
            IF (e.obj = eCONST) & (t = tBYTE) THEN
275
                res := ARITH.range(e.value, 0, 255)
275
                res := ARITH.range(e.value, 0, 255)
276
            ELSE
276
            ELSE
277
                res := TRUE
277
                res := TRUE
278
            END
278
            END
279
        ELSIF
279
        ELSIF
280
            (e.obj = eCONST) & isChar(e) & (t = tWCHAR)
280
            (e.obj = eCONST) & isChar(e) & (t = tWCHAR)
281
            OR isStringW1(e) & (t = tWCHAR)
281
            OR isStringW1(e) & (t = tWCHAR)
282
            OR PROG.isBaseOf(t, e.type)
282
            OR PROG.isBaseOf(t, e._type)
283
            OR ~PROG.isOpenArray(t) & ~PROG.isOpenArray(e.type) & PROG.isTypeEq(t, e.type)
283
            OR ~PROG.isOpenArray(t) & ~PROG.isOpenArray(e._type) & PROG.isTypeEq(t, e._type)
284
            OR isNil(e) & (t.typ IN {PROG.tPOINTER, PROG.tPROCEDURE})
284
            OR isNil(e) & (t.typ IN {PROG.tPOINTER, PROG.tPROCEDURE})
Line 329... Line 329...
329
        IF string.offsetW = -1 THEN
329
        IF string.offsetW = -1 THEN
330
            string.offsetW := IL.putstrW(string.s);
330
            string.offsetW := IL.putstrW(string.s);
331
        END;
331
        END;
332
        offset := string.offsetW
332
        offset := string.offsetW
333
    ELSE
333
    ELSE
334
        IF e.type.typ IN {PROG.tWCHAR, PROG.tCHAR} THEN
334
        IF e._type.typ IN {PROG.tWCHAR, PROG.tCHAR} THEN
335
            offset := IL.putstrW1(ARITH.Int(e.value))
335
            offset := IL.putstrW1(ARITH.Int(e.value))
336
        ELSE (* e.type.typ = PROG.tSTRING *)
336
        ELSE (* e._type.typ = PROG.tSTRING *)
337
            string := e.value.string(SCAN.IDENT);
337
            string := e.value.string(SCAN.IDENT);
338
            IF string.offsetW = -1 THEN
338
            IF string.offsetW = -1 THEN
339
                string.offsetW := IL.putstrW(string.s);
339
                string.offsetW := IL.putstrW(string.s);
340
            END;
340
            END;
341
            offset := string.offsetW
341
            offset := string.offsetW
Line 356... Line 356...
356
    IL.OnError(line, errno);
356
    IL.OnError(line, errno);
357
    IL.SetLabel(label)
357
    IL.SetLabel(label)
358
END CheckRange;
358
END CheckRange;
Line -... Line 359...
-
 
359
 
-
 
360
 
-
 
361
PROCEDURE Float (parser: PARS.PARSER; e: PARS.EXPR);
-
 
362
VAR
-
 
363
    pos: PARS.POSITION;
-
 
364
 
-
 
365
BEGIN
-
 
366
    getpos(parser, pos);
-
 
367
    IL.Float(ARITH.Float(e.value), pos.line, pos.col)
-
 
368
END Float;
359
 
369
 
360
 
370
 
361
PROCEDURE assign (e: PARS.EXPR; VarType: PROG.TYPE_; line: INTEGER): BOOLEAN;
371
PROCEDURE assign (parser: PARS.PARSER; e: PARS.EXPR; VarType: PROG._TYPE; line: INTEGER): BOOLEAN;
362
VAR
372
VAR
Line 363... Line 373...
363
    res:   BOOLEAN;
373
    res:   BOOLEAN;
364
    label: INTEGER;
374
    label: INTEGER;
365
 
375
 
366
BEGIN
376
BEGIN
Line 367... Line 377...
367
    IF isExpr(e) OR (e.obj IN {ePROC, eIMP}) THEN
377
    IF isExpr(e) OR (e.obj IN {ePROC, eIMP}) THEN
368
        res := TRUE;
378
        res := TRUE;
369
        IF PROG.arrcomp(e.type, VarType) THEN
379
        IF PROG.arrcomp(e._type, VarType) THEN
370
 
380
 
371
            IF ~PROG.isOpenArray(VarType) THEN
381
            IF ~PROG.isOpenArray(VarType) THEN
372
                IL.Const(VarType.length)
382
                IL.Const(VarType.length)
373
            END;
383
            END;
374
            IL.AddCmd(IL.opCOPYA, VarType.base.size);
384
            IL.AddCmd(IL.opCOPYA, VarType.base.size);
Line 375... Line 385...
375
            label := IL.NewLabel();
385
            label := IL.NewLabel();
376
            IL.AddJmpCmd(IL.opJE, label);
386
            IL.AddJmpCmd(IL.opJNZ, label);
Line 412... Line 422...
412
            ELSE
422
            ELSE
413
                IL.AddCmd0(IL.opSBOOL)
423
                IL.AddCmd0(IL.opSBOOL)
414
            END
424
            END
415
        ELSIF isReal(e) & (VarType = tREAL) THEN
425
        ELSIF isReal(e) & (VarType = tREAL) THEN
416
            IF e.obj = eCONST THEN
426
            IF e.obj = eCONST THEN
417
                IL.Float(ARITH.Float(e.value))
427
                Float(parser, e)
418
            END;
428
            END;
419
            IL.savef(e.obj = eCONST)
429
            IL.savef(e.obj = eCONST)
420
        ELSIF isChar(e) & (VarType = tCHAR) THEN
430
        ELSIF isChar(e) & (VarType = tCHAR) THEN
421
            IF e.obj = eCONST THEN
431
            IF e.obj = eCONST THEN
422
                IL.AddCmd(IL.opSAVE8C, ARITH.Int(e.value))
432
                IL.AddCmd(IL.opSAVE8C, ARITH.Int(e.value))
Line 431... Line 441...
431
            IF e.obj = eCONST THEN
441
            IF e.obj = eCONST THEN
432
                IL.AddCmd(IL.opSAVE16C, ARITH.Int(e.value))
442
                IL.AddCmd(IL.opSAVE16C, ARITH.Int(e.value))
433
            ELSE
443
            ELSE
434
                IL.AddCmd0(IL.opSAVE16)
444
                IL.AddCmd0(IL.opSAVE16)
435
            END
445
            END
436
        ELSIF PROG.isBaseOf(VarType, e.type) THEN
446
        ELSIF PROG.isBaseOf(VarType, e._type) THEN
437
            IF VarType.typ = PROG.tPOINTER THEN
447
            IF VarType.typ = PROG.tPOINTER THEN
438
                IL.AddCmd0(IL.opSAVE)
448
                IL.AddCmd0(IL.opSAVE)
439
            ELSE
449
            ELSE
440
                IL.AddCmd(IL.opCOPY, VarType.size)
450
                IL.AddCmd(IL.opCOPY, VarType.size)
441
            END
451
            END
442
        ELSIF (e.type.typ = PROG.tCARD32) & (VarType.typ = PROG.tCARD32) THEN
452
        ELSIF (e._type.typ = PROG.tCARD32) & (VarType.typ = PROG.tCARD32) THEN
443
            IL.AddCmd0(IL.opSAVE32)
453
            IL.AddCmd0(IL.opSAVE32)
444
        ELSIF ~PROG.isOpenArray(VarType) & ~PROG.isOpenArray(e.type) & PROG.isTypeEq(VarType, e.type) THEN
454
        ELSIF ~PROG.isOpenArray(VarType) & ~PROG.isOpenArray(e._type) & PROG.isTypeEq(VarType, e._type) THEN
445
            IF e.obj = ePROC THEN
455
            IF e.obj = ePROC THEN
446
                IL.AssignProc(e.ident.proc.label)
456
                IL.AssignProc(e.ident.proc.label)
447
            ELSIF e.obj = eIMP THEN
457
            ELSIF e.obj = eIMP THEN
448
                IL.AssignImpProc(e.ident.import)
458
                IL.AssignImpProc(e.ident._import)
449
            ELSE
459
            ELSE
450
                IF VarType.typ = PROG.tPROCEDURE THEN
460
                IF VarType.typ = PROG.tPROCEDURE THEN
451
                    IL.AddCmd0(IL.opSAVE)
461
                    IL.AddCmd0(IL.opSAVE)
452
                ELSE
462
                ELSE
453
                    IL.AddCmd(IL.opCOPY, VarType.size)
463
                    IL.AddCmd(IL.opCOPY, VarType.size)
Line 479... Line 489...
479
VAR
489
VAR
480
    stroffs: INTEGER;
490
    stroffs: INTEGER;
Line 481... Line 491...
481
 
491
 
482
    PROCEDURE arrcomp (e: PARS.EXPR; p: PROG.PARAM): BOOLEAN;
492
    PROCEDURE arrcomp (e: PARS.EXPR; p: PROG.PARAM): BOOLEAN;
483
    VAR
493
    VAR
Line 484... Line 494...
484
        t1, t2: PROG.TYPE_;
494
        t1, t2: PROG._TYPE;
485
 
495
 
486
    BEGIN
496
    BEGIN
487
        t1 := p.type;
497
        t1 := p._type;
488
        t2 := e.type;
498
        t2 := e._type;
489
        WHILE (t2.typ = PROG.tARRAY) & PROG.isOpenArray(t1) DO
499
        WHILE (t2.typ = PROG.tARRAY) & PROG.isOpenArray(t1) DO
490
            t1 := t1.base;
500
            t1 := t1.base;
Line 491... Line 501...
491
            t2 := t2.base
501
            t2 := t2.base
492
        END
502
        END
Line 493... Line 503...
493
 
503
 
494
        RETURN PROG.isTypeEq(t1, t2)
504
        RETURN PROG.isTypeEq(t1, t2)
495
    END arrcomp;
505
    END arrcomp;
Line 496... Line 506...
496
 
506
 
497
 
507
 
Line 508... Line 518...
508
        ASSERT(n < 0)
518
        ASSERT(n < 0)
509
        RETURN res
519
        RETURN res
510
    END ArrLen;
520
    END ArrLen;
Line 511... Line 521...
511
 
521
 
512
 
522
 
513
    PROCEDURE OpenArray (t, t2: PROG.TYPE_);
523
    PROCEDURE OpenArray (t, t2: PROG._TYPE);
Line 514... Line 524...
514
    VAR
524
    VAR
515
        n, d1, d2: INTEGER;
525
        n, d1, d2: INTEGER;
Line 545... Line 555...
545
 
555
 
546
BEGIN
556
BEGIN
Line 547... Line 557...
547
    IF p.vPar THEN
557
    IF p.vPar THEN
548
 
558
 
549
        PARS.check(isVar(e), pos, 93);
559
        PARS.check(isVar(e), pos, 93);
550
        IF p.type.typ = PROG.tRECORD THEN
560
        IF p._type.typ = PROG.tRECORD THEN
551
            PARS.check(PROG.isBaseOf(p.type, e.type), pos, 66);
561
            PARS.check(PROG.isBaseOf(p._type, e._type), pos, 66);
552
            IF e.obj = eVREC THEN
562
            IF e.obj = eVREC THEN
553
                IF e.ident # NIL THEN
563
                IF e.ident # NIL THEN
554
                    IL.AddCmd(IL.opVADR, e.ident.offset - 1)
564
                    IL.AddCmd(IL.opVADR, e.ident.offset - 1)
555
                ELSE
565
                ELSE
556
                    IL.AddCmd0(IL.opPUSHT)
566
                    IL.AddCmd0(IL.opPUSHT)
557
                END
567
                END
558
            ELSE
568
            ELSE
559
                IL.Const(e.type.num)
569
                IL.Const(e._type.num)
560
            END;
570
            END;
561
            IL.AddCmd(IL.opPARAM, 2)
571
            IL.AddCmd(IL.opPARAM, 2)
562
        ELSIF PROG.isOpenArray(p.type) THEN
572
        ELSIF PROG.isOpenArray(p._type) THEN
563
            PARS.check(arrcomp(e, p), pos, 66);
573
            PARS.check(arrcomp(e, p), pos, 66);
564
            OpenArray(e.type, p.type)
574
            OpenArray(e._type, p._type)
565
        ELSE
575
        ELSE
566
            PARS.check(PROG.isTypeEq(e.type, p.type), pos, 66);
576
            PARS.check(PROG.isTypeEq(e._type, p._type), pos, 66);
567
            IL.Param1
577
            IL.Param1
Line 568... Line 578...
568
        END;
578
        END;
569
        PARS.check(~e.readOnly, pos, 94)
579
        PARS.check(~e.readOnly, pos, 94)
570
 
580
 
571
    ELSE
581
    ELSE
572
        PARS.check(isExpr(e) OR isProc(e), pos, 66);
582
        PARS.check(isExpr(e) OR isProc(e), pos, 66);
573
        IF PROG.isOpenArray(p.type) THEN
583
        IF PROG.isOpenArray(p._type) THEN
574
            IF e.type.typ = PROG.tARRAY THEN
584
            IF e._type.typ = PROG.tARRAY THEN
575
                PARS.check(arrcomp(e, p), pos, 66);
585
                PARS.check(arrcomp(e, p), pos, 66);
576
                OpenArray(e.type, p.type)
586
                OpenArray(e._type, p._type)
577
            ELSIF isString(e) & (p.type.typ = PROG.tARRAY) & (p.type.base = tCHAR) THEN
587
            ELSIF isString(e) & (p._type.typ = PROG.tARRAY) & (p._type.base = tCHAR) THEN
578
                IL.StrAdr(String(e));
588
                IL.StrAdr(String(e));
579
                IL.Param1;
589
                IL.Param1;
580
                IL.Const(strlen(e) + 1);
590
                IL.Const(strlen(e) + 1);
581
                IL.Param1
591
                IL.Param1
582
            ELSIF isStringW(e) & (p.type.typ = PROG.tARRAY) & (p.type.base = tWCHAR) THEN
592
            ELSIF isStringW(e) & (p._type.typ = PROG.tARRAY) & (p._type.base = tWCHAR) THEN
583
                IL.StrAdr(StringW(e));
593
                IL.StrAdr(StringW(e));
584
                IL.Param1;
594
                IL.Param1;
585
                IL.Const(utf8strlen(e) + 1);
595
                IL.Const(utf8strlen(e) + 1);
586
                IL.Param1
596
                IL.Param1
587
            ELSE
597
            ELSE
588
                PARS.error(pos, 66)
598
                PARS.error(pos, 66)
589
            END
599
            END
590
        ELSE
600
        ELSE
591
            PARS.check(~PROG.isOpenArray(e.type), pos, 66);
601
            PARS.check(~PROG.isOpenArray(e._type), pos, 66);
592
            PARS.check(assigncomp(e, p.type), pos, 66);
602
            PARS.check(assigncomp(e, p._type), pos, 66);
593
            IF e.obj = eCONST THEN
603
            IF e.obj = eCONST THEN
594
                IF e.type = tREAL THEN
604
                IF e._type = tREAL THEN
595
                    IL.Float(ARITH.Float(e.value));
605
                    Float(parser, e);
596
                    IL.pushf
606
                    IL.AddCmd0(IL.opPUSHF)
597
                ELSIF e.type.typ = PROG.tNIL THEN
607
                ELSIF e._type.typ = PROG.tNIL THEN
598
                    IL.Const(0);
608
                    IL.Const(0);
599
                    IL.Param1
609
                    IL.Param1
600
                ELSIF isStringW1(e) & (p.type = tWCHAR) THEN
610
                ELSIF isStringW1(e) & (p._type = tWCHAR) THEN
601
                    IL.Const(StrToWChar(e.value.string(SCAN.IDENT).s));
611
                    IL.Const(StrToWChar(e.value.string(SCAN.IDENT).s));
602
                    IL.Param1
612
                    IL.Param1
603
                ELSIF (e.type.typ = PROG.tSTRING) OR
613
                ELSIF (e._type.typ = PROG.tSTRING) OR
604
                      (e.type.typ IN {PROG.tCHAR, PROG.tWCHAR}) & (p.type.typ = PROG.tARRAY) & (p.type.base.typ IN {PROG.tCHAR, PROG.tWCHAR}) THEN
614
                      (e._type.typ IN {PROG.tCHAR, PROG.tWCHAR}) & (p._type.typ = PROG.tARRAY) & (p._type.base.typ IN {PROG.tCHAR, PROG.tWCHAR}) THEN
605
                    IF p.type.base = tCHAR THEN
615
                    IF p._type.base = tCHAR THEN
606
                        stroffs := String(e);
616
                        stroffs := String(e);
607
                        IL.StrAdr(stroffs);
617
                        IL.StrAdr(stroffs);
608
                        IF (CPU = TARGETS.cpuMSP430) & (p.type.size - strlen(e) - 1 > MSP430.IntVectorSize) THEN
618
                        IF (CPU = TARGETS.cpuMSP430) & (p._type.size - strlen(e) - 1 > MSP430.IntVectorSize) THEN
609
                            ERRORS.WarningMsg(pos.line, pos.col, 0)
619
                            ERRORS.WarningMsg(pos.line, pos.col, 0)
610
                        END
620
                        END
611
                    ELSE (* WCHAR *)
621
                    ELSE (* WCHAR *)
612
                        stroffs := StringW(e);
622
                        stroffs := StringW(e);
613
                        IL.StrAdr(stroffs)
623
                        IL.StrAdr(stroffs)
614
                    END;
624
                    END;
615
                    IL.set_dmin(stroffs + p.type.size);
625
                    IL.set_dmin(stroffs + p._type.size);
616
                    IL.Param1
626
                    IL.Param1
617
                ELSE
627
                ELSE
618
                    LoadConst(e);
628
                    LoadConst(e);
619
                    IL.Param1
629
                    IL.Param1
620
                END
630
                END
621
            ELSIF e.obj = ePROC THEN
631
            ELSIF e.obj = ePROC THEN
622
                PARS.check(e.ident.global, pos, 85);
632
                PARS.check(e.ident.global, pos, 85);
623
                IL.PushProc(e.ident.proc.label);
633
                IL.PushProc(e.ident.proc.label);
624
                IL.Param1
634
                IL.Param1
625
            ELSIF e.obj = eIMP THEN
635
            ELSIF e.obj = eIMP THEN
626
                IL.PushImpProc(e.ident.import);
636
                IL.PushImpProc(e.ident._import);
627
                IL.Param1
637
                IL.Param1
628
            ELSIF isExpr(e) & (e.type = tREAL) THEN
638
            ELSIF isExpr(e) & (e._type = tREAL) THEN
629
                IL.pushf
639
                IL.AddCmd0(IL.opPUSHF)
630
            ELSE
640
            ELSE
631
                IF (p.type = tBYTE) & (e.type = tINTEGER) & (chkBYTE IN Options.checking) THEN
641
                IF (p._type = tBYTE) & (e._type = tINTEGER) & (chkBYTE IN Options.checking) THEN
632
                    CheckRange(256, pos.line, errBYTE)
642
                    CheckRange(256, pos.line, errBYTE)
633
                END;
643
                END;
Line 649... Line 659...
649
VAR
659
VAR
650
    e1, e2: PARS.EXPR;
660
    e1, e2: PARS.EXPR;
651
    pos:    PARS.POSITION;
661
    pos:    PARS.POSITION;
652
    proc,
662
    proc,
653
    label,
663
    label,
-
 
664
    size,
654
    n, i:   INTEGER;
665
    n, i:   INTEGER;
655
    code:   ARITH.VALUE;
666
    code:   ARITH.VALUE;
656
    wchar,
667
    wchar,
657
    comma:  BOOLEAN;
668
    comma:  BOOLEAN;
658
    cmd1,
669
    cmd1,
Line 714... Line 725...
714
                IF ~ARITH.getBool(e.value) THEN
725
                IF ~ARITH.getBool(e.value) THEN
715
                    IL.OnError(pos.line, errASSERT)
726
                    IL.OnError(pos.line, errASSERT)
716
                END
727
                END
717
            ELSE
728
            ELSE
718
                label := IL.NewLabel();
729
                label := IL.NewLabel();
-
 
730
                IL.not;
719
                IL.AddJmpCmd(IL.opJE, label);
731
                IL.AndOrOpt(label);
720
                IL.OnError(pos.line, errASSERT);
732
                IL.OnError(pos.line, errASSERT);
721
                IL.SetLabel(label)
733
                IL.SetLabel(label)
722
            END
734
            END
Line 723... Line 735...
723
 
735
 
724
        |PROG.stINC, PROG.stDEC:
736
        |PROG.stINC, PROG.stDEC:
725
            IL.pushBegEnd(begcall, endcall);
737
            IL.pushBegEnd(begcall, endcall);
726
            varparam(parser, pos, isInt, TRUE, e);
738
            varparam(parser, pos, isInt, TRUE, e);
727
            IF e.type = tINTEGER THEN
739
            IF e._type = tINTEGER THEN
728
                IF parser.sym = SCAN.lxCOMMA THEN
740
                IF parser.sym = SCAN.lxCOMMA THEN
729
                    NextPos(parser, pos);
741
                    NextPos(parser, pos);
730
                    IL.setlast(begcall);
742
                    IL.setlast(begcall);
731
                    PExpression(parser, e2);
743
                    PExpression(parser, e2);
Line 737... Line 749...
737
                        IL.AddCmd0(IL.opINC + ORD(proc = PROG.stDEC))
749
                        IL.AddCmd0(IL.opINC + ORD(proc = PROG.stDEC))
738
                    END
750
                    END
739
                ELSE
751
                ELSE
740
                    IL.AddCmd(IL.opINCC, ORD(proc = PROG.stINC) * 2 - 1)
752
                    IL.AddCmd(IL.opINCC, ORD(proc = PROG.stINC) * 2 - 1)
741
                END
753
                END
742
            ELSE  (* e.type = tBYTE *)
754
            ELSE  (* e._type = tBYTE *)
743
                IF parser.sym = SCAN.lxCOMMA THEN
755
                IF parser.sym = SCAN.lxCOMMA THEN
744
                    NextPos(parser, pos);
756
                    NextPos(parser, pos);
745
                    IL.setlast(begcall);
757
                    IL.setlast(begcall);
746
                    PExpression(parser, e2);
758
                    PExpression(parser, e2);
747
                    IL.setlast(endcall.prev(IL.COMMAND));
759
                    IL.setlast(endcall.prev(IL.COMMAND));
Line 775... Line 787...
775
            IL.popBegEnd(begcall, endcall)
787
            IL.popBegEnd(begcall, endcall)
Line 776... Line 788...
776
 
788
 
777
        |PROG.stNEW:
789
        |PROG.stNEW:
778
            varparam(parser, pos, isPtr, TRUE, e);
790
            varparam(parser, pos, isPtr, TRUE, e);
779
            IF CPU = TARGETS.cpuMSP430 THEN
791
            IF CPU = TARGETS.cpuMSP430 THEN
780
                PARS.check(e.type.base.size + 16 < Options.ram, pos, 63)
792
                PARS.check(e._type.base.size + 16 < Options.ram, pos, 63)
781
            END;
793
            END;
Line 782... Line 794...
782
            IL.New(e.type.base.size, e.type.base.num)
794
            IL.New(e._type.base.size, e._type.base.num)
783
 
795
 
784
        |PROG.stDISPOSE:
796
        |PROG.stDISPOSE:
Line 813... Line 825...
813
                wchar := TRUE
825
                wchar := TRUE
814
            ELSE
826
            ELSE
815
                PARS.error(pos, 66)
827
                PARS.error(pos, 66)
816
            END;
828
            END;
Line 817... Line 829...
817
 
829
 
818
            IF isCharArrayX(e) & ~PROG.isOpenArray(e.type) THEN
830
            IF isCharArrayX(e) & ~PROG.isOpenArray(e._type) THEN
819
                IL.Const(e.type.length)
831
                IL.Const(e._type.length)
Line 820... Line 832...
820
            END;
832
            END;
821
 
833
 
822
            PARS.checklex(parser, SCAN.lxCOMMA);
834
            PARS.checklex(parser, SCAN.lxCOMMA);
Line 830... Line 842...
830
                    varparam(parser, pos, isCharArrayX, TRUE, e1)
842
                    varparam(parser, pos, isCharArrayX, TRUE, e1)
831
                ELSE
843
                ELSE
832
                    varparam(parser, pos, isCharArray, TRUE, e1)
844
                    varparam(parser, pos, isCharArray, TRUE, e1)
833
                END;
845
                END;
Line 834... Line 846...
834
 
846
 
835
                wchar := e1.type.base = tWCHAR
847
                wchar := e1._type.base = tWCHAR
Line 836... Line 848...
836
            END;
848
            END;
837
 
849
 
838
            IF ~PROG.isOpenArray(e1.type) THEN
850
            IF ~PROG.isOpenArray(e1._type) THEN
Line 839... Line 851...
839
                IL.Const(e1.type.length)
851
                IL.Const(e1._type.length)
Line 840... Line 852...
840
            END;
852
            END;
Line 848... Line 860...
848
                ELSE
860
                ELSE
849
                    IL.StrAdr(String(e));
861
                    IL.StrAdr(String(e));
850
                    IL.Const(strlen(e) + 1)
862
                    IL.Const(strlen(e) + 1)
851
                END
863
                END
852
            END;
864
            END;
853
            IL.AddCmd(IL.opCOPYS, e1.type.base.size);
865
            IL.AddCmd(IL.opCOPYS, e1._type.base.size);
854
            IL.popBegEnd(begcall, endcall)
866
            IL.popBegEnd(begcall, endcall)
Line 855... Line 867...
855
 
867
 
856
        |PROG.sysGET:
868
        |PROG.sysGET, PROG.sysGET8, PROG.sysGET16, PROG.sysGET32:
857
            PExpression(parser, e);
869
            PExpression(parser, e);
858
            PARS.check(isInt(e), pos, 66);
870
            PARS.check(isInt(e), pos, 66);
859
            PARS.checklex(parser, SCAN.lxCOMMA);
871
            PARS.checklex(parser, SCAN.lxCOMMA);
860
            NextPos(parser, pos);
872
            NextPos(parser, pos);
861
            parser.designator(parser, e2);
873
            parser.designator(parser, e2);
-
 
874
            PARS.check(isVar(e2), pos, 93);
862
            PARS.check(isVar(e2), pos, 93);
875
            IF proc = PROG.sysGET THEN
-
 
876
                PARS.check(e2._type.typ IN PROG.BASICTYPES + {PROG.tPOINTER, PROG.tPROCEDURE}, pos, 66)
-
 
877
            ELSE
-
 
878
                PARS.check(e2._type.typ IN {PROG.tINTEGER, PROG.tBYTE, PROG.tCHAR, PROG.tSET, PROG.tWCHAR, PROG.tCARD32}, pos, 66)
-
 
879
            END;
-
 
880
 
-
 
881
            CASE proc OF
-
 
882
            |PROG.sysGET:   size := e2._type.size
-
 
883
            |PROG.sysGET8:  size := 1
-
 
884
            |PROG.sysGET16: size := 2
-
 
885
            |PROG.sysGET32: size := 4
-
 
886
            END;
-
 
887
 
-
 
888
            PARS.check(size <= e2._type.size, pos, 66);
863
            PARS.check(e2.type.typ IN PROG.BASICTYPES + {PROG.tPOINTER, PROG.tPROCEDURE}, pos, 66);
889
 
864
            IF e.obj = eCONST THEN
890
            IF e.obj = eCONST THEN
865
                IL.AddCmd2(IL.opGETC, ARITH.Int(e.value), e2.type.size)
891
                IL.AddCmd2(IL.opGETC, ARITH.Int(e.value), size)
866
            ELSE
892
            ELSE
867
                IL.AddCmd(IL.opGET, e2.type.size)
893
                IL.AddCmd(IL.opGET, size)
Line 868... Line 894...
868
            END
894
            END
869
 
895
 
870
        |PROG.sysPUT, PROG.sysPUT8, PROG.sysPUT16, PROG.sysPUT32:
896
        |PROG.sysPUT, PROG.sysPUT8, PROG.sysPUT16, PROG.sysPUT32:
Line 879... Line 905...
879
            IL.setlast(begcall);
905
            IL.setlast(begcall);
880
            PExpression(parser, e2);
906
            PExpression(parser, e2);
881
            PARS.check(isExpr(e2), pos, 66);
907
            PARS.check(isExpr(e2), pos, 66);
Line 882... Line 908...
882
 
908
 
883
            IF proc = PROG.sysPUT THEN
909
            IF proc = PROG.sysPUT THEN
884
                PARS.check(e2.type.typ IN PROG.BASICTYPES + {PROG.tPOINTER, PROG.tPROCEDURE}, pos, 66);
910
                PARS.check(e2._type.typ IN PROG.BASICTYPES + {PROG.tPOINTER, PROG.tPROCEDURE}, pos, 66);
885
                IF e2.obj = eCONST THEN
911
                IF e2.obj = eCONST THEN
886
                    IF e2.type = tREAL THEN
912
                    IF e2._type = tREAL THEN
887
                        IL.Float(ARITH.Float(e2.value));
913
                        Float(parser, e2);
888
                        IL.setlast(endcall.prev(IL.COMMAND));
914
                        IL.setlast(endcall.prev(IL.COMMAND));
889
                        IL.savef(FALSE)
915
                        IL.savef(FALSE)
890
                    ELSE
916
                    ELSE
891
                        LoadConst(e2);
917
                        LoadConst(e2);
892
                        IL.setlast(endcall.prev(IL.COMMAND));
918
                        IL.setlast(endcall.prev(IL.COMMAND));
893
                        IL.SysPut(e2.type.size)
919
                        IL.SysPut(e2._type.size)
894
                    END
920
                    END
895
                ELSE
921
                ELSE
896
                    IL.setlast(endcall.prev(IL.COMMAND));
922
                    IL.setlast(endcall.prev(IL.COMMAND));
897
                    IF e2.type = tREAL THEN
923
                    IF e2._type = tREAL THEN
898
                        IL.savef(FALSE)
924
                        IL.savef(FALSE)
899
                    ELSIF e2.type = tBYTE THEN
925
                    ELSIF e2._type = tBYTE THEN
900
                        IL.SysPut(tINTEGER.size)
926
                        IL.SysPut(tINTEGER.size)
901
                    ELSE
927
                    ELSE
902
                        IL.SysPut(e2.type.size)
928
                        IL.SysPut(e2._type.size)
903
                    END
929
                    END
Line 904... Line 930...
904
                END
930
                END
905
 
931
 
906
            ELSIF (proc = PROG.sysPUT8) OR (proc = PROG.sysPUT16) OR (proc = PROG.sysPUT32) THEN
932
            ELSIF (proc = PROG.sysPUT8) OR (proc = PROG.sysPUT16) OR (proc = PROG.sysPUT32) THEN
907
                PARS.check(e2.type.typ IN {PROG.tINTEGER, PROG.tBYTE, PROG.tCHAR, PROG.tSET, PROG.tWCHAR, PROG.tCARD32}, pos, 66);
933
                PARS.check(e2._type.typ IN {PROG.tINTEGER, PROG.tBYTE, PROG.tCHAR, PROG.tSET, PROG.tWCHAR, PROG.tCARD32}, pos, 66);
908
                IF e2.obj = eCONST THEN
934
                IF e2.obj = eCONST THEN
909
                    LoadConst(e2)
935
                    LoadConst(e2)
910
                END;
936
                END;
911
                IL.setlast(endcall.prev(IL.COMMAND));
937
                IL.setlast(endcall.prev(IL.COMMAND));
912
                CASE proc OF
938
                CASE proc OF
913
                |PROG.sysPUT8:  IL.SysPut(1)
939
                |PROG.sysPUT8:  size := 1
914
                |PROG.sysPUT16: IL.SysPut(2)
940
                |PROG.sysPUT16: size := 2
-
 
941
                |PROG.sysPUT32: size := 4
Line 915... Line 942...
915
                |PROG.sysPUT32: IL.SysPut(4)
942
                END;
916
                END
943
                IL.SysPut(size)
Line 917... Line 944...
917
 
944
 
Line 938... Line 965...
938
 
965
 
939
        |PROG.sysCOPY:
966
        |PROG.sysCOPY:
940
            FOR i := 1 TO 2 DO
967
            FOR i := 1 TO 2 DO
941
                parser.designator(parser, e);
968
                parser.designator(parser, e);
942
                PARS.check(isVar(e), pos, 93);
969
                PARS.check(isVar(e), pos, 93);
943
                n := PROG.Dim(e.type);
970
                n := PROG.Dim(e._type);
944
                WHILE n > 0 DO
971
                WHILE n > 0 DO
945
                    IL.drop;
972
                    IL.drop;
946
                    DEC(n)
973
                    DEC(n)
947
                END;
974
                END;
Line 959... Line 986...
959
        |PROG.sysCODE:
986
        |PROG.sysCODE:
960
            REPEAT
987
            REPEAT
961
                getpos(parser, pos);
988
                getpos(parser, pos);
962
                PARS.ConstExpression(parser, code);
989
                PARS.ConstExpression(parser, code);
963
                PARS.check(code.typ = ARITH.tINTEGER, pos, 43);
990
                PARS.check(code.typ = ARITH.tINTEGER, pos, 43);
964
                IF CPU IN {TARGETS.cpuX86, TARGETS.cpuAMD64} THEN
991
                IF TARGETS.WordSize > TARGETS.InstrSize THEN
965
                    PARS.check(ARITH.range(code, 0, 255), pos, 42)
992
                    CASE TARGETS.InstrSize OF
966
                ELSIF CPU = TARGETS.cpuTHUMB THEN
993
                    |1: PARS.check(ARITH.range(code, 0, 255), pos, 42)
967
                    PARS.check(ARITH.range(code, 0, 65535), pos, 110)
994
                    |2: PARS.check(ARITH.range(code, 0, 65535), pos, 110)
-
 
995
                    END
968
                END;
996
                END;
969
                IL.AddCmd(IL.opCODE, ARITH.getInt(code));
997
                IL.AddCmd(IL.opCODE, ARITH.getInt(code));
970
                comma := parser.sym = SCAN.lxCOMMA;
998
                comma := parser.sym = SCAN.lxCOMMA;
971
                IF comma THEN
999
                IF comma THEN
972
                    PARS.Next(parser)
1000
                    PARS.Next(parser)
Line 989... Line 1017...
989
            END
1017
            END
990
            *)
1018
            *)
991
        END;
1019
        END;
Line 992... Line 1020...
992
 
1020
 
993
        e.obj := eEXPR;
1021
        e.obj := eEXPR;
Line 994... Line 1022...
994
        e.type := NIL
1022
        e._type := NIL
Line 995... Line 1023...
995
 
1023
 
996
    ELSIF e.obj IN {eSTFUNC, eSYSFUNC} THEN
1024
    ELSIF e.obj IN {eSTFUNC, eSYSFUNC} THEN
Line 1010... Line 1038...
1010
            PARS.check(isInt(e), pos, 66);
1038
            PARS.check(isInt(e), pos, 66);
1011
            PARS.checklex(parser, SCAN.lxCOMMA);
1039
            PARS.checklex(parser, SCAN.lxCOMMA);
1012
            NextPos(parser, pos);
1040
            NextPos(parser, pos);
1013
            PExpression(parser, e2);
1041
            PExpression(parser, e2);
1014
            PARS.check(isInt(e2), pos, 66);
1042
            PARS.check(isInt(e2), pos, 66);
1015
            e.type := tINTEGER;
1043
            e._type := tINTEGER;
1016
            IF (e.obj = eCONST) & (e2.obj = eCONST) THEN
1044
            IF (e.obj = eCONST) & (e2.obj = eCONST) THEN
1017
                ASSERT(ARITH.opInt(e.value, e2.value, shift_minmax(proc)))
1045
                ASSERT(ARITH.opInt(e.value, e2.value, shift_minmax(proc)))
1018
            ELSE
1046
            ELSE
1019
                IF e.obj = eCONST THEN
1047
                IF e.obj = eCONST THEN
1020
                    IL.shift_minmax1(shift_minmax(proc), ARITH.Int(e.value))
1048
                    IL.shift_minmax1(shift_minmax(proc), ARITH.Int(e.value))
Line 1027... Line 1055...
1027
            END
1055
            END
Line 1028... Line 1056...
1028
 
1056
 
1029
        |PROG.stCHR:
1057
        |PROG.stCHR:
1030
            PExpression(parser, e);
1058
            PExpression(parser, e);
1031
            PARS.check(isInt(e), pos, 66);
1059
            PARS.check(isInt(e), pos, 66);
1032
            e.type := tCHAR;
1060
            e._type := tCHAR;
1033
            IF e.obj = eCONST THEN
1061
            IF e.obj = eCONST THEN
1034
                ARITH.setChar(e.value, ARITH.getInt(e.value));
1062
                ARITH.setChar(e.value, ARITH.getInt(e.value));
1035
                PARS.check(ARITH.check(e.value), pos, 107)
1063
                PARS.check(ARITH.check(e.value), pos, 107)
1036
            ELSE
1064
            ELSE
Line 1042... Line 1070...
1042
            END
1070
            END
Line 1043... Line 1071...
1043
 
1071
 
1044
        |PROG.stWCHR:
1072
        |PROG.stWCHR:
1045
            PExpression(parser, e);
1073
            PExpression(parser, e);
1046
            PARS.check(isInt(e), pos, 66);
1074
            PARS.check(isInt(e), pos, 66);
1047
            e.type := tWCHAR;
1075
            e._type := tWCHAR;
1048
            IF e.obj = eCONST THEN
1076
            IF e.obj = eCONST THEN
1049
                ARITH.setWChar(e.value, ARITH.getInt(e.value));
1077
                ARITH.setWChar(e.value, ARITH.getInt(e.value));
1050
                PARS.check(ARITH.check(e.value), pos, 101)
1078
                PARS.check(ARITH.check(e.value), pos, 101)
1051
            ELSE
1079
            ELSE
Line 1057... Line 1085...
1057
            END
1085
            END
Line 1058... Line 1086...
1058
 
1086
 
1059
        |PROG.stFLOOR:
1087
        |PROG.stFLOOR:
1060
            PExpression(parser, e);
1088
            PExpression(parser, e);
1061
            PARS.check(isReal(e), pos, 66);
1089
            PARS.check(isReal(e), pos, 66);
1062
            e.type := tINTEGER;
1090
            e._type := tINTEGER;
1063
            IF e.obj = eCONST THEN
1091
            IF e.obj = eCONST THEN
1064
                PARS.check(ARITH.floor(e.value), pos, 39)
1092
                PARS.check(ARITH.floor(e.value), pos, 39)
1065
            ELSE
1093
            ELSE
1066
                IL.floor
1094
                IL.AddCmd0(IL.opFLOOR)
Line 1067... Line 1095...
1067
            END
1095
            END
1068
 
1096
 
1069
        |PROG.stFLT:
1097
        |PROG.stFLT:
1070
            PExpression(parser, e);
1098
            PExpression(parser, e);
1071
            PARS.check(isInt(e), pos, 66);
1099
            PARS.check(isInt(e), pos, 66);
1072
            e.type := tREAL;
1100
            e._type := tREAL;
1073
            IF e.obj = eCONST THEN
1101
            IF e.obj = eCONST THEN
1074
                ARITH.flt(e.value)
1102
                ARITH.flt(e.value)
1075
            ELSE
1103
            ELSE
Line 1076... Line 1104...
1076
                PARS.check(IL.flt(), pos, 41)
1104
                IL.AddCmd2(IL.opFLT, pos.line, pos.col)
1077
            END
1105
            END
1078
 
1106
 
1079
        |PROG.stLEN:
1107
        |PROG.stLEN:
1080
            cmd1 := IL.getlast();
1108
            cmd1 := IL.getlast();
1081
            varparam(parser, pos, isArr, FALSE, e);
1109
            varparam(parser, pos, isArr, FALSE, e);
1082
            IF e.type.length > 0 THEN
1110
            IF e._type.length > 0 THEN
1083
                cmd2 := IL.getlast();
1111
                cmd2 := IL.getlast();
1084
                IL.delete2(cmd1.next, cmd2);
1112
                IL.delete2(cmd1.next, cmd2);
1085
                IL.setlast(cmd1);
1113
                IL.setlast(cmd1);
1086
                ASSERT(ARITH.setInt(e.value, e.type.length));
1114
                ASSERT(ARITH.setInt(e.value, e._type.length));
1087
                e.obj := eCONST
1115
                e.obj := eCONST
1088
            ELSE
1116
            ELSE
Line 1089... Line 1117...
1089
                IL.len(PROG.Dim(e.type))
1117
                IL.len(PROG.Dim(e._type))
1090
            END;
1118
            END;
1091
            e.type := tINTEGER
1119
            e._type := tINTEGER
1092
 
1120
 
1093
        |PROG.stLENGTH:
1121
        |PROG.stLENGTH:
1094
            PExpression(parser, e);
1122
            PExpression(parser, e);
1095
            IF isCharArray(e) THEN
1123
            IF isCharArray(e) THEN
1096
                IF e.type.length > 0 THEN
1124
                IF e._type.length > 0 THEN
1097
                    IL.Const(e.type.length)
1125
                    IL.Const(e._type.length)
1098
                END;
1126
                END;
1099
                IL.AddCmd0(IL.opLENGTH)
1127
                IL.AddCmd0(IL.opLENGTH)
1100
            ELSIF isCharArrayW(e) THEN
1128
            ELSIF isCharArrayW(e) THEN
1101
                IF e.type.length > 0 THEN
1129
                IF e._type.length > 0 THEN
1102
                    IL.Const(e.type.length)
1130
                    IL.Const(e._type.length)
1103
                END;
1131
                END;
1104
                IL.AddCmd0(IL.opLENGTHW)
1132
                IL.AddCmd0(IL.opLENGTHW)
Line 1105... Line 1133...
1105
            ELSE
1133
            ELSE
1106
                PARS.error(pos, 66);
1134
                PARS.error(pos, 66);
1107
            END;
1135
            END;
1108
            e.type := tINTEGER
1136
            e._type := tINTEGER
1109
 
1137
 
1110
        |PROG.stODD:
1138
        |PROG.stODD:
1111
            PExpression(parser, e);
1139
            PExpression(parser, e);
1112
            PARS.check(isInt(e), pos, 66);
1140
            PARS.check(isInt(e), pos, 66);
1113
            e.type := tBOOLEAN;
1141
            e._type := tBOOLEAN;
Line 1126... Line 1154...
1126
                ELSE
1154
                ELSE
1127
                    ARITH.ord(e.value)
1155
                    ARITH.ord(e.value)
1128
                END
1156
                END
1129
            ELSE
1157
            ELSE
1130
                IF isBoolean(e) THEN
1158
                IF isBoolean(e) THEN
1131
                    IL.AddCmd0(IL.opORD)
1159
                    IL._ord
1132
                END
1160
                END
1133
            END;
1161
            END;
1134
            e.type := tINTEGER
1162
            e._type := tINTEGER
Line 1135... Line 1163...
1135
 
1163
 
1136
        |PROG.stBITS:
1164
        |PROG.stBITS:
1137
            PExpression(parser, e);
1165
            PExpression(parser, e);
1138
            PARS.check(isInt(e), pos, 66);
1166
            PARS.check(isInt(e), pos, 66);
1139
            IF e.obj = eCONST THEN
1167
            IF e.obj = eCONST THEN
1140
                ARITH.bits(e.value)
1168
                ARITH.bits(e.value)
1141
            END;
1169
            END;
Line 1142... Line 1170...
1142
            e.type := tSET
1170
            e._type := tSET
1143
 
1171
 
1144
        |PROG.sysADR:
1172
        |PROG.sysADR:
1145
            parser.designator(parser, e);
1173
            parser.designator(parser, e);
1146
            IF isVar(e) THEN
1174
            IF isVar(e) THEN
1147
               n := PROG.Dim(e.type);
1175
                n := PROG.Dim(e._type);
1148
               WHILE n > 0 DO
1176
                WHILE n > 0 DO
1149
                    IL.drop;
1177
                    IL.drop;
1150
                    DEC(n)
1178
                    DEC(n)
1151
               END
1179
                END
1152
            ELSIF e.obj = ePROC THEN
1180
            ELSIF e.obj = ePROC THEN
1153
                IL.PushProc(e.ident.proc.label)
1181
                IL.PushProc(e.ident.proc.label)
1154
            ELSIF e.obj = eIMP THEN
1182
            ELSIF e.obj = eIMP THEN
1155
                IL.PushImpProc(e.ident.import)
1183
                IL.PushImpProc(e.ident._import)
1156
            ELSE
1184
            ELSE
1157
                PARS.error(pos, 108)
1185
                PARS.error(pos, 108)
Line 1158... Line 1186...
1158
            END;
1186
            END;
1159
            e.type := tINTEGER
1187
            e._type := tINTEGER
1160
 
1188
 
1161
        |PROG.sysSADR:
1189
        |PROG.sysSADR:
1162
            PExpression(parser, e);
1190
            PExpression(parser, e);
1163
            PARS.check(isString(e), pos, 66);
1191
            PARS.check(isString(e), pos, 66);
Line 1164... Line 1192...
1164
            IL.StrAdr(String(e));
1192
            IL.StrAdr(String(e));
1165
            e.type := tINTEGER;
1193
            e._type := tINTEGER;
1166
            e.obj := eEXPR
1194
            e.obj := eEXPR
1167
 
1195
 
1168
        |PROG.sysWSADR:
1196
        |PROG.sysWSADR:
1169
            PExpression(parser, e);
1197
            PExpression(parser, e);
Line 1170... Line 1198...
1170
            PARS.check(isStringW(e), pos, 66);
1198
            PARS.check(isStringW(e), pos, 66);
1171
            IL.StrAdr(StringW(e));
1199
            IL.StrAdr(StringW(e));
1172
            e.type := tINTEGER;
1200
            e._type := tINTEGER;
1173
            e.obj := eEXPR
1201
            e.obj := eEXPR
1174
 
1202
 
1175
        |PROG.sysTYPEID:
1203
        |PROG.sysTYPEID:
1176
            PExpression(parser, e);
1204
            PExpression(parser, e);
1177
            PARS.check(e.obj = eTYPE, pos, 68);
1205
            PARS.check(e.obj = eTYPE, pos, 68);
1178
            IF e.type.typ = PROG.tRECORD THEN
1206
            IF e._type.typ = PROG.tRECORD THEN
1179
                ASSERT(ARITH.setInt(e.value, e.type.num))
1207
                ASSERT(ARITH.setInt(e.value, e._type.num))
1180
            ELSIF  e.type.typ = PROG.tPOINTER THEN
1208
            ELSIF  e._type.typ = PROG.tPOINTER THEN
1181
                ASSERT(ARITH.setInt(e.value, e.type.base.num))
1209
                ASSERT(ARITH.setInt(e.value, e._type.base.num))
Line 1182... Line 1210...
1182
            ELSE
1210
            ELSE
1183
                PARS.error(pos, 52)
1211
                PARS.error(pos, 52)
1184
            END;
1212
            END;
1185
            e.obj := eCONST;
1213
            e.obj := eCONST;
Line 1186... Line 1214...
1186
            e.type := tINTEGER
1214
            e._type := tINTEGER
1187
 
1215
 
1188
        |PROG.sysINF:
1216
        |PROG.sysINF:
1189
            PARS.check(IL.inf(), pos, 41);
1217
            IL.AddCmd2(IL.opINF, pos.line, pos.col);
1190
            e.obj := eEXPR;
1218
            e.obj := eEXPR;
1191
            e.type := tREAL
1219
            e._type := tREAL
Line 1192... Line 1220...
1192
 
1220
 
Line 1193... Line 1221...
1193
        |PROG.sysSIZE:
1221
        |PROG.sysSIZE:
Line 1213... Line 1241...
1213
END stProc;
1241
END stProc;
Line 1214... Line 1242...
1214
 
1242
 
1215
 
1243
 
1216
PROCEDURE ActualParameters (parser: PARS.PARSER; VAR e: PARS.EXPR);
1244
PROCEDURE ActualParameters (parser: PARS.PARSER; VAR e: PARS.EXPR);
1217
VAR
1245
VAR
1218
    proc:  PROG.TYPE_;
1246
    proc:  PROG._TYPE;
1219
    param: LISTS.ITEM;
1247
    param: LISTS.ITEM;
Line 1220... Line 1248...
1220
    e1:    PARS.EXPR;
1248
    e1:    PARS.EXPR;
1221
    pos:   PARS.POSITION;
1249
    pos:   PARS.POSITION;
Line 1222... Line 1250...
1222
 
1250
 
1223
BEGIN
1251
BEGIN
1224
    ASSERT(parser.sym = SCAN.lxLROUND);
1252
    ASSERT(parser.sym = SCAN.lxLROUND);
1225
 
1253
 
Line 1226... Line 1254...
1226
    IF (e.obj IN {ePROC, eIMP}) OR isExpr(e) THEN
1254
    IF (e.obj IN {ePROC, eIMP}) OR isExpr(e) THEN
1227
        proc := e.type;
1255
        proc := e._type;
Line 1249... Line 1277...
1249
 
1277
 
1250
        PARS.checklex(parser, SCAN.lxRROUND);
1278
        PARS.checklex(parser, SCAN.lxRROUND);
Line 1251... Line 1279...
1251
        PARS.Next(parser);
1279
        PARS.Next(parser);
1252
 
1280
 
Line 1253... Line 1281...
1253
        e.obj := eEXPR;
1281
        e.obj := eEXPR;
1254
        e.type := proc.base
1282
        e._type := proc.base
1255
 
1283
 
1256
    ELSIF e.obj IN {eSTPROC, eSTFUNC, eSYSPROC, eSYSFUNC} THEN
1284
    ELSIF e.obj IN {eSTPROC, eSTFUNC, eSYSPROC, eSYSFUNC} THEN
Line 1263... Line 1291...
1263
 
1291
 
1264
 
1292
 
1265
PROCEDURE qualident (parser: PARS.PARSER; VAR e: PARS.EXPR);
1293
PROCEDURE qualident (parser: PARS.PARSER; VAR e: PARS.EXPR);
1266
VAR
1294
VAR
1267
    ident:  PROG.IDENT;
1295
    ident: PROG.IDENT;
Line 1268... Line 1296...
1268
    import: BOOLEAN;
1296
    imp:   BOOLEAN;
1269
    pos:    PARS.POSITION;
1297
    pos:   PARS.POSITION;
1270
 
1298
 
1271
BEGIN
1299
BEGIN
1272
    PARS.checklex(parser, SCAN.lxIDENT);
1300
    PARS.checklex(parser, SCAN.lxIDENT);
1273
    getpos(parser, pos);
1301
    getpos(parser, pos);
1274
    import := FALSE;
1302
    imp := FALSE;
1275
    ident := PROG.getIdent(parser.unit, parser.lex.ident, FALSE);
1303
    ident := PROG.getIdent(parser.unit, parser.lex.ident, FALSE);
1276
    PARS.check1(ident # NIL, parser, 48);
1304
    PARS.check1(ident # NIL, parser, 48);
1277
    IF ident.typ = PROG.idMODULE THEN
1305
    IF ident.typ = PROG.idMODULE THEN
1278
        PARS.ExpectSym(parser, SCAN.lxPOINT);
1306
        PARS.ExpectSym(parser, SCAN.lxPOINT);
1279
        PARS.ExpectSym(parser, SCAN.lxIDENT);
1307
        PARS.ExpectSym(parser, SCAN.lxIDENT);
1280
        ident := PROG.getIdent(ident.unit, parser.lex.ident, FALSE);
1308
        ident := PROG.getIdent(ident.unit, parser.lex.ident, FALSE);
1281
        PARS.check1((ident # NIL) & ident.export, parser, 48);
1309
        PARS.check1((ident # NIL) & ident.export, parser, 48);
Line 1282... Line 1310...
1282
        import := TRUE
1310
        imp := TRUE
1283
    END;
1311
    END;
Line 1284... Line 1312...
1284
    PARS.Next(parser);
1312
    PARS.Next(parser);
1285
 
1313
 
1286
    e.readOnly := FALSE;
1314
    e.readOnly := FALSE;
1287
    e.ident := ident;
1315
    e.ident := ident;
1288
 
1316
 
1289
    CASE ident.typ OF
1317
    CASE ident.typ OF
1290
    |PROG.idCONST:
1318
    |PROG.idCONST:
1291
        e.obj   := eCONST;
1319
        e.obj   := eCONST;
1292
        e.type  := ident.type;
1320
        e._type := ident._type;
1293
        e.value := ident.value
1321
        e.value := ident.value
1294
    |PROG.idTYPE:
1322
    |PROG.idTYPE:
1295
        e.obj  := eTYPE;
1323
        e.obj   := eTYPE;
1296
        e.type := ident.type
1324
        e._type := ident._type
1297
    |PROG.idVAR:
1325
    |PROG.idVAR:
1298
        e.obj  := eVAR;
1326
        e.obj   := eVAR;
1299
        e.type := ident.type;
1327
        e._type := ident._type;
1300
        e.readOnly := import
1328
        e.readOnly := imp
1301
    |PROG.idPROC:
1329
    |PROG.idPROC:
1302
        e.obj   := ePROC;
1330
        e.obj   := ePROC;
1303
        e.type  := ident.type
1331
        e._type := ident._type
1304
    |PROG.idIMP:
1332
    |PROG.idIMP:
1305
        e.obj   := eIMP;
1333
        e.obj   := eIMP;
1306
        e.type  := ident.type
1334
        e._type := ident._type
1307
    |PROG.idVPAR:
1335
    |PROG.idVPAR:
1308
        e.type := ident.type;
1336
        e._type := ident._type;
1309
        IF e.type.typ = PROG.tRECORD THEN
1337
        IF e._type.typ = PROG.tRECORD THEN
1310
            e.obj := eVREC
1338
            e.obj := eVREC
1311
        ELSE
1339
        ELSE
1312
            e.obj := eVPAR
1340
            e.obj := eVPAR
1313
        END
1341
        END
1314
    |PROG.idPARAM:
1342
    |PROG.idPARAM:
-
 
1343
        e.obj := ePARAM;
1315
        e.obj  := ePARAM;
1344
        e._type := ident._type;
1316
        e.type := ident.type;
1345
        e.readOnly := (e._type.typ IN {PROG.tRECORD, PROG.tARRAY})
1317
        e.readOnly := (e.type.typ IN {PROG.tRECORD, PROG.tARRAY})
1346
    |PROG.idSTPROC:
-
 
1347
        e.obj    := eSTPROC;
1318
    |PROG.idSTPROC:
1348
        e._type  := ident._type;
1319
        e.obj    := eSTPROC;
1349
        e.stproc := ident.stproc
1320
        e.stproc := ident.stproc
1350
    |PROG.idSTFUNC:
-
 
1351
        e.obj    := eSTFUNC;
1321
    |PROG.idSTFUNC:
1352
        e._type  := ident._type;
1322
        e.obj    := eSTFUNC;
1353
        e.stproc := ident.stproc
1323
        e.stproc := ident.stproc
1354
    |PROG.idSYSPROC:
1324
    |PROG.idSYSPROC:
1355
        e.obj    := eSYSPROC;
-
 
1356
        e._type  := ident._type;
1325
        e.obj    := eSYSPROC;
1357
        e.stproc := ident.stproc
1326
        e.stproc := ident.stproc
1358
    |PROG.idSYSFUNC:
1327
    |PROG.idSYSFUNC:
1359
        PARS.check(~parser.constexp, pos, 109);
1328
        PARS.check(~parser.constexp, pos, 109);
1360
        e.obj    := eSYSFUNC;
Line 1343... Line 1375...
1343
VAR
1375
VAR
1344
    label: INTEGER;
1376
    label: INTEGER;
Line 1345... Line 1377...
1345
 
1377
 
1346
BEGIN
1378
BEGIN
1347
    IF load THEN
1379
    IF load THEN
1348
        IL.load(e.type.size)
1380
        IL.load(e._type.size)
Line 1349... Line 1381...
1349
    END;
1381
    END;
1350
 
1382
 
1351
    IF chkPTR IN Options.checking THEN
1383
    IF chkPTR IN Options.checking THEN
1352
        label := IL.NewLabel();
1384
        label := IL.NewLabel();
1353
        IL.AddJmpCmd(IL.opJNZ, label);
1385
        IL.AddJmpCmd(IL.opJNZ1, label);
1354
        IL.OnError(pos.line, error);
1386
        IL.OnError(pos.line, error);
1355
        IL.SetLabel(label)
1387
        IL.SetLabel(label)
Line 1371... Line 1403...
1371
        PROCEDURE OpenArray (e: PARS.EXPR);
1403
        PROCEDURE OpenArray (e: PARS.EXPR);
1372
        VAR
1404
        VAR
1373
            offset, n: INTEGER;
1405
            offset, n: INTEGER;
1374
        BEGIN
1406
        BEGIN
1375
            offset := e.ident.offset;
1407
            offset := e.ident.offset;
1376
            n := PROG.Dim(e.type);
1408
            n := PROG.Dim(e._type);
1377
            WHILE n >= 0 DO
1409
            WHILE n >= 0 DO
1378
                IL.AddCmd(IL.opVADR, offset);
1410
                IL.AddCmd(IL.opVADR, offset);
1379
                DEC(offset);
1411
                DEC(offset);
1380
                DEC(n)
1412
                DEC(n)
1381
            END
1413
            END
1382
        END OpenArray;
1414
        END OpenArray;
Line 1383... Line 1415...
1383
 
1415
 
1384
 
1416
 
1385
    BEGIN
1417
    BEGIN
1386
        IF e.obj = eVAR THEN
1418
        IF e.obj = eVAR THEN
1387
            offset := PROG.getOffset(PARS.program, e.ident);
1419
            offset := PROG.getOffset(e.ident);
1388
            IF e.ident.global THEN
1420
            IF e.ident.global THEN
1389
                IL.AddCmd(IL.opGADR, offset)
1421
                IL.AddCmd(IL.opGADR, offset)
1390
            ELSE
1422
            ELSE
1391
                IL.AddCmd(IL.opLADR, -offset)
1423
                IL.AddCmd(IL.opLADR, -offset)
1392
            END
1424
            END
1393
        ELSIF e.obj = ePARAM THEN
1425
        ELSIF e.obj = ePARAM THEN
1394
            IF (e.type.typ = PROG.tRECORD) OR ((e.type.typ = PROG.tARRAY) & (e.type.length > 0)) THEN
1426
            IF (e._type.typ = PROG.tRECORD) OR ((e._type.typ = PROG.tARRAY) & (e._type.length > 0)) THEN
1395
                IL.AddCmd(IL.opVADR, e.ident.offset)
1427
                IL.AddCmd(IL.opVADR, e.ident.offset)
1396
            ELSIF PROG.isOpenArray(e.type) THEN
1428
            ELSIF PROG.isOpenArray(e._type) THEN
1397
                OpenArray(e)
1429
                OpenArray(e)
1398
            ELSE
1430
            ELSE
1399
                IL.AddCmd(IL.opLADR, e.ident.offset)
1431
                IL.AddCmd(IL.opLADR, e.ident.offset)
1400
            END
1432
            END
1401
        ELSIF e.obj IN {eVPAR, eVREC} THEN
1433
        ELSIF e.obj IN {eVPAR, eVREC} THEN
1402
            IF PROG.isOpenArray(e.type) THEN
1434
            IF PROG.isOpenArray(e._type) THEN
1403
                OpenArray(e)
1435
                OpenArray(e)
1404
            ELSE
1436
            ELSE
1405
                IL.AddCmd(IL.opVADR, e.ident.offset)
1437
                IL.AddCmd(IL.opVADR, e.ident.offset)
Line 1409... Line 1441...
1409
 
1441
 
1410
 
1442
 
1411
    PROCEDURE OpenIdx (parser: PARS.PARSER; pos: PARS.POSITION; e: PARS.EXPR);
1443
    PROCEDURE OpenIdx (parser: PARS.PARSER; pos: PARS.POSITION; e: PARS.EXPR);
1412
    VAR
1444
    VAR
Line 1413... Line 1445...
1413
        label, offset, n, k: INTEGER;
1445
        label, offset, n, k: INTEGER;
Line 1414... Line 1446...
1414
        type: PROG.TYPE_;
1446
        _type: PROG._TYPE;
1415
 
1447
 
Line 1422... Line 1454...
1422
            IL.SetLabel(label)
1454
            IL.SetLabel(label)
1423
        ELSE
1455
        ELSE
1424
            IL.AddCmd(IL.opCHKIDX2, -1)
1456
            IL.AddCmd(IL.opCHKIDX2, -1)
1425
        END;
1457
        END;
Line 1426... Line 1458...
1426
 
1458
 
1427
        type := PROG.OpenBase(e.type);
1459
        _type := PROG.OpenBase(e._type);
1428
        IF type.size # 1 THEN
1460
        IF _type.size # 1 THEN
1429
            IL.AddCmd(IL.opMULC, type.size)
1461
            IL.AddCmd(IL.opMULC, _type.size)
1430
        END;
1462
        END;
1431
        n := PROG.Dim(e.type) - 1;
1463
        n := PROG.Dim(e._type) - 1;
1432
        k := n;
1464
        k := n;
1433
        WHILE n > 0 DO
1465
        WHILE n > 0 DO
1434
            IL.AddCmd0(IL.opMUL);
1466
            IL.AddCmd0(IL.opMUL);
1435
            DEC(n)
1467
            DEC(n)
Line 1456... Line 1488...
1456
        LoadAdr(e)
1488
        LoadAdr(e)
1457
    END;
1489
    END;
Line 1458... Line 1490...
1458
 
1490
 
1459
    WHILE parser.sym = SCAN.lxPOINT DO
1491
    WHILE parser.sym = SCAN.lxPOINT DO
1460
        getpos(parser, pos);
1492
        getpos(parser, pos);
1461
        PARS.check1(isExpr(e) & (e.type.typ IN {PROG.tRECORD, PROG.tPOINTER}), parser, 73);
1493
        PARS.check1(isExpr(e) & (e._type.typ IN {PROG.tRECORD, PROG.tPOINTER}), parser, 73);
1462
        IF e.type.typ = PROG.tPOINTER THEN
1494
        IF e._type.typ = PROG.tPOINTER THEN
1463
            deref(pos, e, TRUE, errPTR)
1495
            deref(pos, e, TRUE, errPTR)
1464
        END;
1496
        END;
1465
        PARS.ExpectSym(parser, SCAN.lxIDENT);
1497
        PARS.ExpectSym(parser, SCAN.lxIDENT);
1466
        IF e.type.typ = PROG.tPOINTER THEN
1498
        IF e._type.typ = PROG.tPOINTER THEN
1467
            e.type := e.type.base;
1499
            e._type := e._type.base;
1468
            e.readOnly := FALSE
1500
            e.readOnly := FALSE
1469
        END;
1501
        END;
1470
        field := PROG.getField(e.type, parser.lex.ident, parser.unit);
1502
        field := PROG.getField(e._type, parser.lex.ident, parser.unit);
1471
        PARS.check1(field # NIL, parser, 74);
1503
        PARS.check1(field # NIL, parser, 74);
1472
        e.type := field.type;
1504
        e._type := field._type;
1473
        IF e.obj = eVREC THEN
1505
        IF e.obj = eVREC THEN
1474
            e.obj := eVPAR
1506
            e.obj := eVPAR
1475
        END;
1507
        END;
1476
        IF field.offset # 0 THEN
1508
        IF field.offset # 0 THEN
1477
            IL.AddCmd(IL.opADDR, field.offset)
1509
            IL.AddCmd(IL.opADDC, field.offset)
1478
        END;
1510
        END;
1479
        PARS.Next(parser);
1511
        PARS.Next(parser);
Line 1480... Line 1512...
1480
        e.ident := NIL
1512
        e.ident := NIL
Line 1487... Line 1519...
1487
            NextPos(parser, pos);
1519
            NextPos(parser, pos);
1488
            PExpression(parser, idx);
1520
            PExpression(parser, idx);
1489
            PARS.check(isInt(idx), pos, 76);
1521
            PARS.check(isInt(idx), pos, 76);
Line 1490... Line 1522...
1490
 
1522
 
1491
            IF idx.obj = eCONST THEN
1523
            IF idx.obj = eCONST THEN
1492
                IF e.type.length > 0 THEN
1524
                IF e._type.length > 0 THEN
1493
                    PARS.check(ARITH.range(idx.value, 0, e.type.length - 1), pos, 83);
1525
                    PARS.check(ARITH.range(idx.value, 0, e._type.length - 1), pos, 83);
1494
                    IF ARITH.Int(idx.value) > 0 THEN
1526
                    IF ARITH.Int(idx.value) > 0 THEN
1495
                        IL.AddCmd(IL.opADDR, ARITH.Int(idx.value) * e.type.base.size)
1527
                        IL.AddCmd(IL.opADDC, ARITH.Int(idx.value) * e._type.base.size)
1496
                    END
1528
                    END
1497
                ELSE
1529
                ELSE
1498
                    PARS.check(ARITH.range(idx.value, 0, UTILS.target.maxInt), pos, 83);
1530
                    PARS.check(ARITH.range(idx.value, 0, UTILS.target.maxInt), pos, 83);
1499
                    LoadConst(idx);
1531
                    LoadConst(idx);
1500
                    OpenIdx(parser, pos, e)
1532
                    OpenIdx(parser, pos, e)
1501
                END
1533
                END
1502
            ELSE
1534
            ELSE
1503
                IF e.type.length > 0 THEN
1535
                IF e._type.length > 0 THEN
1504
                    IF chkIDX IN Options.checking THEN
1536
                    IF chkIDX IN Options.checking THEN
1505
                        CheckRange(e.type.length, pos.line, errIDX)
1537
                        CheckRange(e._type.length, pos.line, errIDX)
1506
                    END;
1538
                    END;
1507
                    IF e.type.base.size # 1 THEN
1539
                    IF e._type.base.size # 1 THEN
1508
                        IL.AddCmd(IL.opMULC, e.type.base.size)
1540
                        IL.AddCmd(IL.opMULC, e._type.base.size)
1509
                    END;
1541
                    END;
1510
                    IL.AddCmd0(IL.opADD)
1542
                    IL.AddCmd0(IL.opADD)
1511
                ELSE
1543
                ELSE
1512
                    OpenIdx(parser, pos, e)
1544
                    OpenIdx(parser, pos, e)
1513
                END
1545
                END
Line 1514... Line 1546...
1514
            END;
1546
            END;
Line 1515... Line 1547...
1515
 
1547
 
Line 1516... Line 1548...
1516
            e.type := e.type.base
1548
            e._type := e._type.base
1517
 
1549
 
Line 1523... Line 1555...
1523
 
1555
 
1524
    ELSIF parser.sym = SCAN.lxCARET DO
1556
    ELSIF parser.sym = SCAN.lxCARET DO
1525
        getpos(parser, pos);
1557
        getpos(parser, pos);
1526
        PARS.check1(isPtr(e), parser, 77);
1558
        PARS.check1(isPtr(e), parser, 77);
1527
        deref(pos, e, TRUE, errPTR);
1559
        deref(pos, e, TRUE, errPTR);
1528
        e.type := e.type.base;
1560
        e._type := e._type.base;
1529
        e.readOnly := FALSE;
1561
        e.readOnly := FALSE;
1530
        PARS.Next(parser);
1562
        PARS.Next(parser);
1531
        e.ident := NIL;
1563
        e.ident := NIL;
Line 1532... Line 1564...
1532
        e.obj := eVREC
1564
        e.obj := eVREC
Line 1533... Line 1565...
1533
 
1565
 
1534
    ELSIF (parser.sym = SCAN.lxLROUND) & isExpr(e) & (e.type.typ IN {PROG.tRECORD, PROG.tPOINTER}) DO
1566
    ELSIF (parser.sym = SCAN.lxLROUND) & isExpr(e) & (e._type.typ IN {PROG.tRECORD, PROG.tPOINTER}) DO
1535
 
1567
 
1536
        IF e.type.typ = PROG.tRECORD THEN
1568
        IF e._type.typ = PROG.tRECORD THEN
1537
            PARS.check1(e.obj = eVREC, parser, 78)
1569
            PARS.check1(e.obj = eVREC, parser, 78)
1538
        END;
1570
        END;
Line 1539... Line 1571...
1539
        NextPos(parser, pos);
1571
        NextPos(parser, pos);
1540
        qualident(parser, t);
1572
        qualident(parser, t);
1541
        PARS.check(t.obj = eTYPE, pos, 79);
1573
        PARS.check(t.obj = eTYPE, pos, 79);
1542
 
1574
 
1543
        IF e.type.typ = PROG.tRECORD THEN
1575
        IF e._type.typ = PROG.tRECORD THEN
1544
            PARS.check(t.type.typ = PROG.tRECORD, pos, 80);
1576
            PARS.check(t._type.typ = PROG.tRECORD, pos, 80);
1545
            IF chkGUARD IN Options.checking THEN
1577
            IF chkGUARD IN Options.checking THEN
1546
                IF e.ident = NIL THEN
1578
                IF e.ident = NIL THEN
1547
                    IL.TypeGuard(IL.opTYPEGD, t.type.num, pos.line, errGUARD)
1579
                    IL.TypeGuard(IL.opTYPEGD, t._type.num, pos.line, errGUARD)
1548
                ELSE
1580
                ELSE
1549
                    IL.AddCmd(IL.opVADR, e.ident.offset - 1);
1581
                    IL.AddCmd(IL.opVADR, e.ident.offset - 1);
1550
                    IL.TypeGuard(IL.opTYPEGR, t.type.num, pos.line, errGUARD)
1582
                    IL.TypeGuard(IL.opTYPEGR, t._type.num, pos.line, errGUARD)
1551
                END
1583
                END
1552
            END;
1584
            END;
1553
        ELSE
1585
        ELSE
1554
            PARS.check(t.type.typ = PROG.tPOINTER, pos, 81);
1586
            PARS.check(t._type.typ = PROG.tPOINTER, pos, 81);
Line 1555... Line 1587...
1555
            IF chkGUARD IN Options.checking THEN
1587
            IF chkGUARD IN Options.checking THEN
Line 1556... Line 1588...
1556
                IL.TypeGuard(IL.opTYPEGP, t.type.base.num, pos.line, errGUARD)
1588
                IL.TypeGuard(IL.opTYPEGP, t._type.base.num, pos.line, errGUARD)
Line 1557... Line 1589...
1557
            END
1589
            END
1558
        END;
1590
        END;
Line 1559... Line 1591...
1559
 
1591
 
Line 1560... Line 1592...
1560
        PARS.check(PROG.isBaseOf(e.type, t.type), pos, 82);
1592
        PARS.check(PROG.isBaseOf(e._type, t._type), pos, 82);
Line 1561... Line 1593...
1561
 
1593
 
1562
        e.type := t.type;
1594
        e._type := t._type;
1563
 
1595
 
1564
        PARS.checklex(parser, SCAN.lxRROUND);
1596
        PARS.checklex(parser, SCAN.lxRROUND);
1565
        PARS.Next(parser)
1597
        PARS.Next(parser)
1566
 
1598
 
Line 1592... Line 1624...
1592
    ELSE
1624
    ELSE
1593
        callconv := IL.call_stack;
1625
        callconv := IL.call_stack;
1594
        fparSize := 0
1626
        fparSize := 0
1595
    END;
1627
    END;
1596
    IL.setlast(begcall);
1628
    IL.setlast(begcall);
1597
    fregs := IL.precall(isfloat);
1629
    IL.AddCmd(IL.opPRECALL, ORD(isfloat));
Line 1598... Line 1630...
1598
 
1630
 
1599
    IF cconv IN {PROG._ccall16, PROG.ccall16} THEN
1631
    IF cconv IN {PROG._ccall16, PROG.ccall16} THEN
1600
        IL.AddCmd(IL.opALIGN16, parSize)
1632
        IL.AddCmd(IL.opALIGN16, parSize)
1601
    ELSIF cconv IN {PROG._win64, PROG.win64} THEN
1633
    ELSIF cconv IN {PROG._win64, PROG.win64} THEN
Line 1604... Line 1636...
1604
        IL.AddCmd(IL.opSYSVALIGN16, parSize + stk_par)
1636
        IL.AddCmd(IL.opSYSVALIGN16, parSize + stk_par)
1605
    END;
1637
    END;
1606
    IL.setlast(endcall.prev(IL.COMMAND));
1638
    IL.setlast(endcall.prev(IL.COMMAND));
Line 1607... Line 1639...
1607
 
1639
 
1608
    IF e.obj = eIMP THEN
1640
    IF e.obj = eIMP THEN
1609
        IL.CallImp(e.ident.import, callconv, fparSize)
1641
        IL.CallImp(e.ident._import, callconv, fparSize)
1610
    ELSIF e.obj = ePROC THEN
1642
    ELSIF e.obj = ePROC THEN
1611
        IL.Call(e.ident.proc.label, callconv, fparSize)
1643
        IL.Call(e.ident.proc.label, callconv, fparSize)
1612
    ELSIF isExpr(e) THEN
1644
    ELSIF isExpr(e) THEN
1613
        deref(pos, e, CallStat, errPROC);
1645
        deref(pos, e, CallStat, errPROC);
Line 1625... Line 1657...
1625
        IL.AddCmd0(IL.opPOPSP)
1657
        IL.AddCmd0(IL.opPOPSP)
1626
    ELSIF cconv IN {PROG._ccall, PROG.ccall, PROG.default16, PROG.code, PROG._code} THEN
1658
    ELSIF cconv IN {PROG._ccall, PROG.ccall, PROG.default16, PROG.code, PROG._code} THEN
1627
        IL.AddCmd(IL.opCLEANUP, parSize)
1659
        IL.AddCmd(IL.opCLEANUP, parSize)
1628
    END;
1660
    END;
Line 1629... Line 1661...
1629
 
1661
 
-
 
1662
    IF CallStat THEN
-
 
1663
        IL.AddCmd0(IL.opRES);
-
 
1664
        IL.drop
1630
    IF ~CallStat THEN
1665
    ELSE
1631
        IF isfloat THEN
1666
        IF isfloat THEN
1632
            PARS.check(IL.resf(fregs), pos, 41)
1667
            IL.AddCmd2(IL.opRESF, pos.line, pos.col)
1633
        ELSE
1668
        ELSE
1634
            IL.res(fregs)
1669
            IL.AddCmd0(IL.opRES)
1635
        END
1670
        END
1636
    END
1671
    END
Line 1637... Line 1672...
1637
END ProcCall;
1672
END ProcCall;
1638
 
1673
 
1639
 
1674
 
1640
PROCEDURE expression (parser: PARS.PARSER; VAR e: PARS.EXPR);
-
 
1641
VAR
-
 
1642
    pos, pos0, pos1: PARS.POSITION;
1675
PROCEDURE expression (parser: PARS.PARSER; VAR e: PARS.EXPR);
1643
 
1676
VAR
1644
    op:        INTEGER;
1677
    pos, pos0, pos1: PARS.POSITION;
1645
    e1:        PARS.EXPR;
-
 
Line 1646... Line 1678...
1646
    constant:  BOOLEAN;
1678
    e1: PARS.EXPR;
1647
    operator:  ARITH.RELATION;
1679
    op, cmp, error: INTEGER;
1648
    error:     INTEGER;
1680
    constant, eq: BOOLEAN;
Line 1699... Line 1731...
1699
            IF e1.obj = eCONST THEN
1731
            IF e1.obj = eCONST THEN
1700
                e2 := e1
1732
                e2 := e1
1701
            END
1733
            END
1702
        END;
1734
        END;
Line 1703... Line 1735...
1703
 
1735
 
Line 1704... Line 1736...
1704
        e.type := tSET;
1736
        e._type := tSET;
1705
 
1737
 
1706
        IF (e1.obj = eCONST) & (e2.obj = eCONST) THEN
1738
        IF (e1.obj = eCONST) & (e2.obj = eCONST) THEN
1707
            ARITH.constrSet(e.value, e1.value, e2.value);
1739
            ARITH.constrSet(e.value, e1.value, e2.value);
Line 1730... Line 1762...
1730
 
1762
 
1731
    BEGIN
1763
    BEGIN
Line 1732... Line 1764...
1732
        ASSERT(parser.sym = SCAN.lxLCURLY);
1764
        ASSERT(parser.sym = SCAN.lxLCURLY);
1733
 
1765
 
1734
        e.obj := eCONST;
1766
        e.obj := eCONST;
Line 1735... Line 1767...
1735
        e.type := tSET;
1767
        e._type := tSET;
1736
        ARITH.emptySet(e.value);
1768
        ARITH.emptySet(e.value);
1737
 
1769
 
Line 1750... Line 1782...
1750
                element(parser, e1);
1782
                element(parser, e1);
1751
                IF (e.obj = eCONST) & (e1.obj = eCONST) THEN
1783
                IF (e.obj = eCONST) & (e1.obj = eCONST) THEN
1752
                    ARITH.opSet(e.value, e1.value, "+")
1784
                    ARITH.opSet(e.value, e1.value, "+")
1753
                ELSE
1785
                ELSE
1754
                    IF e.obj = eCONST THEN
1786
                    IF e.obj = eCONST THEN
1755
                        IL.AddCmd(IL.opADDSL, ARITH.Int(e.value))
1787
                        IL.AddCmd(IL.opADDSC, ARITH.Int(e.value))
1756
                    ELSIF e1.obj = eCONST THEN
1788
                    ELSIF e1.obj = eCONST THEN
1757
                        IL.AddCmd(IL.opADDSR, ARITH.Int(e1.value))
1789
                        IL.AddCmd(IL.opADDSC, ARITH.Int(e1.value))
1758
                    ELSE
1790
                    ELSE
1759
                        IL.AddCmd0(IL.opADDS)
1791
                        IL.AddCmd0(IL.opADDS)
1760
                    END;
1792
                    END;
1761
                    e.obj := eEXPR
1793
                    e.obj := eEXPR
1762
                END
1794
                END
Line 1771... Line 1803...
1771
    VAR
1803
    VAR
1772
        sym:      INTEGER;
1804
        sym:      INTEGER;
1773
        pos:      PARS.POSITION;
1805
        pos:      PARS.POSITION;
1774
        e1:       PARS.EXPR;
1806
        e1:       PARS.EXPR;
1775
        isfloat:  BOOLEAN;
1807
        isfloat:  BOOLEAN;
1776
        fregs:    INTEGER;
-
 
Line 1777... Line 1808...
1777
 
1808
 
1778
 
1809
 
1779
        PROCEDURE LoadVar (e: PARS.EXPR; parser: PARS.PARSER; pos: PARS.POSITION);
1810
        PROCEDURE LoadVar (e: PARS.EXPR; parser: PARS.PARSER; pos: PARS.POSITION);
1780
        BEGIN
1811
        BEGIN
1781
            IF ~(e.type.typ IN {PROG.tRECORD, PROG.tARRAY}) THEN
1812
            IF ~(e._type.typ IN {PROG.tRECORD, PROG.tARRAY}) THEN
1782
                IF e.type = tREAL THEN
1813
                IF e._type = tREAL THEN
1783
                    PARS.check(IL.loadf(), pos, 41)
1814
                    IL.AddCmd2(IL.opLOADF, pos.line, pos.col)
1784
                ELSE
1815
                ELSE
1785
                    IL.load(e.type.size)
1816
                    IL.load(e._type.size)
1786
                END
1817
                END
Line 1792... Line 1823...
1792
        sym := parser.sym;
1823
        sym := parser.sym;
Line 1793... Line 1824...
1793
 
1824
 
1794
        IF (sym = SCAN.lxINTEGER) OR (sym = SCAN.lxHEX) OR (sym = SCAN.lxFLOAT) OR (sym = SCAN.lxCHAR) OR (sym = SCAN.lxSTRING) THEN
1825
        IF (sym = SCAN.lxINTEGER) OR (sym = SCAN.lxHEX) OR (sym = SCAN.lxFLOAT) OR (sym = SCAN.lxCHAR) OR (sym = SCAN.lxSTRING) THEN
1795
            e.obj := eCONST;
1826
            e.obj := eCONST;
1796
            e.value := parser.lex.value;
1827
            e.value := parser.lex.value;
1797
            e.type := PROG.getType(PARS.program, e.value.typ);
1828
            e._type := PROG.getType(e.value.typ);
Line 1798... Line 1829...
1798
            PARS.Next(parser)
1829
            PARS.Next(parser)
1799
 
1830
 
1800
        ELSIF sym = SCAN.lxNIL THEN
1831
        ELSIF sym = SCAN.lxNIL THEN
1801
            e.obj  := eCONST;
1832
            e.obj  := eCONST;
Line 1802... Line 1833...
1802
            e.type := PARS.program.stTypes.tNIL;
1833
            e._type := PROG.program.stTypes.tNIL;
1803
            PARS.Next(parser)
1834
            PARS.Next(parser)
1804
 
1835
 
1805
        ELSIF (sym = SCAN.lxTRUE) OR (sym = SCAN.lxFALSE) THEN
1836
        ELSIF (sym = SCAN.lxTRUE) OR (sym = SCAN.lxFALSE) THEN
1806
            e.obj := eCONST;
1837
            e.obj := eCONST;
Line 1807... Line 1838...
1807
            ARITH.setbool(e.value, sym = SCAN.lxTRUE);
1838
            ARITH.setbool(e.value, sym = SCAN.lxTRUE);
1808
            e.type := tBOOLEAN;
1839
            e._type := tBOOLEAN;
Line 1821... Line 1852...
1821
                LoadVar(e, parser, pos)
1852
                LoadVar(e, parser, pos)
1822
            END;
1853
            END;
1823
            IF parser.sym = SCAN.lxLROUND THEN
1854
            IF parser.sym = SCAN.lxLROUND THEN
1824
                e1 := e;
1855
                e1 := e;
1825
                ActualParameters(parser, e);
1856
                ActualParameters(parser, e);
1826
                PARS.check(e.type # NIL, pos, 59);
1857
                PARS.check(e._type # NIL, pos, 59);
1827
                isfloat := e.type = tREAL;
1858
                isfloat := e._type = tREAL;
1828
                IF e1.obj IN {ePROC, eIMP} THEN
1859
                IF e1.obj IN {ePROC, eIMP} THEN
1829
                    ProcCall(e1, e1.ident.type, isfloat, fregs, parser, pos, FALSE)
1860
                    ProcCall(e1, e1.ident._type, isfloat, parser, pos, FALSE)
1830
                ELSIF isExpr(e1) THEN
1861
                ELSIF isExpr(e1) THEN
1831
                    ProcCall(e1, e1.type, isfloat, fregs, parser, pos, FALSE)
1862
                    ProcCall(e1, e1._type, isfloat, parser, pos, FALSE)
1832
                END
1863
                END
1833
            END;
1864
            END;
1834
            IL.popBegEnd(begcall, endcall)
1865
            IL.popBegEnd(begcall, endcall)
Line 1835... Line 1866...
1835
 
1866
 
Line 1882... Line 1913...
1882
                    END;
1913
                    END;
Line 1883... Line 1914...
1883
 
1914
 
1884
                    IF e.obj = eCONST THEN
1915
                    IF e.obj = eCONST THEN
1885
                        IL.Const(ORD(ARITH.getBool(e.value)))
1916
                        IL.Const(ORD(ARITH.getBool(e.value)))
1886
                    END;
-
 
1887
                    IL.AddCmd0(IL.opACC);
-
 
1888
                    IL.AddJmpCmd(IL.opJZ, label);
1917
                    END;
1889
                    IL.drop
1918
                    IL.AndOrOpt(label)
1890
                END
1919
                END
Line 1891... Line 1920...
1891
            END;
1920
            END;
Line 1912... Line 1941...
1912
                        ELSE
1941
                        ELSE
1913
                            IL.AddCmd0(IL.opMUL)
1942
                            IL.AddCmd0(IL.opMUL)
1914
                        END
1943
                        END
1915
                    ELSIF isReal(e) THEN
1944
                    ELSIF isReal(e) THEN
1916
                        IF e.obj = eCONST THEN
1945
                        IF e.obj = eCONST THEN
1917
                            IL.Float(ARITH.Float(e.value))
1946
                            Float(parser, e)
1918
                        ELSIF e1.obj = eCONST THEN
1947
                        ELSIF e1.obj = eCONST THEN
1919
                            IL.Float(ARITH.Float(e1.value))
1948
                            Float(parser, e1)
1920
                        END;
1949
                        END;
1921
                        IL.fbinop(IL.opMULF)
1950
                        IL.AddCmd0(IL.opMULF)
1922
                    ELSIF isSet(e) THEN
1951
                    ELSIF isSet(e) THEN
1923
                        IF e.obj = eCONST THEN
1952
                        IF e.obj = eCONST THEN
1924
                            IL.AddCmd(IL.opMULSC, ARITH.Int(e.value))
1953
                            IL.AddCmd(IL.opMULSC, ARITH.Int(e.value))
1925
                        ELSIF e1.obj = eCONST THEN
1954
                        ELSIF e1.obj = eCONST THEN
1926
                            IL.AddCmd(IL.opMULSC, ARITH.Int(e1.value))
1955
                            IL.AddCmd(IL.opMULSC, ARITH.Int(e1.value))
Line 1944... Line 1973...
1944
                    END
1973
                    END
Line 1945... Line 1974...
1945
 
1974
 
1946
                ELSE
1975
                ELSE
1947
                    IF isReal(e) THEN
1976
                    IF isReal(e) THEN
1948
                        IF e.obj = eCONST THEN
1977
                        IF e.obj = eCONST THEN
1949
                            IL.Float(ARITH.Float(e.value));
1978
                            Float(parser, e);
1950
                            IL.fbinop(IL.opDIVFI)
1979
                            IL.AddCmd0(IL.opDIVFI)
1951
                        ELSIF e1.obj = eCONST THEN
1980
                        ELSIF e1.obj = eCONST THEN
1952
                            IL.Float(ARITH.Float(e1.value));
1981
                            Float(parser, e1);
1953
                            IL.fbinop(IL.opDIVF)
1982
                            IL.AddCmd0(IL.opDIVF)
1954
                        ELSE
1983
                        ELSE
1955
                            IL.fbinop(IL.opDIVF)
1984
                            IL.AddCmd0(IL.opDIVF)
1956
                        END
1985
                        END
1957
                    ELSIF isSet(e) THEN
1986
                    ELSIF isSet(e) THEN
1958
                        IF e.obj = eCONST THEN
1987
                        IF e.obj = eCONST THEN
1959
                            IL.AddCmd(IL.opDIVSC, ARITH.Int(e.value))
1988
                            IL.AddCmd(IL.opDIVSC, ARITH.Int(e.value))
Line 2005... Line 2034...
2005
                    ARITH.opBoolean(e.value, e1.value, "&")
2034
                    ARITH.opBoolean(e.value, e1.value, "&")
2006
                ELSE
2035
                ELSE
2007
                    e.obj := eEXPR;
2036
                    e.obj := eEXPR;
2008
                    IF e1.obj = eCONST THEN
2037
                    IF e1.obj = eCONST THEN
2009
                        IL.Const(ORD(ARITH.getBool(e1.value)))
2038
                        IL.Const(ORD(ARITH.getBool(e1.value)))
2010
                    END;
2039
                    END
2011
                    IL.AddCmd0(IL.opACC)
-
 
2012
                END
2040
                END
Line 2013... Line 2041...
2013
 
2041
 
2014
            END
2042
            END
Line 2015... Line 2043...
2015
        END;
2043
        END;
-
 
2044
 
-
 
2045
        IF label # -1 THEN
2016
 
2046
            label1 := IL.NewLabel();
-
 
2047
            IL.AddJmpCmd(IL.opJNZ, label1);
-
 
2048
            IL.SetLabel(label);
-
 
2049
            IL.Const(0);
-
 
2050
            IL.drop;
-
 
2051
            label := IL.NewLabel();
-
 
2052
            IL.AddJmpCmd(IL.opJMP, label);
-
 
2053
            IL.SetLabel(label1);
-
 
2054
            IL.Const(1);
2017
        IF label # -1 THEN
2055
            IL.SetLabel(label);
2018
            IL.SetLabel(label)
2056
            IL.AddCmd0(IL.opAND)
Line 2019... Line 2057...
2019
        END
2057
        END
2020
    END term;
2058
    END term;
2021
 
2059
 
2022
 
2060
 
2023
    PROCEDURE SimpleExpression (parser: PARS.PARSER; VAR e: PARS.EXPR);
2061
    PROCEDURE SimpleExpression (parser: PARS.PARSER; VAR e: PARS.EXPR);
-
 
2062
    VAR
Line 2024... Line 2063...
2024
    VAR
2063
        pos: PARS.POSITION;
Line 2025... Line 2064...
2025
        pos: PARS.POSITION;
2064
        op:  INTEGER;
Line 2026... Line 2065...
2026
        op:  INTEGER;
2065
        e1:  PARS.EXPR;
2027
        e1:  PARS.EXPR;
2066
        s, s1: SCAN.LEXSTR;
2028
 
2067
 
Line 2079... Line 2118...
2079
                    END;
2118
                    END;
Line 2080... Line 2119...
2080
 
2119
 
2081
                    IF e.obj = eCONST THEN
2120
                    IF e.obj = eCONST THEN
2082
                        IL.Const(ORD(ARITH.getBool(e.value)))
2121
                        IL.Const(ORD(ARITH.getBool(e.value)))
2083
                    END;
2122
                    END;
2084
                    IL.AddCmd0(IL.opACC);
-
 
2085
                    IL.AddJmpCmd(IL.opJNZ, label);
2123
                    IL.not;
2086
                    IL.drop
2124
                    IL.AndOrOpt(label)
Line 2087... Line 2125...
2087
                END
2125
                END
Line 2088... Line 2126...
2088
 
2126
 
Line 2089... Line 2127...
2089
            END;
2127
            END;
2090
 
2128
 
Line 2091... Line 2129...
2091
            term(parser, e1);
2129
            term(parser, e1);
2092
 
-
 
2093
            CASE op OF
2130
 
2094
            |SCAN.lxPLUS, SCAN.lxMINUS:
2131
            CASE op OF
-
 
2132
            |SCAN.lxPLUS, SCAN.lxMINUS:
-
 
2133
 
2095
 
2134
                minus := op = SCAN.lxMINUS;
Line 2096... Line 2135...
2096
                IF op = SCAN.lxPLUS THEN
2135
                IF minus THEN
2097
                    op := ORD("+")
2136
                    op := ORD("-")
Line 2098... Line 2137...
2098
                ELSE
2137
                ELSE
-
 
2138
                    op := ORD("+")
2099
                    op := ORD("-")
2139
                END;
-
 
2140
 
-
 
2141
                PARS.check(isInt(e) & isInt(e1) OR isReal(e) & isReal(e1) OR isSet(e) & isSet(e1) OR isString(e) & isString(e1) & ~minus, pos, 37);
2100
                END;
2142
                IF (e.obj = eCONST) & (e1.obj = eCONST) THEN
-
 
2143
 
-
 
2144
                    CASE e.value.typ OF
2101
 
2145
                    |ARITH.tINTEGER:
-
 
2146
                        PARS.check(ARITH.opInt(e.value, e1.value, CHR(op)),   pos, 39)
-
 
2147
 
-
 
2148
                    |ARITH.tREAL:
-
 
2149
                        PARS.check(ARITH.opFloat(e.value, e1.value, CHR(op)), pos, 40)
-
 
2150
 
-
 
2151
                    |ARITH.tSET:
-
 
2152
                        ARITH.opSet(e.value, e1.value, CHR(op))
-
 
2153
 
-
 
2154
                    |ARITH.tCHAR, ARITH.tSTRING:
-
 
2155
                        IF e.value.typ = ARITH.tCHAR THEN
-
 
2156
                            ARITH.charToStr(e.value, s)
-
 
2157
                        ELSE
-
 
2158
                            s := e.value.string(SCAN.IDENT).s
-
 
2159
                        END;
-
 
2160
                        IF e1.value.typ = ARITH.tCHAR THEN
-
 
2161
                            ARITH.charToStr(e1.value, s1)
2102
                PARS.check(isInt(e) & isInt(e1) OR isReal(e) & isReal(e1) OR isSet(e) & isSet(e1), pos, 37);
2162
                        ELSE
Line 2103... Line 2163...
2103
                IF (e.obj = eCONST) & (e1.obj = eCONST) THEN
2163
                            s1 := e1.value.string(SCAN.IDENT).s
2104
 
2164
                        END;
2105
                   CASE e.value.typ OF
2165
                        PARS.check(ARITH.concat(s, s1), pos, 5);
2106
                   |ARITH.tINTEGER: PARS.check(ARITH.opInt(e.value, e1.value, CHR(op)),   pos, 39)
2166
                        e.value.string := SCAN.enterid(s);
2107
                   |ARITH.tREAL:    PARS.check(ARITH.opFloat(e.value, e1.value, CHR(op)), pos, 40)
2167
                        e.value.typ := ARITH.tSTRING;
2108
                   |ARITH.tSET:     ARITH.opSet(e.value, e1.value, CHR(op))
2168
                        e._type := PROG.program.stTypes.tSTRING
2109
                   END
2169
                   END
2110
 
2170
 
2111
                ELSE
2171
                ELSE
2112
                    IF isInt(e) THEN
2172
                    IF isInt(e) THEN
2113
                        IF e.obj = eCONST THEN
2173
                        IF e.obj = eCONST THEN
2114
                            IL.AddCmd(IL.opADDL + ORD(op = ORD("-")), ARITH.Int(e.value))
2174
                            IL.AddCmd(IL.opADDC - ORD(minus), ARITH.Int(e.value))
2115
                        ELSIF e1.obj = eCONST THEN
2175
                        ELSIF e1.obj = eCONST THEN
2116
                            IL.AddCmd(IL.opADDR + ORD(op = ORD("-")), ARITH.Int(e1.value))
2176
                            IL.AddCmd(IL.opADDC + ORD(minus), ARITH.Int(e1.value))
2117
                        ELSE
2177
                        ELSE
2118
                            IL.AddCmd0(IL.opADD  + ORD(op = ORD("-")))
2178
                            IL.AddCmd0(IL.opADD + ORD(minus))
2119
                        END
2179
                        END
2120
                    ELSIF isReal(e) THEN
2180
                    ELSIF isReal(e) THEN
2121
                        IF e.obj = eCONST THEN
2181
                        IF e.obj = eCONST THEN
2122
                            IL.Float(ARITH.Float(e.value));
2182
                            Float(parser, e);
2123
                            IL.fbinop(IL.opADDFI + ORD(op = ORD("-")))
2183
                            IL.AddCmd0(IL.opADDF - ORD(minus))
2124
                        ELSIF e1.obj = eCONST THEN
2184
                        ELSIF e1.obj = eCONST THEN
2125
                            IL.Float(ARITH.Float(e1.value));
2185
                            Float(parser, e1);
2126
                            IL.fbinop(IL.opADDF  + ORD(op = ORD("-")))
2186
                            IL.AddCmd0(IL.opADDF + ORD(minus))
2127
                        ELSE
2187
                        ELSE
2128
                            IL.fbinop(IL.opADDF  + ORD(op = ORD("-")))
2188
                            IL.AddCmd0(IL.opADDF + ORD(minus))
2129
                        END
2189
                        END
2130
                    ELSIF isSet(e) THEN
2190
                    ELSIF isSet(e) THEN
2131
                        IF e.obj = eCONST THEN
2191
                        IF e.obj = eCONST THEN
2132
                            IL.AddCmd(IL.opADDSL + ORD(op = ORD("-")), ARITH.Int(e.value))
2192
                            IL.AddCmd(IL.opADDSC - ORD(minus), ARITH.Int(e.value))
Line 2146... Line 2206...
2146
                    ARITH.opBoolean(e.value, e1.value, "|")
2206
                    ARITH.opBoolean(e.value, e1.value, "|")
2147
                ELSE
2207
                ELSE
2148
                    e.obj := eEXPR;
2208
                    e.obj := eEXPR;
2149
                    IF e1.obj = eCONST THEN
2209
                    IF e1.obj = eCONST THEN
2150
                        IL.Const(ORD(ARITH.getBool(e1.value)))
2210
                        IL.Const(ORD(ARITH.getBool(e1.value)))
2151
                    END;
2211
                    END
2152
                    IL.AddCmd0(IL.opACC)
-
 
2153
                END
2212
                END
Line 2154... Line 2213...
2154
 
2213
 
2155
            END
2214
            END
Line 2156... Line 2215...
2156
        END;
2215
        END;
-
 
2216
 
-
 
2217
        IF label # -1 THEN
2157
 
2218
            label1 := IL.NewLabel();
-
 
2219
            IL.AddJmpCmd(IL.opJZ, label1);
-
 
2220
            IL.SetLabel(label);
-
 
2221
            IL.Const(1);
-
 
2222
            IL.drop;
-
 
2223
            label := IL.NewLabel();
-
 
2224
            IL.AddJmpCmd(IL.opJMP, label);
-
 
2225
            IL.SetLabel(label1);
-
 
2226
            IL.Const(0);
2158
        IF label # -1 THEN
2227
            IL.SetLabel(label);
Line 2159... Line 2228...
2159
            IL.SetLabel(label)
2228
            IL.AddCmd0(IL.opOR)
Line 2166... Line 2235...
2166
    VAR
2235
    VAR
2167
        res: INTEGER;
2236
        res: INTEGER;
Line 2168... Line 2237...
2168
 
2237
 
2169
    BEGIN
2238
    BEGIN
2170
        CASE op OF
2239
        CASE op OF
2171
        |SCAN.lxEQ: res := 0
2240
        |SCAN.lxEQ: res := ARITH.opEQ
2172
        |SCAN.lxNE: res := 1
2241
        |SCAN.lxNE: res := ARITH.opNE
2173
        |SCAN.lxLT: res := 2
2242
        |SCAN.lxLT: res := ARITH.opLT
2174
        |SCAN.lxLE: res := 3
2243
        |SCAN.lxLE: res := ARITH.opLE
2175
        |SCAN.lxGT: res := 4
2244
        |SCAN.lxGT: res := ARITH.opGT
-
 
2245
        |SCAN.lxGE: res := ARITH.opGE
-
 
2246
        |SCAN.lxIN: res := ARITH.opIN
2176
        |SCAN.lxGE: res := 5
2247
        |SCAN.lxIS: res := ARITH.opIS
Line 2177... Line 2248...
2177
        END
2248
        END
2178
 
2249
 
Line 2184... Line 2255...
2184
    VAR
2255
    VAR
2185
        res: INTEGER;
2256
        res: INTEGER;
Line 2186... Line 2257...
2186
 
2257
 
2187
    BEGIN
2258
    BEGIN
2188
        CASE op OF
2259
        CASE op OF
2189
        |SCAN.lxEQ: res := 0
2260
        |SCAN.lxEQ: res := ARITH.opEQ
2190
        |SCAN.lxNE: res := 1
2261
        |SCAN.lxNE: res := ARITH.opNE
2191
        |SCAN.lxLT: res := 4
2262
        |SCAN.lxLT: res := ARITH.opGT
2192
        |SCAN.lxLE: res := 5
2263
        |SCAN.lxLE: res := ARITH.opGE
2193
        |SCAN.lxGT: res := 2
2264
        |SCAN.lxGT: res := ARITH.opLT
-
 
2265
        |SCAN.lxGE: res := ARITH.opLE
-
 
2266
        |SCAN.lxIN: res := ARITH.opIN
2194
        |SCAN.lxGE: res := 3
2267
        |SCAN.lxIS: res := ARITH.opIS
Line 2195... Line 2268...
2195
        END
2268
        END
2196
 
2269
 
Line 2209... Line 2282...
2209
 
2282
 
2210
 
2283
 
2211
    PROCEDURE strcmp (VAR e, e1: PARS.EXPR; op: INTEGER): BOOLEAN;
2284
    PROCEDURE strcmp (VAR e, e1: PARS.EXPR; op: INTEGER): BOOLEAN;
-
 
2285
    VAR
Line 2212... Line 2286...
2212
    VAR
2286
        res: BOOLEAN;
2213
        res: BOOLEAN;
2287
        cmp: INTEGER;
-
 
2288
 
Line 2214... Line 2289...
2214
 
2289
    BEGIN
2215
    BEGIN
2290
        res := TRUE;
2216
        res := TRUE;
2291
        cmp := cmpcode(op);
2217
 
2292
 
Line 2218... Line -...
2218
        IF isString(e) & isCharArray(e1) THEN
-
 
2219
            IL.StrAdr(String(e));
-
 
2220
            IL.Const(strlen(e) + 1);
-
 
2221
            IL.AddCmd0(IL.opEQS + invcmpcode(op))
-
 
2222
 
-
 
2223
        ELSIF isString(e) & isCharArrayW(e1) THEN
2293
        IF isString(e) & isCharArray(e1) THEN
2224
            IL.StrAdr(StringW(e));
2294
            IL.StrAdr(String(e));
2225
            IL.Const(utf8strlen(e) + 1);
2295
            IL.Const(strlen(e) + 1);
2226
            IL.AddCmd0(IL.opEQSW + invcmpcode(op))
2296
            IL.AddCmd0(IL.opEQS + invcmpcode(op))
Line 2227... Line 2297...
2227
 
2297
 
2228
        ELSIF isStringW(e) & isCharArrayW(e1) THEN
2298
        ELSIF (isString(e) OR isStringW(e)) & isCharArrayW(e1) THEN
2229
            IL.StrAdr(StringW(e));
2299
            IL.StrAdr(StringW(e));
2230
            IL.Const(utf8strlen(e) + 1);
2300
            IL.Const(utf8strlen(e) + 1);
2231
            IL.AddCmd0(IL.opEQSW + invcmpcode(op))
-
 
2232
 
-
 
2233
        ELSIF isCharArray(e) & isString(e1) THEN
-
 
2234
            IL.StrAdr(String(e1));
-
 
2235
            IL.Const(strlen(e1) + 1);
-
 
Line 2236... Line 2301...
2236
            IL.AddCmd0(IL.opEQS + cmpcode(op))
2301
            IL.AddCmd0(IL.opEQSW + invcmpcode(op))
2237
 
2302
 
2238
        ELSIF isCharArrayW(e) & isString(e1) THEN
2303
        ELSIF isCharArray(e) & isString(e1) THEN
2239
            IL.StrAdr(StringW(e1));
2304
            IL.StrAdr(String(e1));
Line 2240... Line 2305...
2240
            IL.Const(utf8strlen(e1) + 1);
2305
            IL.Const(strlen(e1) + 1);
2241
            IL.AddCmd0(IL.opEQSW + cmpcode(op))
2306
            IL.AddCmd0(IL.opEQS + cmp)
Line 2242... Line 2307...
2242
 
2307
 
2243
        ELSIF isCharArrayW(e) & isStringW(e1) THEN
2308
        ELSIF isCharArrayW(e) & (isString(e1) OR isStringW(e1)) THEN
Line 2244... Line 2309...
2244
            IL.StrAdr(StringW(e1));
2309
            IL.StrAdr(StringW(e1));
2245
            IL.Const(utf8strlen(e1) + 1);
2310
            IL.Const(utf8strlen(e1) + 1);
Line 2246... Line 2311...
2246
            IL.AddCmd0(IL.opEQSW + cmpcode(op))
2311
            IL.AddCmd0(IL.opEQSW + cmp)
Line 2265... Line 2330...
2265
 
2330
 
2266
BEGIN
2331
BEGIN
2267
    getpos(parser, pos0);
2332
    getpos(parser, pos0);
2268
    SimpleExpression(parser, e);
2333
    SimpleExpression(parser, e);
2269
    IF relation(parser.sym) THEN
2334
    IF relation(parser.sym) THEN
2270
        IF (isCharArray(e) OR isCharArrayW(e)) & (e.type.length # 0) THEN
2335
        IF (isCharArray(e) OR isCharArrayW(e)) & (e._type.length # 0) THEN
2271
            IL.Const(e.type.length)
2336
            IL.Const(e._type.length)
2272
        END;
2337
        END;
2273
        op  := parser.sym;
2338
        op := parser.sym;
2274
        getpos(parser, pos);
2339
        getpos(parser, pos);
Line 2275... Line 2340...
2275
        PARS.Next(parser);
2340
        PARS.Next(parser);
2276
 
2341
 
Line 2277... Line 2342...
2277
        getpos(parser, pos1);
2342
        getpos(parser, pos1);
2278
        SimpleExpression(parser, e1);
2343
        SimpleExpression(parser, e1);
2279
 
2344
 
Line 2280... Line 2345...
2280
        IF (isCharArray(e1) OR isCharArrayW(e1)) & (e1.type.length # 0) THEN
2345
        IF (isCharArray(e1) OR isCharArrayW(e1)) & (e1._type.length # 0) THEN
2281
            IL.Const(e1.type.length)
-
 
2282
        END;
-
 
2283
 
-
 
2284
        constant := (e.obj = eCONST) & (e1.obj = eCONST);
-
 
2285
 
-
 
2286
        CASE op OF
-
 
2287
        |SCAN.lxEQ: operator := "="
-
 
2288
        |SCAN.lxNE: operator := "#"
-
 
2289
        |SCAN.lxLT: operator := "<"
-
 
2290
        |SCAN.lxLE: operator := "<="
-
 
2291
        |SCAN.lxGT: operator := ">"
-
 
2292
        |SCAN.lxGE: operator := ">="
-
 
2293
        |SCAN.lxIN: operator := "IN"
2346
            IL.Const(e1._type.length)
-
 
2347
        END;
Line 2294... Line 2348...
2294
        |SCAN.lxIS: operator := ""
2348
 
2295
        END;
2349
        constant := (e.obj = eCONST) & (e1.obj = eCONST);
2296
 
-
 
-
 
2350
        error := 0;
2297
        error := 0;
2351
        cmp := cmpcode(op);
2298
 
2352
 
2299
        CASE op OF
2353
        CASE op OF
2300
        |SCAN.lxEQ, SCAN.lxNE:
2354
        |SCAN.lxEQ, SCAN.lxNE:
2301
 
2355
            eq := op = SCAN.lxEQ;
2302
            IF isInt(e) & isInt(e1) OR isSet(e) & isSet(e1) OR isChar(e) & isChar(e1) OR isCharW(e) & isCharW(e1) OR
2356
            IF isInt(e) & isInt(e1) OR isSet(e) & isSet(e1) OR isChar(e) & isChar(e1) OR isCharW(e) & isCharW(e1) OR
2303
            isCharW(e) & isChar(e1) & (e1.obj = eCONST) OR isCharW(e1) & isChar(e) & (e.obj = eCONST) OR
2357
            isCharW(e) & isChar(e1) & (e1.obj = eCONST) OR isCharW(e1) & isChar(e) & (e.obj = eCONST) OR
2304
            isCharW(e1) & (e1.obj = eCONST) & isChar(e) & (e.obj = eCONST) OR
2358
            isCharW(e1) & (e1.obj = eCONST) & isChar(e) & (e.obj = eCONST) OR
2305
            isCharW(e) & (e.obj = eCONST) & isChar(e1) & (e1.obj = eCONST) OR
2359
            isCharW(e) & (e.obj = eCONST) & isChar(e1) & (e1.obj = eCONST) OR
2306
            isPtr(e) & isPtr(e1) & (PROG.isBaseOf(e.type, e1.type) OR PROG.isBaseOf(e1.type, e.type)) THEN
2360
            isPtr(e) & isPtr(e1) & (PROG.isBaseOf(e._type, e1._type) OR PROG.isBaseOf(e1._type, e._type)) THEN
2307
                IF constant THEN
2361
                IF constant THEN
2308
                    ARITH.relation(e.value, e1.value, operator, error)
2362
                    ARITH.relation(e.value, e1.value, cmp, error)
2309
                ELSE
2363
                ELSE
2310
                    IF e.obj = eCONST THEN
2364
                    IF e.obj = eCONST THEN
2311
                        IL.AddCmd(IL.opEQC + cmpcode(op), ARITH.Int(e.value))
2365
                        IL.AddCmd(IL.opEQC + cmp, ARITH.Int(e.value))
2312
                    ELSIF e1.obj = eCONST THEN
2366
                    ELSIF e1.obj = eCONST THEN
Line 2313... Line 2367...
2313
                        IL.AddCmd(IL.opEQC + cmpcode(op), ARITH.Int(e1.value))
2367
                        IL.AddCmd(IL.opEQC + cmp, ARITH.Int(e1.value))
2314
                    ELSE
2368
                    ELSE
Line 2315... Line 2369...
2315
                        IL.AddCmd0(IL.opEQ + cmpcode(op))
2369
                        IL.AddCmd0(IL.opEQ + cmp)
2316
                    END
2370
                    END
Line 2317... Line 2371...
2317
                END
2371
                END
2318
 
2372
 
2319
            ELSIF isStringW1(e) & isCharW(e1) THEN
2373
            ELSIF isStringW1(e) & isCharW(e1) THEN
2320
                IL.AddCmd(IL.opEQC + cmpcode(op), StrToWChar(e.value.string(SCAN.IDENT).s))
2374
                IL.AddCmd(IL.opEQC + cmp, StrToWChar(e.value.string(SCAN.IDENT).s))
2321
 
2375
 
2322
            ELSIF isStringW1(e1) & isCharW(e) THEN
2376
            ELSIF isStringW1(e1) & isCharW(e) THEN
2323
                IL.AddCmd(IL.opEQC + cmpcode(op), StrToWChar(e1.value.string(SCAN.IDENT).s))
2377
                IL.AddCmd(IL.opEQC + cmp, StrToWChar(e1.value.string(SCAN.IDENT).s))
2324
 
2378
 
2325
            ELSIF isBoolean(e) & isBoolean(e1) THEN
2379
            ELSIF isBoolean(e) & isBoolean(e1) THEN
2326
                IF constant THEN
2380
                IF constant THEN
2327
                    ARITH.relation(e.value, e1.value, operator, error)
2381
                    ARITH.relation(e.value, e1.value, cmp, error)
2328
                ELSE
2382
                ELSE
2329
                    IF e.obj = eCONST THEN
2383
                    IF e.obj = eCONST THEN
2330
                        BoolCmp(op = SCAN.lxEQ, ARITH.Int(e.value) # 0)
2384
                        BoolCmp(eq, ARITH.Int(e.value) # 0)
2331
                    ELSIF e1.obj = eCONST THEN
2385
                    ELSIF e1.obj = eCONST THEN
2332
                        BoolCmp(op = SCAN.lxEQ, ARITH.Int(e1.value) # 0)
2386
                        BoolCmp(eq, ARITH.Int(e1.value) # 0)
Line 2333... Line 2387...
2333
                    ELSE
2387
                    ELSE
2334
                        IF op = SCAN.lxEQ THEN
2388
                        IF eq THEN
2335
                            IL.AddCmd0(IL.opEQB)
2389
                            IL.AddCmd0(IL.opEQB)
2336
                        ELSE
2390
                        ELSE
2337
                            IL.AddCmd0(IL.opNEB)
2391
                            IL.AddCmd0(IL.opNEB)
2338
                        END
2392
                        END
2339
                    END
2393
                    END
2340
                END
2394
                END
2341
 
2395
 
2342
            ELSIF isReal(e) & isReal(e1) THEN
2396
            ELSIF isReal(e) & isReal(e1) THEN
2343
                IF constant THEN
2397
                IF constant THEN
Line 2344... Line 2398...
2344
                    ARITH.relation(e.value, e1.value, operator, error)
2398
                    ARITH.relation(e.value, e1.value, cmp, error)
2345
                ELSE
2399
                ELSE
2346
                    IF e.obj = eCONST THEN
2400
                    IF e.obj = eCONST THEN
2347
                        IL.Float(ARITH.Float(e.value))
2401
                        Float(parser, e)
Line 2348... Line 2402...
2348
                    ELSIF e1.obj = eCONST THEN
2402
                    ELSIF e1.obj = eCONST THEN
2349
                        IL.Float(ARITH.Float(e1.value))
2403
                        Float(parser, e1)
Line 2350... Line 2404...
2350
                    END;
2404
                    END;
2351
                    IL.fcmp(IL.opEQF + cmpcode(op))
2405
                    IL.AddCmd0(IL.opEQF + cmp)
2352
                END
2406
                END
2353
 
2407
 
2354
            ELSIF (isStringW(e) OR isCharArrayX(e)) & (isStringW(e1) OR isCharArrayX(e1)) THEN
2408
            ELSIF (isStringW(e) OR isCharArrayX(e)) & (isStringW(e1) OR isCharArrayX(e1)) THEN
2355
                IF ~strcmp(e, e1, op) THEN
2409
                IF ~strcmp(e, e1, op) THEN
2356
                    PARS.error(pos, 37)
2410
                    PARS.error(pos, 37)
2357
                END
2411
                END
2358
 
2412
 
Line 2359... Line 2413...
2359
            ELSIF isPtr(e) & isNil(e1) OR isNil(e) & isPtr(e1) THEN
2413
            ELSIF isPtr(e) & isNil(e1) OR isNil(e) & isPtr(e1) THEN
2360
                IL.AddCmd0(IL.opEQC + cmpcode(op))
2414
                IL.AddCmd0(IL.opEQC + cmp)
2361
 
2415
 
2362
            ELSIF isProc(e) & isNil(e1) THEN
2416
            ELSIF isProc(e) & isNil(e1) THEN
2363
                IF e.obj IN {ePROC, eIMP} THEN
2417
                IF e.obj IN {ePROC, eIMP} THEN
2364
                    PARS.check(e.ident.global, pos0, 85);
2418
                    PARS.check(e.ident.global, pos0, 85);
2365
                    constant := TRUE;
2419
                    constant := TRUE;
2366
                    e.obj := eCONST;
2420
                    e.obj := eCONST;
2367
                    ARITH.setbool(e.value, op = SCAN.lxNE)
2421
                    ARITH.setbool(e.value, ~eq)
Line 2368... Line 2422...
2368
                ELSE
2422
                ELSE
2369
                    IL.AddCmd0(IL.opEQC + cmpcode(op))
2423
                    IL.AddCmd0(IL.opEQC + cmp)
2370
                END
2424
                END
2371
 
2425
 
2372
            ELSIF isNil(e) & isProc(e1) THEN
2426
            ELSIF isNil(e) & isProc(e1) THEN
2373
                IF e1.obj IN {ePROC, eIMP} THEN
2427
                IF e1.obj IN {ePROC, eIMP} THEN
2374
                    PARS.check(e1.ident.global, pos1, 85);
2428
                    PARS.check(e1.ident.global, pos1, 85);
2375
                    constant := TRUE;
2429
                    constant := TRUE;
2376
                    e.obj := eCONST;
2430
                    e.obj := eCONST;
2377
                    ARITH.setbool(e.value, op = SCAN.lxNE)
2431
                    ARITH.setbool(e.value, ~eq)
2378
                ELSE
2432
                ELSE
2379
                    IL.AddCmd0(IL.opEQC + cmpcode(op))
2433
                    IL.AddCmd0(IL.opEQC + cmp)
2380
                END
2434
                END
2381
 
2435
 
2382
            ELSIF isProc(e) & isProc(e1) & PROG.isTypeEq(e.type, e1.type) THEN
2436
            ELSIF isProc(e) & isProc(e1) & PROG.isTypeEq(e._type, e1._type) THEN
2383
                IF e.obj = ePROC THEN
2437
                IF e.obj = ePROC THEN
2384
                    PARS.check(e.ident.global, pos0, 85)
2438
                    PARS.check(e.ident.global, pos0, 85)
2385
                END;
2439
                END;
2386
                IF e1.obj = ePROC THEN
2440
                IF e1.obj = ePROC THEN
2387
                    PARS.check(e1.ident.global, pos1, 85)
2441
                    PARS.check(e1.ident.global, pos1, 85)
2388
                END;
2442
                END;
2389
                IF (e.obj IN {ePROC, eIMP}) & (e1.obj IN {ePROC, eIMP}) THEN
2443
                IF (e.obj IN {ePROC, eIMP}) & (e1.obj IN {ePROC, eIMP}) THEN
2390
                    constant := TRUE;
2444
                    constant := TRUE;
2391
                    e.obj := eCONST;
2445
                    e.obj := eCONST;
2392
                    IF op = SCAN.lxEQ THEN
2446
                    IF eq THEN
2393
                        ARITH.setbool(e.value, e.ident = e1.ident)
2447
                        ARITH.setbool(e.value, e.ident = e1.ident)
Line 2394... Line 2448...
2394
                    ELSE
2448
                    ELSE
2395
                        ARITH.setbool(e.value, e.ident # e1.ident)
2449
                        ARITH.setbool(e.value, e.ident # e1.ident)
2396
                    END
2450
                    END
2397
                ELSIF e.obj = ePROC THEN
2451
                ELSIF e.obj = ePROC THEN
Line 2398... Line 2452...
2398
                    IL.ProcCmp(e.ident.proc.label, op = SCAN.lxEQ)
2452
                    IL.ProcCmp(e.ident.proc.label, eq)
2399
                ELSIF e1.obj = ePROC THEN
2453
                ELSIF e1.obj = ePROC THEN
2400
                    IL.ProcCmp(e1.ident.proc.label, op = SCAN.lxEQ)
2454
                    IL.ProcCmp(e1.ident.proc.label, eq)
Line 2420... Line 2474...
2420
                isCharW(e) & isChar(e1) & (e1.obj = eCONST) OR isCharW(e1) & isChar(e) & (e.obj = eCONST) OR
2474
                isCharW(e) & isChar(e1) & (e1.obj = eCONST) OR isCharW(e1) & isChar(e) & (e.obj = eCONST) OR
2421
                isCharW(e1) & (e1.obj = eCONST) & isChar(e) & (e.obj = eCONST) OR
2475
                isCharW(e1) & (e1.obj = eCONST) & isChar(e) & (e.obj = eCONST) OR
2422
                isCharW(e) & (e.obj = eCONST) & isChar(e1) & (e1.obj = eCONST) THEN
2476
                isCharW(e) & (e.obj = eCONST) & isChar(e1) & (e1.obj = eCONST) THEN
Line 2423... Line 2477...
2423
 
2477
 
2424
                IF constant THEN
2478
                IF constant THEN
2425
                    ARITH.relation(e.value, e1.value, operator, error)
2479
                    ARITH.relation(e.value, e1.value, cmp, error)
2426
                ELSE
2480
                ELSE
2427
                    IF e.obj = eCONST THEN
2481
                    IF e.obj = eCONST THEN
2428
                        IL.AddCmd(IL.opEQC + invcmpcode(op), ARITH.Int(e.value))
2482
                        IL.AddCmd(IL.opEQC + invcmpcode(op), ARITH.Int(e.value))
2429
                    ELSIF e1.obj = eCONST THEN
2483
                    ELSIF e1.obj = eCONST THEN
2430
                        IL.AddCmd(IL.opEQC + cmpcode(op), ARITH.Int(e1.value))
2484
                        IL.AddCmd(IL.opEQC + cmp, ARITH.Int(e1.value))
2431
                    ELSE
2485
                    ELSE
2432
                        IL.AddCmd0(IL.opEQ + cmpcode(op))
2486
                        IL.AddCmd0(IL.opEQ + cmp)
2433
                    END
2487
                    END
Line 2434... Line 2488...
2434
                END
2488
                END
2435
 
2489
 
Line 2436... Line 2490...
2436
            ELSIF isStringW1(e) & isCharW(e1) THEN
2490
            ELSIF isStringW1(e) & isCharW(e1) THEN
2437
                IL.AddCmd(IL.opEQC + invcmpcode(op), StrToWChar(e.value.string(SCAN.IDENT).s))
2491
                IL.AddCmd(IL.opEQC + invcmpcode(op), StrToWChar(e.value.string(SCAN.IDENT).s))
Line 2438... Line 2492...
2438
 
2492
 
2439
            ELSIF isStringW1(e1) & isCharW(e) THEN
2493
            ELSIF isStringW1(e1) & isCharW(e) THEN
2440
                IL.AddCmd(IL.opEQC + cmpcode(op), StrToWChar(e1.value.string(SCAN.IDENT).s))
2494
                IL.AddCmd(IL.opEQC + cmp, StrToWChar(e1.value.string(SCAN.IDENT).s))
2441
 
2495
 
2442
            ELSIF isReal(e) & isReal(e1) THEN
2496
            ELSIF isReal(e) & isReal(e1) THEN
2443
                IF constant THEN
2497
                IF constant THEN
2444
                    ARITH.relation(e.value, e1.value, operator, error)
2498
                    ARITH.relation(e.value, e1.value, cmp, error)
2445
                ELSE
2499
                ELSE
2446
                    IF e.obj = eCONST THEN
2500
                    IF e.obj = eCONST THEN
2447
                        IL.Float(ARITH.Float(e.value));
2501
                        Float(parser, e);
2448
                        IL.fcmp(IL.opEQF + invcmpcode(op))
2502
                        IL.AddCmd0(IL.opEQF + invcmpcode(op))
2449
                    ELSIF e1.obj = eCONST THEN
2503
                    ELSIF e1.obj = eCONST THEN
2450
                        IL.Float(ARITH.Float(e1.value));
2504
                        Float(parser, e1);
2451
                        IL.fcmp(IL.opEQF + cmpcode(op))
2505
                        IL.AddCmd0(IL.opEQF + cmp)
Line 2452... Line 2506...
2452
                    ELSE
2506
                    ELSE
2453
                        IL.fcmp(IL.opEQF + cmpcode(op))
2507
                        IL.AddCmd0(IL.opEQF + cmp)
Line 2467... Line 2521...
2467
            PARS.check(isInt(e) & isSet(e1), pos, 37);
2521
            PARS.check(isInt(e) & isSet(e1), pos, 37);
2468
            IF e.obj = eCONST THEN
2522
            IF e.obj = eCONST THEN
2469
                PARS.check(ARITH.range(e.value, 0, UTILS.target.maxSet), pos0, 56)
2523
                PARS.check(ARITH.range(e.value, 0, UTILS.target.maxSet), pos0, 56)
2470
            END;
2524
            END;
2471
            IF constant THEN
2525
            IF constant THEN
2472
                ARITH.relation(e.value, e1.value, operator, error)
2526
                ARITH.relation(e.value, e1.value, ARITH.opIN, error)
2473
            ELSE
2527
            ELSE
2474
                IF e.obj = eCONST THEN
2528
                IF e.obj = eCONST THEN
2475
                    IL.AddCmd(IL.opINL, ARITH.Int(e.value))
2529
                    IL.AddCmd(IL.opINL, ARITH.Int(e.value))
2476
                ELSIF e1.obj = eCONST THEN
2530
                ELSIF e1.obj = eCONST THEN
2477
                    IL.AddCmd(IL.opINR, ARITH.Int(e1.value))
2531
                    IL.AddCmd(IL.opINR, ARITH.Int(e1.value))
Line 2484... Line 2538...
2484
            PARS.check(isRecPtr(e), pos, 73);
2538
            PARS.check(isRecPtr(e), pos, 73);
2485
            PARS.check(e1.obj = eTYPE, pos1, 79);
2539
            PARS.check(e1.obj = eTYPE, pos1, 79);
Line 2486... Line 2540...
2486
 
2540
 
2487
            IF isRec(e) THEN
2541
            IF isRec(e) THEN
2488
                PARS.check(e.obj = eVREC, pos0, 78);
2542
                PARS.check(e.obj = eVREC, pos0, 78);
2489
                PARS.check(e1.type.typ = PROG.tRECORD, pos1, 80);
2543
                PARS.check(e1._type.typ = PROG.tRECORD, pos1, 80);
2490
                IF e.ident = NIL THEN
2544
                IF e.ident = NIL THEN
2491
                    IL.TypeCheck(e1.type.num)
2545
                    IL.TypeCheck(e1._type.num)
2492
                ELSE
2546
                ELSE
2493
                    IL.AddCmd(IL.opVADR, e.ident.offset - 1);
2547
                    IL.AddCmd(IL.opVADR, e.ident.offset - 1);
2494
                    IL.TypeCheckRec(e1.type.num)
2548
                    IL.TypeCheckRec(e1._type.num)
2495
                END
2549
                END
2496
            ELSE
2550
            ELSE
2497
                PARS.check(e1.type.typ = PROG.tPOINTER, pos1, 81);
2551
                PARS.check(e1._type.typ = PROG.tPOINTER, pos1, 81);
2498
                IL.TypeCheck(e1.type.base.num)
2552
                IL.TypeCheck(e1._type.base.num)
Line 2499... Line 2553...
2499
            END;
2553
            END;
Line 2500... Line 2554...
2500
 
2554
 
Line 2501... Line 2555...
2501
            PARS.check(PROG.isBaseOf(e.type, e1.type), pos1, 82)
2555
            PARS.check(PROG.isBaseOf(e._type, e1._type), pos1, 82)
Line 2502... Line 2556...
2502
 
2556
 
Line 2503... Line 2557...
2503
        END;
2557
        END;
2504
 
2558
 
2505
        ASSERT(error = 0);
2559
        ASSERT(error = 0);
Line 2518... Line 2572...
2518
VAR
2572
VAR
2519
    e, e1: PARS.EXPR;
2573
    e, e1: PARS.EXPR;
2520
    pos:   PARS.POSITION;
2574
    pos:   PARS.POSITION;
2521
    line:  INTEGER;
2575
    line:  INTEGER;
2522
    call:  BOOLEAN;
2576
    call:  BOOLEAN;
2523
    fregs: INTEGER;
-
 
Line 2524... Line 2577...
2524
 
2577
 
2525
BEGIN
2578
BEGIN
Line 2526... Line 2579...
2526
    getpos(parser, pos);
2579
    getpos(parser, pos);
Line 2539... Line 2592...
2539
        NextPos(parser, pos);
2592
        NextPos(parser, pos);
2540
        expression(parser, e1);
2593
        expression(parser, e1);
Line 2541... Line 2594...
2541
 
2594
 
Line 2542... Line 2595...
2542
        IL.setlast(endcall.prev(IL.COMMAND));
2595
        IL.setlast(endcall.prev(IL.COMMAND));
2543
 
2596
 
2544
        PARS.check(assign(e1, e.type, line), pos, 91);
2597
        PARS.check(assign(parser, e1, e._type, line), pos, 91);
2545
        IF e1.obj = ePROC THEN
2598
        IF e1.obj = ePROC THEN
2546
            PARS.check(e1.ident.global, pos, 85)
2599
            PARS.check(e1.ident.global, pos, 85)
2547
        END;
2600
        END;
2548
        call := FALSE
2601
        call := FALSE
2549
    ELSIF parser.sym = SCAN.lxEQ THEN
2602
    ELSIF parser.sym = SCAN.lxEQ THEN
2550
        PARS.check1(FALSE, parser, 96)
2603
        PARS.check1(FALSE, parser, 96)
2551
    ELSIF parser.sym = SCAN.lxLROUND THEN
2604
    ELSIF parser.sym = SCAN.lxLROUND THEN
2552
        e1 := e;
2605
        e1 := e;
2553
        ActualParameters(parser, e1);
2606
        ActualParameters(parser, e1);
2554
        PARS.check((e1.type = NIL) OR ODD(e.type.call), pos, 92);
2607
        PARS.check((e1._type = NIL) OR ODD(e._type.call), pos, 92);
2555
        call := TRUE
2608
        call := TRUE
2556
    ELSE
2609
    ELSE
2557
        IF e.obj IN {eSYSPROC, eSTPROC} THEN
2610
        IF e.obj IN {eSYSPROC, eSTPROC} THEN
2558
            stProc(parser, e);
2611
            stProc(parser, e);
2559
            call := FALSE
2612
            call := FALSE
2560
        ELSE
2613
        ELSE
2561
            PARS.check(isProc(e), pos, 86);
2614
            PARS.check(isProc(e), pos, 86);
2562
            PARS.check((e.type.base = NIL) OR ODD(e.type.call), pos, 92);
2615
            PARS.check((e._type.base = NIL) OR ODD(e._type.call), pos, 92);
2563
            PARS.check1(e.type.params.first = NIL, parser, 64);
2616
            PARS.check1(e._type.params.first = NIL, parser, 64);
2564
            call := TRUE
2617
            call := TRUE
Line 2565... Line 2618...
2565
        END
2618
        END
2566
    END;
2619
    END;
2567
 
2620
 
2568
    IF call THEN
2621
    IF call THEN
2569
        IF e.obj IN {ePROC, eIMP} THEN
2622
        IF e.obj IN {ePROC, eIMP} THEN
2570
            ProcCall(e, e.ident.type, FALSE, fregs, parser, pos, TRUE)
2623
            ProcCall(e, e.ident._type, FALSE, parser, pos, TRUE)
2571
        ELSIF isExpr(e) THEN
2624
        ELSIF isExpr(e) THEN
Line 2572... Line 2625...
2572
            ProcCall(e, e.type, FALSE, fregs, parser, pos, TRUE)
2625
            ProcCall(e, e._type, FALSE, parser, pos, TRUE)
2573
        END
2626
        END
Line 2574... Line 2627...
2574
    END;
2627
    END;
2575
 
2628
 
2576
    IL.popBegEnd(begcall, endcall)
2629
    IL.popBegEnd(begcall, endcall)
2577
END ElementaryStatement;
2630
END ElementaryStatement;
Line 2578... Line 2631...
2578
 
2631
 
Line 2579... Line 2632...
2579
 
2632
 
2580
PROCEDURE IfStatement (parser: PARS.PARSER; if: BOOLEAN);
2633
PROCEDURE IfStatement (parser: PARS.PARSER; _if: BOOLEAN);
Line 2581... Line 2634...
2581
VAR
2634
VAR
2582
    e:   PARS.EXPR;
2635
    e:   PARS.EXPR;
2583
    pos: PARS.POSITION;
2636
    pos: PARS.POSITION;
2584
 
2637
 
Line 2585... Line 2638...
2585
    label, L: INTEGER;
2638
    label, L: INTEGER;
Line 2603... Line 2656...
2603
        IF e.obj = eCONST THEN
2656
        IF e.obj = eCONST THEN
2604
            IF ~ARITH.getBool(e.value) THEN
2657
            IF ~ARITH.getBool(e.value) THEN
2605
                IL.AddJmpCmd(IL.opJMP, label)
2658
                IL.AddJmpCmd(IL.opJMP, label)
2606
            END
2659
            END
2607
        ELSE
2660
        ELSE
2608
            IL.AddJmpCmd(IL.opJNE, label)
2661
            IL.AndOrOpt(label)
2609
        END;
2662
        END;
Line 2610... Line 2663...
2610
 
2663
 
2611
        IF if THEN
2664
        IF _if THEN
2612
            PARS.checklex(parser, SCAN.lxTHEN)
2665
            PARS.checklex(parser, SCAN.lxTHEN)
2613
        ELSE
2666
        ELSE
2614
            PARS.checklex(parser, SCAN.lxDO)
2667
            PARS.checklex(parser, SCAN.lxDO)
Line 2615... Line 2668...
2615
        END;
2668
        END;
2616
 
2669
 
Line -... Line 2670...
-
 
2670
        PARS.Next(parser);
2617
        PARS.Next(parser);
2671
        parser.StatSeq(parser);
-
 
2672
 
2618
        parser.StatSeq(parser);
2673
        IF ~_if OR (parser.sym # SCAN.lxEND) THEN
Line 2619... Line 2674...
2619
 
2674
            IL.AddJmpCmd(IL.opJMP, L)
Line 2620... Line 2675...
2620
        IL.AddJmpCmd(IL.opJMP, L);
2675
        END;
2621
        IL.SetLabel(label)
2676
        IL.SetLabel(label)
2622
 
2677
 
2623
    UNTIL parser.sym # SCAN.lxELSIF;
2678
    UNTIL parser.sym # SCAN.lxELSIF;
2624
 
2679
 
2625
    IF if THEN
2680
    IF _if THEN
-
 
2681
        IF parser.sym = SCAN.lxELSE THEN
-
 
2682
            PARS.Next(parser);
2626
        IF parser.sym = SCAN.lxELSE THEN
2683
            parser.StatSeq(parser)
Line 2627... Line 2684...
2627
            PARS.Next(parser);
2684
        END;
Line 2628... Line -...
2628
            parser.StatSeq(parser)
-
 
2629
        END;
-
 
2630
        IL.SetLabel(L)
-
 
2631
    END;
-
 
2632
 
2685
        IL.SetLabel(L)
2633
    PARS.checklex(parser, SCAN.lxEND);
2686
    ELSE
Line 2634... Line 2687...
2634
 
2687
        IL.AddCmd0(IL.opENDLOOP)
2635
    IF ~if THEN
2688
    END;
2636
        IL.AddCmd0(IL.opENDLOOP)
2689
 
2637
    END;
2690
    PARS.checklex(parser, SCAN.lxEND);
2638
 
2691
 
-
 
2692
    PARS.Next(parser)
Line 2639... Line 2693...
2639
    PARS.Next(parser)
2693
END IfStatement;
2640
END IfStatement;
2694
 
Line 2641... Line 2695...
2641
 
2695
 
2642
 
2696
PROCEDURE RepeatStatement (parser: PARS.PARSER);
-
 
2697
VAR
Line 2643... Line 2698...
2643
PROCEDURE RepeatStatement (parser: PARS.PARSER);
2698
    e:     PARS.EXPR;
2644
VAR
2699
    pos:   PARS.POSITION;
2645
    e:     PARS.EXPR;
2700
    label: INTEGER;
2646
    pos:   PARS.POSITION;
2701
    L:     IL.COMMAND;
Line 2662... Line 2717...
2662
    IF e.obj = eCONST THEN
2717
    IF e.obj = eCONST THEN
2663
        IF ~ARITH.getBool(e.value) THEN
2718
        IF ~ARITH.getBool(e.value) THEN
2664
            IL.AddJmpCmd(IL.opJMP, label)
2719
            IL.AddJmpCmd(IL.opJMP, label)
2665
        END
2720
        END
2666
    ELSE
2721
    ELSE
2667
        IL.AddJmpCmd(IL.opJNE, label)
2722
        IL.AndOrOpt(label);
-
 
2723
        L.param1 := label
2668
    END;
2724
    END;
Line 2669... Line 2725...
2669
 
2725
 
2670
    IL.AddCmd0(IL.opENDLOOP)
2726
    IL.AddCmd0(IL.opENDLOOP)
Line 2722... Line 2778...
2722
VAR
2778
VAR
2723
    e:   PARS.EXPR;
2779
    e:   PARS.EXPR;
2724
    pos: PARS.POSITION;
2780
    pos: PARS.POSITION;
Line 2725... Line 2781...
2725
 
2781
 
2726
 
2782
 
2727
    PROCEDURE Label (parser: PARS.PARSER; caseExpr: PARS.EXPR; VAR type: PROG.TYPE_): INTEGER;
2783
    PROCEDURE Label (parser: PARS.PARSER; caseExpr: PARS.EXPR; VAR _type: PROG._TYPE): INTEGER;
2728
    VAR
2784
    VAR
2729
        a:     INTEGER;
2785
        a:     INTEGER;
2730
        label: PARS.EXPR;
2786
        label: PARS.EXPR;
Line 2731... Line 2787...
2731
        pos:   PARS.POSITION;
2787
        pos:   PARS.POSITION;
2732
        value: ARITH.VALUE;
2788
        value: ARITH.VALUE;
2733
 
2789
 
Line 2734... Line 2790...
2734
    BEGIN
2790
    BEGIN
2735
        getpos(parser, pos);
2791
        getpos(parser, pos);
2736
        type := NIL;
2792
        _type := NIL;
2737
 
2793
 
Line 2752... Line 2808...
2752
            PARS.check(value.typ = ARITH.tINTEGER, pos, 99);
2808
            PARS.check(value.typ = ARITH.tINTEGER, pos, 99);
2753
            a := ARITH.getInt(value)
2809
            a := ARITH.getInt(value)
2754
        ELSIF isRecPtr(caseExpr) THEN
2810
        ELSIF isRecPtr(caseExpr) THEN
2755
            qualident(parser, label);
2811
            qualident(parser, label);
2756
            PARS.check(label.obj = eTYPE, pos, 79);
2812
            PARS.check(label.obj = eTYPE, pos, 79);
2757
            PARS.check(PROG.isBaseOf(caseExpr.type, label.type), pos, 99);
2813
            PARS.check(PROG.isBaseOf(caseExpr._type, label._type), pos, 99);
2758
            IF isRec(caseExpr) THEN
2814
            IF isRec(caseExpr) THEN
2759
                a := label.type.num
2815
                a := label._type.num
2760
            ELSE
2816
            ELSE
2761
                a := label.type.base.num
2817
                a := label._type.base.num
2762
            END;
2818
            END;
2763
            type := label.type
2819
            _type := label._type
2764
        END
2820
        END
Line 2765... Line 2821...
2765
 
2821
 
2766
        RETURN a
2822
        RETURN a
Line 2767... Line 2823...
2767
    END Label;
2823
    END Label;
2768
 
2824
 
2769
 
2825
 
2770
    PROCEDURE CheckType (node: AVL.NODE; type: PROG.TYPE_; parser: PARS.PARSER; pos: PARS.POSITION);
2826
    PROCEDURE CheckType (node: AVL.NODE; _type: PROG._TYPE; parser: PARS.PARSER; pos: PARS.POSITION);
2771
    BEGIN
2827
    BEGIN
2772
        IF node # NIL THEN
2828
        IF node # NIL THEN
2773
            PARS.check(~(PROG.isBaseOf(node.data(CASE_LABEL).type, type) OR PROG.isBaseOf(type, node.data(CASE_LABEL).type)), pos, 100);
2829
            PARS.check(~(PROG.isBaseOf(node.data(CASE_LABEL)._type, _type) OR PROG.isBaseOf(_type, node.data(CASE_LABEL)._type)), pos, 100);
2774
            CheckType(node.left, type, parser, pos);
2830
            CheckType(node.left, _type, parser, pos);
Line 2775... Line 2831...
2775
            CheckType(node.right, type, parser, pos)
2831
            CheckType(node.right, _type, parser, pos)
Line 2796... Line 2852...
2796
 
2852
 
2797
        label.variant := variant;
2853
        label.variant := variant;
Line 2798... Line 2854...
2798
        label.self := IL.NewLabel();
2854
        label.self := IL.NewLabel();
2799
 
2855
 
Line 2800... Line 2856...
2800
        getpos(parser, pos1);
2856
        getpos(parser, pos1);
2801
        range.a := Label(parser, caseExpr, label.type);
2857
        range.a := Label(parser, caseExpr, label._type);
2802
 
2858
 
2803
        IF parser.sym = SCAN.lxRANGE THEN
2859
        IF parser.sym = SCAN.lxRANGE THEN
2804
            PARS.check1(~isRecPtr(caseExpr), parser, 53);
2860
            PARS.check1(~isRecPtr(caseExpr), parser, 53);
2805
            NextPos(parser, pos);
2861
            NextPos(parser, pos);
2806
            range.b := Label(parser, caseExpr, label.type);
2862
            range.b := Label(parser, caseExpr, label._type);
2807
            PARS.check(range.a <= range.b, pos, 103)
2863
            PARS.check(range.a <= range.b, pos, 103)
Line 2808... Line 2864...
2808
        ELSE
2864
        ELSE
Line 2809... Line 2865...
2809
            range.b := range.a
2865
            range.b := range.a
2810
        END;
2866
        END;
2811
 
2867
 
2812
        label.range := range;
2868
        label.range := range;
2813
 
2869
 
Line 2814... Line 2870...
2814
        IF isRecPtr(caseExpr) THEN
2870
        IF isRecPtr(caseExpr) THEN
Line 2841... Line 2897...
2841
 
2897
 
2842
        RETURN res
2898
        RETURN res
Line 2843... Line 2899...
2843
    END CaseLabelList;
2899
    END CaseLabelList;
2844
 
2900
 
2845
 
2901
 
2846
    PROCEDURE case (parser: PARS.PARSER; caseExpr: PARS.EXPR; VAR tree: AVL.NODE; end: INTEGER);
2902
    PROCEDURE _case (parser: PARS.PARSER; caseExpr: PARS.EXPR; VAR tree: AVL.NODE; _end: INTEGER);
2847
    VAR
2903
    VAR
2848
        sym:     INTEGER;
2904
        sym:     INTEGER;
2849
        t:       PROG.TYPE_;
2905
        t:       PROG._TYPE;
Line 2850... Line 2906...
2850
        variant: INTEGER;
2906
        variant: INTEGER;
Line 2857... Line 2913...
2857
            variant := IL.NewLabel();
2913
            variant := IL.NewLabel();
2858
            node := CaseLabelList(parser, caseExpr, tree, variant);
2914
            node := CaseLabelList(parser, caseExpr, tree, variant);
2859
            PARS.checklex(parser, SCAN.lxCOLON);
2915
            PARS.checklex(parser, SCAN.lxCOLON);
2860
            PARS.Next(parser);
2916
            PARS.Next(parser);
2861
            IF isRecPtr(caseExpr) THEN
2917
            IF isRecPtr(caseExpr) THEN
2862
                t := caseExpr.type;
2918
                t := caseExpr._type;
2863
                caseExpr.ident.type := node.data(CASE_LABEL).type
2919
                caseExpr.ident._type := node.data(CASE_LABEL)._type
2864
            END;
2920
            END;
Line 2865... Line 2921...
2865
 
2921
 
2866
            last := IL.getlast();
2922
            last := IL.getlast();
Line 2867... Line 2923...
2867
            IL.SetLabel(variant);
2923
            IL.SetLabel(variant);
2868
 
2924
 
2869
            IF ~isRecPtr(caseExpr) THEN
2925
            IF ~isRecPtr(caseExpr) THEN
Line 2870... Line 2926...
2870
                LISTS.push(CaseVariants, NewVariant(variant, last))
2926
                LISTS.push(CaseVariants, NewVariant(variant, last))
2871
            END;
2927
            END;
Line 2872... Line 2928...
2872
 
2928
 
2873
            parser.StatSeq(parser);
2929
            parser.StatSeq(parser);
2874
            IL.AddJmpCmd(IL.opJMP, end);
2930
            IL.AddJmpCmd(IL.opJMP, _end);
2875
 
2931
 
2876
            IF isRecPtr(caseExpr) THEN
2932
            IF isRecPtr(caseExpr) THEN
Line 2877... Line 2933...
2877
                caseExpr.ident.type := t
2933
                caseExpr.ident._type := t
2878
            END
2934
            END
2879
        END
2935
        END
2880
    END case;
2936
    END _case;
2881
 
2937
 
2882
 
2938
 
Line 2895... Line 2951...
2895
 
2951
 
2896
            left := node.left;
2952
            left := node.left;
2897
            IF left # NIL THEN
2953
            IF left # NIL THEN
2898
                L := left.data(CASE_LABEL).self
2954
                L := left.data(CASE_LABEL).self
2899
            ELSE
2955
            ELSE
2900
                L := else
2956
                L := _else
Line 2901... Line 2957...
2901
            END;
2957
            END;
2902
 
2958
 
2903
            right := node.right;
2959
            right := node.right;
2904
            IF right # NIL THEN
2960
            IF right # NIL THEN
2905
                R := right.data(CASE_LABEL).self
2961
                R := right.data(CASE_LABEL).self
2906
            ELSE
2962
            ELSE
Line 2907... Line 2963...
2907
                R := else
2963
                R := _else
Line 2908... Line 2964...
2908
            END;
2964
            END;
Line 2916... Line 2972...
2916
 
2972
 
2917
            ASSERT((v # NIL) & (v.label # 0));
2973
            ASSERT((v # NIL) & (v.label # 0));
Line 2918... Line 2974...
2918
            IL.setlast(v.cmd);
2974
            IL.setlast(v.cmd);
2919
 
2975
 
2920
            IL.SetLabel(node.data(CASE_LABEL).self);
2976
            IL.SetLabel(node.data(CASE_LABEL).self);
2921
            IL.case(range.a, range.b, L, R);
2977
            IL._case(range.a, range.b, L, R);
2922
            IF v.processed THEN
2978
            IF v.processed THEN
2923
                IL.AddJmpCmd(IL.opJMP, node.data(CASE_LABEL).variant)
2979
                IL.AddJmpCmd(IL.opJMP, node.data(CASE_LABEL).variant)
Line 2924... Line 2980...
2924
            END;
2980
            END;
Line 2925... Line 2981...
2925
            v.processed := TRUE;
2981
            v.processed := TRUE;
2926
 
2982
 
2927
            IL.setlast(last);
2983
            IL.setlast(last);
2928
 
2984
 
Line 2929... Line 2985...
2929
            Table(left, else);
2985
            Table(left, _else);
2930
            Table(right, else)
2986
            Table(right, _else)
2931
        END
2987
        END
2932
    END Table;
2988
    END Table;
2933
 
-
 
2934
 
2989
 
2935
    PROCEDURE TableT (node: AVL.NODE);
2990
 
2936
    BEGIN
2991
    PROCEDURE TableT (node: AVL.NODE);
2937
        IF node # NIL THEN
2992
    BEGIN
Line 2938... Line 2993...
2938
            IL.caset(node.data(CASE_LABEL).range.a, node.data(CASE_LABEL).variant);
2993
        IF node # NIL THEN
2939
 
2994
            IL.AddCmd2(IL.opCASET, node.data(CASE_LABEL).variant, node.data(CASE_LABEL).range.a);
2940
            TableT(node.left);
2995
            TableT(node.left);
2941
            TableT(node.right)
2996
            TableT(node.right)
2942
        END
2997
        END
Line 2943... Line 2998...
2943
    END TableT;
2998
    END TableT;
2944
 
2999
 
2945
 
3000
 
2946
    PROCEDURE ParseCase (parser: PARS.PARSER; e: PARS.EXPR; pos: PARS.POSITION);
3001
    PROCEDURE ParseCase (parser: PARS.PARSER; e: PARS.EXPR; pos: PARS.POSITION);
2947
    VAR
3002
    VAR
2948
        table, end, else: INTEGER;
3003
        table, _end, _else: INTEGER;
2949
        tree: AVL.NODE;
3004
        tree: AVL.NODE;
Line 2950... Line 3005...
2950
        item: LISTS.ITEM;
3005
        item: LISTS.ITEM;
Line 2951... Line 3006...
2951
 
3006
 
2952
    BEGIN
3007
    BEGIN
2953
        LISTS.push(CaseVariants, NewVariant(0, NIL));
3008
        LISTS.push(CaseVariants, NewVariant(0, NIL));
2954
        end   := IL.NewLabel();
3009
        _end  := IL.NewLabel();
2955
        else  := IL.NewLabel();
3010
        _else := IL.NewLabel();
Line 2956... Line 3011...
2956
        table := IL.NewLabel();
3011
        table := IL.NewLabel();
2957
        IL.AddCmd(IL.opSWITCH, ORD(isRecPtr(e)));
3012
        IL.AddCmd(IL.opSWITCH, ORD(isRecPtr(e)));
2958
        IL.AddJmpCmd(IL.opJMP, table);
3013
        IL.AddJmpCmd(IL.opJMP, table);
2959
 
3014
 
2960
        tree := NIL;
3015
        tree := NIL;
2961
 
3016
 
2962
        case(parser, e, tree, end);
3017
        _case(parser, e, tree, _end);
2963
        WHILE parser.sym = SCAN.lxBAR DO
3018
        WHILE parser.sym = SCAN.lxBAR DO
Line 2964... Line 3019...
2964
            PARS.Next(parser);
3019
            PARS.Next(parser);
2965
            case(parser, e, tree, end)
3020
            _case(parser, e, tree, _end)
Line 2966... Line 3021...
2966
        END;
3021
        END;
2967
 
3022
 
2968
        IL.SetLabel(else);
3023
        IL.SetLabel(_else);
2969
        IF parser.sym = SCAN.lxELSE THEN
3024
        IF parser.sym = SCAN.lxELSE THEN
2970
            PARS.Next(parser);
3025
            PARS.Next(parser);
2971
            parser.StatSeq(parser);
3026
            parser.StatSeq(parser);
2972
            IL.AddJmpCmd(IL.opJMP, end)
3027
            IL.AddJmpCmd(IL.opJMP, _end)
2973
        ELSE
3028
        ELSE
Line 2974... Line 3029...
2974
            IL.OnError(pos.line, errCASE)
3029
            IL.OnError(pos.line, errCASE)
2975
        END;
3030
        END;
2976
 
3031
 
Line 2977... Line 3032...
2977
        PARS.checklex(parser, SCAN.lxEND);
3032
        PARS.checklex(parser, SCAN.lxEND);
2978
        PARS.Next(parser);
3033
        PARS.Next(parser);
2979
 
3034
 
Line 3046... Line 3101...
3046
 
3101
 
3047
    PARS.ExpectSym(parser, SCAN.lxIDENT);
3102
    PARS.ExpectSym(parser, SCAN.lxIDENT);
3048
    ident := PROG.getIdent(parser.unit, parser.lex.ident, TRUE);
3103
    ident := PROG.getIdent(parser.unit, parser.lex.ident, TRUE);
3049
    PARS.check1(ident # NIL, parser, 48);
3104
    PARS.check1(ident # NIL, parser, 48);
3050
    PARS.check1(ident.typ = PROG.idVAR, parser, 93);
3105
    PARS.check1(ident.typ = PROG.idVAR, parser, 93);
3051
    PARS.check1(ident.type = tINTEGER, parser, 97);
3106
    PARS.check1(ident._type = tINTEGER, parser, 97);
3052
    PARS.ExpectSym(parser, SCAN.lxASSIGN);
3107
    PARS.ExpectSym(parser, SCAN.lxASSIGN);
3053
    NextPos(parser, pos);
3108
    NextPos(parser, pos);
3054
    expression(parser, e);
3109
    expression(parser, e);
Line 3055... Line 3110...
3055
    PARS.check(isInt(e), pos, 76);
3110
    PARS.check(isInt(e), pos, 76);
Line 3056... Line 3111...
3056
 
3111
 
3057
    offset := PROG.getOffset(PARS.program, ident);
3112
    offset := PROG.getOffset(ident);
3058
 
3113
 
3059
    IF ident.global THEN
3114
    IF ident.global THEN
Line 3073... Line 3128...
3073
    IF ident.global THEN
3128
    IF ident.global THEN
3074
        IL.AddCmd(IL.opGADR, offset)
3129
        IL.AddCmd(IL.opGADR, offset)
3075
    ELSE
3130
    ELSE
3076
        IL.AddCmd(IL.opLADR, -offset)
3131
        IL.AddCmd(IL.opLADR, -offset)
3077
    END;
3132
    END;
3078
    IL.load(ident.type.size);
3133
    IL.load(ident._type.size);
Line 3079... Line 3134...
3079
 
3134
 
3080
    PARS.checklex(parser, SCAN.lxTO);
3135
    PARS.checklex(parser, SCAN.lxTO);
3081
    NextPos(parser, pos2);
3136
    NextPos(parser, pos2);
3082
    expression(parser, e);
3137
    expression(parser, e);
Line 3110... Line 3165...
3110
        ELSE
3165
        ELSE
3111
            IL.AddCmd0(IL.opGE)
3166
            IL.AddCmd0(IL.opGE)
3112
        END
3167
        END
3113
    END;
3168
    END;
Line 3114... Line 3169...
3114
 
3169
 
Line 3115... Line 3170...
3115
    IL.AddJmpCmd(IL.opJNE, L2);
3170
    IL.AddJmpCmd(IL.opJZ, L2);
3116
 
3171
 
3117
    PARS.checklex(parser, SCAN.lxDO);
3172
    PARS.checklex(parser, SCAN.lxDO);
Line 3169... Line 3224...
3169
        statement(parser)
3224
        statement(parser)
3170
    END
3225
    END
3171
END StatSeq;
3226
END StatSeq;
Line 3172... Line 3227...
3172
 
3227
 
3173
 
3228
 
3174
PROCEDURE chkreturn (parser: PARS.PARSER; e: PARS.EXPR; t: PROG.TYPE_; pos: PARS.POSITION): BOOLEAN;
3229
PROCEDURE chkreturn (parser: PARS.PARSER; e: PARS.EXPR; t: PROG._TYPE; pos: PARS.POSITION): BOOLEAN;
Line 3175... Line 3230...
3175
VAR
3230
VAR
3176
    res: BOOLEAN;
3231
    res: BOOLEAN;
3177
 
3232
 
3178
BEGIN
3233
BEGIN
3179
    res := assigncomp(e, t);
3234
    res := assigncomp(e, t);
3180
    IF res THEN
3235
    IF res THEN
3181
        IF e.obj = eCONST THEN
3236
        IF e.obj = eCONST THEN
3182
            IF e.type = tREAL THEN
3237
            IF e._type = tREAL THEN
3183
                IL.Float(ARITH.Float(e.value))
3238
                Float(parser, e)
3184
            ELSIF e.type.typ = PROG.tNIL THEN
3239
            ELSIF e._type.typ = PROG.tNIL THEN
3185
                IL.Const(0)
3240
                IL.Const(0)
3186
            ELSE
3241
            ELSE
3187
                LoadConst(e)
3242
                LoadConst(e)
3188
            END
3243
            END
3189
        ELSIF (e.type = tINTEGER) & (t = tBYTE) & (chkBYTE IN Options.checking) THEN
3244
        ELSIF (e._type = tINTEGER) & (t = tBYTE) & (chkBYTE IN Options.checking) THEN
3190
            CheckRange(256, pos.line, errBYTE)
3245
            CheckRange(256, pos.line, errBYTE)
3191
        ELSIF e.obj = ePROC THEN
3246
        ELSIF e.obj = ePROC THEN
3192
            PARS.check(e.ident.global, pos, 85);
3247
            PARS.check(e.ident.global, pos, 85);
3193
            IL.PushProc(e.ident.proc.label)
-
 
3194
        ELSIF e.obj = eIMP THEN
-
 
3195
            IL.PushImpProc(e.ident.import)
-
 
3196
        END;
-
 
3197
 
3248
            IL.PushProc(e.ident.proc.label)
3198
        IF e.type = tREAL THEN
3249
        ELSIF e.obj = eIMP THEN
Line 3199... Line 3250...
3199
            IL.retf
3250
            IL.PushImpProc(e.ident._import)
3200
        END
3251
        END
Line 3214... Line 3265...
3214
        id: PROG.IDENT;
3265
        id: PROG.IDENT;
Line 3215... Line 3266...
3215
 
3266
 
3216
    BEGIN
3267
    BEGIN
Line 3217... Line 3268...
3217
        id := PROG.getIdent(rtl, SCAN.enterid(name), FALSE);
3268
        id := PROG.getIdent(rtl, SCAN.enterid(name), FALSE);
3218
 
3269
 
3219
        IF (id # NIL) & (id.import # NIL) THEN
3270
        IF (id # NIL) & (id._import # NIL) THEN
3220
            IL.set_rtl(idx, -id.import(IL.IMPORT_PROC).label);
3271
            IL.set_rtl(idx, -id._import(IL.IMPORT_PROC).label);
3221
            id.proc.used := TRUE
3272
            id.proc.used := TRUE
3222
        ELSIF (id # NIL) & (id.proc # NIL) THEN
3273
        ELSIF (id # NIL) & (id.proc # NIL) THEN
3223
            IL.set_rtl(idx, id.proc.label);
3274
            IL.set_rtl(idx, id.proc.label);
Line 3227... Line 3278...
3227
        END
3278
        END
3228
    END getproc;
3279
    END getproc;
Line 3229... Line 3280...
3229
 
3280
 
3230
 
3281
 
3231
BEGIN
3282
BEGIN
Line 3232... Line 3283...
3232
    rtl := PARS.program.rtl;
3283
    rtl := PROG.program.rtl;
3233
    ASSERT(rtl # NIL);
3284
    ASSERT(rtl # NIL);
3234
 
3285
 
Line 3254... Line 3305...
3254
        getproc(rtl, "_exit",     IL._exit);
3305
        getproc(rtl, "_exit",     IL._exit);
3255
        getproc(rtl, "_dispose",  IL._dispose);
3306
        getproc(rtl, "_dispose",  IL._dispose);
3256
        getproc(rtl, "_isrec",    IL._isrec);
3307
        getproc(rtl, "_isrec",    IL._isrec);
3257
        getproc(rtl, "_dllentry", IL._dllentry);
3308
        getproc(rtl, "_dllentry", IL._dllentry);
3258
        getproc(rtl, "_sofinit",  IL._sofinit)
3309
        getproc(rtl, "_sofinit",  IL._sofinit)
3259
    ELSIF CPU = TARGETS.cpuTHUMB THEN
3310
    ELSIF CPU IN {TARGETS.cpuTHUMB, TARGETS.cpuRVM32I} THEN
3260
        getproc(rtl, "_fmul",  IL._fmul);
3311
        getproc(rtl, "_fmul",  IL._fmul);
3261
        getproc(rtl, "_fdiv",  IL._fdiv);
3312
        getproc(rtl, "_fdiv",  IL._fdiv);
3262
        getproc(rtl, "_fdivi", IL._fdivi);
3313
        getproc(rtl, "_fdivi", IL._fdivi);
3263
        getproc(rtl, "_fadd",  IL._fadd);
3314
        getproc(rtl, "_fadd",  IL._fadd);
3264
        getproc(rtl, "_fsub",  IL._fsub);
3315
        getproc(rtl, "_fsub",  IL._fsub);
3265
        getproc(rtl, "_fsubi", IL._fsubi);
3316
        getproc(rtl, "_fsubi", IL._fsubi);
3266
        getproc(rtl, "_fcmp",  IL._fcmp);
3317
        getproc(rtl, "_fcmp",  IL._fcmp);
3267
        getproc(rtl, "_floor", IL._floor);
3318
        getproc(rtl, "_floor", IL._floor);
3268
        getproc(rtl, "_flt",   IL._flt);
3319
        getproc(rtl, "_flt",   IL._flt);
3269
        getproc(rtl, "_pack",  IL._pack);
3320
        getproc(rtl, "_pack",  IL._pack);
3270
        getproc(rtl, "_unpk",  IL._unpk)
3321
        getproc(rtl, "_unpk",  IL._unpk);
-
 
3322
        IF CPU = TARGETS.cpuRVM32I THEN
-
 
3323
            getproc(rtl, "_error", IL._error)
-
 
3324
        END
3271
    END
3325
    END
Line 3272... Line 3326...
3272
 
3326
 
Line 3277... Line 3331...
3277
VAR
3331
VAR
3278
    parser: PARS.PARSER;
3332
    parser: PARS.PARSER;
3279
    ext: PARS.PATH;
3333
    ext: PARS.PATH;
Line 3280... Line 3334...
3280
 
3334
 
3281
BEGIN
3335
BEGIN
3282
    tINTEGER := PARS.program.stTypes.tINTEGER;
3336
    tINTEGER := PROG.program.stTypes.tINTEGER;
3283
    tBYTE    := PARS.program.stTypes.tBYTE;
3337
    tBYTE    := PROG.program.stTypes.tBYTE;
3284
    tCHAR    := PARS.program.stTypes.tCHAR;
3338
    tCHAR    := PROG.program.stTypes.tCHAR;
3285
    tSET     := PARS.program.stTypes.tSET;
3339
    tSET     := PROG.program.stTypes.tSET;
3286
    tBOOLEAN := PARS.program.stTypes.tBOOLEAN;
3340
    tBOOLEAN := PROG.program.stTypes.tBOOLEAN;
3287
    tWCHAR   := PARS.program.stTypes.tWCHAR;
3341
    tWCHAR   := PROG.program.stTypes.tWCHAR;
Line 3288... Line 3342...
3288
    tREAL    := PARS.program.stTypes.tREAL;
3342
    tREAL    := PROG.program.stTypes.tREAL;
3289
 
3343
 
Line 3290... Line 3344...
3290
    Options := options;
3344
    Options := options;
Line 3297... Line 3351...
3297
    CaseVariants := LISTS.create(NIL);
3351
    CaseVariants := LISTS.create(NIL);
3298
    LISTS.push(CaseVariants, NewVariant(0, NIL));
3352
    LISTS.push(CaseVariants, NewVariant(0, NIL));
Line 3299... Line 3353...
3299
 
3353
 
Line 3300... Line 3354...
3300
    IL.init(CPU);
3354
    IL.init(CPU);
3301
 
3355
 
3302
    IF CPU # TARGETS.cpuMSP430 THEN
3356
    IF TARGETS.RTL THEN
3303
        parser := PARS.create(path, lib_path, StatSeq, expression, designator, chkreturn);
3357
        parser := PARS.create(path, lib_path, StatSeq, expression, designator, chkreturn);
3304
        IF parser.open(parser, UTILS.RTL_NAME) THEN
3358
        IF parser.open(parser, UTILS.RTL_NAME) THEN
3305
            parser.parse(parser);
3359
            parser.parse(parser);
Line 3325... Line 3379...
3325
        ERRORS.FileNotFound(path, modname, UTILS.FILE_EXT)
3379
        ERRORS.FileNotFound(path, modname, UTILS.FILE_EXT)
3326
    END;
3380
    END;
Line 3327... Line 3381...
3327
 
3381
 
Line 3328... Line 3382...
3328
    PARS.destroy(parser);
3382
    PARS.destroy(parser);
3329
 
3383
 
3330
    IF PARS.program.bss > UTILS.MAX_GLOBAL_SIZE THEN
3384
    IF PROG.program.bss > UTILS.MAX_GLOBAL_SIZE THEN
Line 3331... Line 3385...
3331
        ERRORS.Error(204)
3385
        ERRORS.Error(204)
3332
    END;
3386
    END;
3333
 
3387
 
Line 3334... Line 3388...
3334
    IF CPU # TARGETS.cpuMSP430 THEN
3388
    IF TARGETS.RTL THEN
Line 3335... Line 3389...
3335
        setrtl
3389
        setrtl
Line 3336... Line 3390...
3336
    END;
3390
    END;
3337
 
3391
 
3338
    PROG.DelUnused(PARS.program, IL.DelImport);
3392
    PROG.DelUnused(IL.DelImport);
3339
 
3393
 
3340
    IL.set_bss(PARS.program.bss);
3394
    IL.set_bss(PROG.program.bss);
-
 
3395
 
3341
 
3396
    CASE CPU OF
Line 3342... Line 3397...
3342
    CASE CPU OF
3397
    |TARGETS.cpuAMD64:   AMD64.CodeGen(outname, target, options)