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 1... Line 1...
1
(*
1
(*
2
    BSD 2-Clause License
2
    BSD 2-Clause License
Line 3... Line 3...
3
 
3
 
4
    Copyright (c) 2018-2019, Anton Krotov
4
    Copyright (c) 2018-2020, Anton Krotov
5
    All rights reserved.
5
    All rights reserved.
Line 6... Line 6...
6
*)
6
*)
Line 7... Line 7...
7
 
7
 
Line 8... Line 8...
8
MODULE PROG;
8
MODULE PROG;
Line 9... Line 9...
9
 
9
 
Line 22... Line 22...
22
    idSYSPROC* = 12;  idIMP*    = 13;
22
    idSYSPROC* = 12;  idIMP*    = 13;
Line 23... Line 23...
23
 
23
 
24
    tINTEGER* =  1;  tBYTE*      =  2;  tCHAR*   =  3;  tSET*    =  4;
24
    tINTEGER* =  1;  tBYTE*      =  2;  tCHAR*   =  3;  tSET*    =  4;
25
    tBOOLEAN* =  5;  tREAL*      =  6;  tARRAY*  =  7;  tRECORD* =  8;
25
    tBOOLEAN* =  5;  tREAL*      =  6;  tARRAY*  =  7;  tRECORD* =  8;
26
    tPOINTER* =  9;  tPROCEDURE* = 10;  tSTRING* = 11;  tNIL*    = 12;
26
    tPOINTER* =  9;  tPROCEDURE* = 10;  tSTRING* = 11;  tNIL*    = 12;
Line 27... Line 27...
27
    tCARD32*  = 13;  tANYREC*    = 14;  tWCHAR*  = 15;
27
    tCARD32*  = 13;  tANYREC*    = 14;  tWCHAR*  = 15;  tNONE*   = 16;
Line 28... Line 28...
28
 
28
 
29
    BASICTYPES* = {tINTEGER, tBYTE, tCHAR, tSET, tBOOLEAN, tREAL, tCARD32, tWCHAR};
29
    BASICTYPES* = {tINTEGER, tBYTE, tCHAR, tSET, tBOOLEAN, tREAL, tCARD32, tWCHAR};
Line 38... Line 38...
38
    stDISPOSE* = 23;  stLSR*     = 24;  stBITS*  = 25;  sysCODE*  = 26;
38
    stDISPOSE* = 23;  stLSR*     = 24;  stBITS*   = 25;  sysCODE*  = 26;
39
    sysMOVE*   = 27;  stLENGTH*  = 28;  stMIN*   = 29;  stMAX*    = 30;
39
    sysMOVE*   = 27;  stLENGTH*  = 28;  stMIN*    = 29;  stMAX*    = 30;
40
    sysSADR*   = 31;  sysTYPEID* = 32;  sysCOPY* = 33;  sysINF*   = 34;
40
    sysSADR*   = 31;  sysTYPEID* = 32;  sysCOPY*  = 33;  sysINF*   = 34;
41
    sysPUT8*   = 35;  sysPUT16*  = 36;  stCOPY*  = 37;  stWCHR*   = 38;
41
    sysPUT8*   = 35;  sysPUT16*  = 36;  stCOPY*   = 37;  stWCHR*   = 38;
42
    sysWSADR*  = 39;  sysPUT32*  = 40;  (*sysNOP*  = 41;  sysEINT*  = 42;
42
    sysWSADR*  = 39;  sysPUT32*  = 40;  (*sysNOP*   = 41;  sysEINT*  = 42;
43
    sysDINT*   = 43;*)
43
    sysDINT*   = 43;*)sysGET8*   = 44;  sysGET16* = 45;  sysGET32* = 46;
Line 44... Line 44...
44
 
44
 
45
    default32* =  2;
45
    default32* =  2;  _default32* = default32 + 1;
46
    stdcall*   =  4;  _stdcall*   = stdcall + 1;
46
    stdcall*   =  4;  _stdcall*   = stdcall + 1;
47
    ccall*     =  6;  _ccall*     = ccall + 1;
47
    ccall*     =  6;  _ccall*     = ccall + 1;
48
    ccall16*   =  8;  _ccall16*   = ccall16 + 1;
48
    ccall16*   =  8;  _ccall16*   = ccall16 + 1;
49
    win64*     = 10;  _win64*     = win64 + 1;
49
    win64*     = 10;  _win64*     = win64 + 1;
50
    stdcall64* = 12;  _stdcall64* = stdcall64 + 1;
50
    stdcall64* = 12;  _stdcall64* = stdcall64 + 1;
51
    default64* = 14;
51
    default64* = 14;  _default64* = default64 + 1;
52
    systemv*   = 16;  _systemv*   = systemv + 1;
52
    systemv*   = 16;  _systemv*   = systemv + 1;
53
    default16* = 18;
53
    default16* = 18;
Line 54... Line 54...
54
    code*      = 20;  _code*      = code + 1;
54
    code*      = 20;  _code*      = code + 1;
Line 55... Line 55...
55
 
55
 
Line 56... Line 56...
56
    noalign* = 22;
56
    noalign* = 22;
57
 
57
 
58
    callee_clean_up* = {default32, stdcall, _stdcall, default64, stdcall64, _stdcall64};
58
    callee_clean_up* = {default32, stdcall, _stdcall, default64, stdcall64, _stdcall64};
59
 
59
 
Line 60... Line 60...
60
    sf_stdcall* = 0; sf_stdcall64* = 1; sf_ccall*   = 2; sf_ccall16* = 3;
60
    sf_stdcall* =  0; sf_stdcall64* = 1; sf_ccall*   = 2; sf_ccall16* = 3;
61
    sf_win64*   = 4; sf_systemv*   = 5; sf_windows* = 6; sf_linux*   = 7;
61
    sf_win64*   =  4; sf_systemv*   = 5; sf_windows* = 6; sf_linux*   = 7;
Line 62... Line 62...
62
    sf_code*    = 8;
62
    sf_code*    =  8; sf_oberon*    = 9;
Line 63... Line 63...
63
    sf_noalign* = 9;
63
    sf_noalign* = 10;
Line 64... Line 64...
64
 
64
 
Line 65... Line 65...
65
    proc_flags* = {sf_stdcall, sf_stdcall64, sf_ccall, sf_ccall16, sf_win64, sf_systemv, sf_windows, sf_linux, sf_code};
65
    proc_flags* = {sf_stdcall, sf_stdcall64, sf_ccall, sf_ccall16, sf_win64, sf_systemv, sf_windows, sf_linux, sf_code, sf_oberon};
66
    rec_flags*  = {sf_noalign};
66
    rec_flags*  = {sf_noalign};
67
 
67
 
Line 68... Line 68...
68
    STACK_FRAME = 2;
68
    STACK_FRAME = 2;
Line 69... Line 69...
69
 
69
 
Line 70... Line 70...
70
 
70
 
Line 71... Line -...
71
TYPE
-
 
72
 
-
 
73
    OPTIONS* = RECORD
71
TYPE
Line 74... Line 72...
74
 
72
 
Line 75... Line 73...
75
        version*, stack*, ram*, rom*: INTEGER;
73
    OPTIONS* = RECORD
76
        pic*: BOOLEAN;
74
 
77
        checking*: SET
75
        version*, stack*, ram*, rom*: INTEGER;
Line 78... Line 76...
78
 
76
        pic*, lower*: BOOLEAN;
79
    END;
77
        checking*: SET
Line 100... Line 98...
100
    PROC* = POINTER TO RECORD (LISTS.ITEM)
98
    PROC* = POINTER TO RECORD (LISTS.ITEM)
Line 101... Line 99...
101
 
99
 
102
        label*:      INTEGER;
100
        label*:      INTEGER;
103
        used*:       BOOLEAN;
101
        used*:       BOOLEAN;
104
        processed*:  BOOLEAN;
102
        processed*:  BOOLEAN;
105
        import*:     LISTS.ITEM;
103
        _import*:    LISTS.ITEM;
106
        using*:      LISTS.LIST;
104
        using*:      LISTS.LIST;
107
        enter*,
105
        enter*,
Line 108... Line 106...
108
        leave*:      LISTS.ITEM
106
        leave*:      LISTS.ITEM
Line 115... Line 113...
115
 
113
 
Line 116... Line 114...
116
    END;
114
    END;
Line 117... Line -...
117
 
-
 
118
    rUNIT = RECORD (LISTS.ITEM)
115
 
119
 
116
    rUNIT = RECORD (LISTS.ITEM)
120
        program*:    PROGRAM;
117
 
121
        name*:       SCAN.IDENT;
118
        name*:       SCAN.IDENT;
122
        idents*:     LISTS.LIST;
119
        idents*:     LISTS.LIST;
Line 131... Line 128...
131
 
128
 
Line 132... Line 129...
132
    FIELD* = POINTER TO rFIELD;
129
    FIELD* = POINTER TO rFIELD;
Line 133... Line 130...
133
 
130
 
Line 134... Line 131...
134
    PARAM* = POINTER TO rPARAM;
131
    PARAM* = POINTER TO rPARAM;
135
 
132
 
136
    rTYPE_ = RECORD (LISTS.ITEM)
133
    rTYPE = RECORD (LISTS.ITEM)
137
 
134
 
138
        typ*:        INTEGER;
135
        typ*:        INTEGER;
139
        size*:       INTEGER;
136
        size*:       INTEGER;
140
        parSize*:    INTEGER;
137
        parSize*:    INTEGER;
141
        length*:     INTEGER;
138
        length*:     INTEGER;
142
        align*:      INTEGER;
139
        align*:      INTEGER;
143
        base*:       TYPE_;
140
        base*:       _TYPE;
144
        fields*:     LISTS.LIST;
141
        fields*:     LISTS.LIST;
145
        params*:     LISTS.LIST;
142
        params*:     LISTS.LIST;
146
        unit*:       UNIT;
143
        unit*:       UNIT;
147
        closed*:     BOOLEAN;
144
        closed*:     BOOLEAN;
Line 148... Line 145...
148
        num*:        INTEGER;
145
        num*:        INTEGER;
Line 149... Line 146...
149
        call*:       INTEGER;
146
        call*:       INTEGER;
Line 150... Line 147...
150
        import*:     BOOLEAN;
147
        _import*:    BOOLEAN;
151
        noalign*:    BOOLEAN
148
        noalign*:    BOOLEAN
152
 
149
 
153
    END;
150
    END;
Line 154... Line 151...
154
 
151
 
Line 155... Line 152...
155
    rFIELD = RECORD (LISTS.ITEM)
152
    rFIELD = RECORD (LISTS.ITEM)
Line 156... Line 153...
156
 
153
 
157
        type*:       TYPE_;
154
        _type*:      _TYPE;
158
        name*:       SCAN.IDENT;
155
        name*:       SCAN.IDENT;
159
        export*:     BOOLEAN;
156
        export*:     BOOLEAN;
Line 160... Line 157...
160
        offset*:     INTEGER
157
        offset*:     INTEGER
Line 161... Line 158...
161
 
158
 
Line 162... Line 159...
162
    END;
159
    END;
163
 
160
 
164
    rPARAM = RECORD (LISTS.ITEM)
161
    rPARAM = RECORD (LISTS.ITEM)
165
 
162
 
166
        name*:       SCAN.IDENT;
163
        name*:       SCAN.IDENT;
167
        type*:       TYPE_;
164
        _type*:      _TYPE;
168
        vPar*:       BOOLEAN;
165
        vPar*:       BOOLEAN;
169
        offset*:     INTEGER
166
        offset*:     INTEGER
170
 
167
 
171
    END;
168
    END;
172
 
169
 
173
    rIDENT = RECORD (LISTS.ITEM)
170
    rIDENT = RECORD (LISTS.ITEM)
174
 
171
 
Line 175... Line 172...
175
        name*:       SCAN.IDENT;
172
        name*:       SCAN.IDENT;
Line 176... Line 173...
176
        typ*:        INTEGER;
173
        typ*:        INTEGER;
Line 177... Line 174...
177
        export*:     BOOLEAN;
174
        export*:     BOOLEAN;
178
        import*:     LISTS.ITEM;
175
        _import*:    LISTS.ITEM;
179
        unit*:       UNIT;
176
        unit*:       UNIT;
180
        value*:      ARITH.VALUE;
177
        value*:      ARITH.VALUE;
Line 204... Line 201...
204
        options*:    OPTIONS;
201
        options*:    OPTIONS;
Line 205... Line 202...
205
 
202
 
Line 206... Line 203...
206
        stTypes*:    RECORD
203
        stTypes*:    RECORD
207
 
204
 
Line 208... Line 205...
208
            tINTEGER*, tBYTE*, tCHAR*, tWCHAR*, tSET*, tBOOLEAN*, tREAL*,
205
            tINTEGER*, tBYTE*, tCHAR*, tWCHAR*, tSET*, tBOOLEAN*, tREAL*,
Line 209... Line 206...
209
            tSTRING*, tNIL*, tCARD32*, tANYREC*: TYPE_
206
            tSTRING*, tNIL*, tCARD32*, tANYREC*, tNONE*: _TYPE
Line 210... Line 207...
210
 
207
 
Line 211... Line 208...
211
        END
208
        END
Line -... Line 209...
-
 
209
 
212
 
210
    END;
-
 
211
 
Line 213... Line 212...
213
    END;
212
    DELIMPORT = PROCEDURE (_import: LISTS.ITEM);
214
 
213
 
215
    DELIMPORT = PROCEDURE (import: LISTS.ITEM);
214
 
Line 235... Line 234...
235
 
234
 
236
    RETURN ident
235
    RETURN ident
Line 237... Line 236...
237
END NewIdent;
236
END NewIdent;
238
 
237
 
239
 
238
 
Line 240... Line 239...
240
PROCEDURE getOffset* (program: PROGRAM; varIdent: IDENT): INTEGER;
239
PROCEDURE getOffset* (varIdent: IDENT): INTEGER;
241
VAR
240
VAR
242
    size: INTEGER;
241
    size: INTEGER;
243
 
242
 
244
BEGIN
243
BEGIN
245
    IF varIdent.offset = -1 THEN
244
    IF varIdent.offset = -1 THEN
246
        size := varIdent.type.size;
245
        size := varIdent._type.size;
247
        IF varIdent.global THEN
246
        IF varIdent.global THEN
248
            IF UTILS.Align(program.bss, varIdent.type.align) THEN
247
            IF UTILS.Align(program.bss, varIdent._type.align) THEN
249
                IF UTILS.maxint - program.bss >= size THEN
248
                IF UTILS.maxint - program.bss >= size THEN
Line 279... Line 278...
279
    ident := unit.idents.last(IDENT);
278
    ident := unit.idents.last(IDENT);
280
    WHILE (ident # NIL) & (ident.typ # idGUARD) DO
279
    WHILE (ident # NIL) & (ident.typ # idGUARD) DO
281
        IF (ident.typ = idVAR) & (ident.offset = -1) THEN
280
        IF (ident.typ = idVAR) & (ident.offset = -1) THEN
282
            ERRORS.HintMsg(ident.name.s, ident.pos.line, ident.pos.col, 0);
281
            ERRORS.HintMsg(ident.name.s, ident.pos.line, ident.pos.col, 0);
283
            IF ident.export THEN
282
            IF ident.export THEN
284
                offset := getOffset(unit.program, ident)
283
                offset := getOffset(ident)
285
            END
284
            END
286
        END;
285
        END;
287
        ident := ident.prev(IDENT)
286
        ident := ident.prev(IDENT)
288
    END;
287
    END;
Line 320... Line 319...
320
PROCEDURE addIdent* (unit: UNIT; ident: SCAN.IDENT; typ: INTEGER): IDENT;
319
PROCEDURE addIdent* (unit: UNIT; ident: SCAN.IDENT; typ: INTEGER): IDENT;
321
VAR
320
VAR
322
    item:  IDENT;
321
    item:  IDENT;
323
    res:   BOOLEAN;
322
    res:   BOOLEAN;
324
    proc:  PROC;
323
    proc:  PROC;
325
    procs: LISTS.LIST;
-
 
Line 326... Line 324...
326
 
324
 
327
BEGIN
325
BEGIN
328
    ASSERT(unit # NIL);
326
    ASSERT(unit # NIL);
Line 335... Line 333...
335
 
333
 
336
        item.name   := ident;
334
        item.name    := ident;
337
        item.typ    := typ;
335
        item.typ     := typ;
338
        item.unit   := NIL;
336
        item.unit    := NIL;
339
        item.export := FALSE;
337
        item.export  := FALSE;
340
        item.import := NIL;
338
        item._import := NIL;
341
        item.type   := NIL;
339
        item._type   := NIL;
342
        item.value.typ := 0;
340
        item.value.typ := 0;
Line 343... Line 341...
343
        item.stproc := 0;
341
        item.stproc := 0;
344
 
342
 
345
        item.global := unit.scopeLvl = 0;
343
        item.global := unit.scopeLvl = 0;
Line 346... Line 344...
346
        item.scopeLvl := unit.scopeLvl;
344
        item.scopeLvl := unit.scopeLvl;
347
        item.offset := -1;
345
        item.offset := -1;
348
 
346
 
349
        IF item.typ IN {idPROC, idIMP} THEN
347
        IF item.typ IN {idPROC, idIMP} THEN
350
            NEW(proc);
348
            NEW(proc);
351
            proc.import := NIL;
349
            proc._import := NIL;
352
            proc.label := 0;
350
            proc.label := 0;
353
            proc.used := FALSE;
-
 
354
            proc.processed := FALSE;
351
            proc.used := FALSE;
355
            proc.using := LISTS.create(NIL);
352
            proc.processed := FALSE;
356
            procs := unit.program.procs;
353
            proc.using := LISTS.create(NIL);
Line 357... Line 354...
357
            LISTS.push(procs, proc);
354
            LISTS.push(program.procs, proc);
358
            item.proc := proc
355
            item.proc := proc
Line 391... Line 388...
391
        END
388
        END
392
    END
389
    END
393
END UseProc;
390
END UseProc;
Line 394... Line 391...
394
 
391
 
395
 
392
 
396
PROCEDURE setVarsType* (unit: UNIT; type: TYPE_);
393
PROCEDURE setVarsType* (unit: UNIT; _type: _TYPE);
Line 397... Line 394...
397
VAR
394
VAR
398
    item: IDENT;
395
    item: IDENT;
Line 399... Line 396...
399
 
396
 
400
BEGIN
397
BEGIN
401
    ASSERT(type # NIL);
398
    ASSERT(_type # NIL);
402
 
399
 
403
    item := unit.idents.last(IDENT);
400
    item := unit.idents.last(IDENT);
404
    WHILE (item # NIL) & (item.typ = idVAR) & (item.type = NIL) DO
401
    WHILE (item # NIL) & (item.typ = idVAR) & (item._type = NIL) DO
Line 479... Line 476...
479
        item := item.prev(IDENT);
476
        item := item.prev(IDENT);
480
        IF (del.typ = idVAR) & (del.offset = -1) THEN
477
        IF (del.typ = idVAR) & (del.offset = -1) THEN
481
            ERRORS.HintMsg(del.name.s, del.pos.line, del.pos.col, 0)
478
            ERRORS.HintMsg(del.name.s, del.pos.line, del.pos.col, 0)
482
        END;
479
        END;
483
        IF (variables # NIL) & (del.typ IN {idVAR, idPARAM}) & (del.offset # -1) THEN
480
        IF (variables # NIL) & (del.typ IN {idVAR, idPARAM}) & (del.offset # -1) THEN
484
            IF del.type.typ IN BASICTYPES - {tREAL} + {tPOINTER, tPROCEDURE} THEN
481
            IF del._type.typ IN BASICTYPES - {tREAL} + {tPOINTER, tPROCEDURE} THEN
485
                lvar := IL.NewVar();
482
                lvar := IL.NewVar();
486
                lvar.offset := del.offset;
483
                lvar.offset := del.offset;
487
                lvar.size   := del.type.size;
484
                lvar.size   := del._type.size;
488
                IF del.typ = idVAR THEN
485
                IF del.typ = idVAR THEN
489
                    lvar.offset := -lvar.offset
486
                    lvar.offset := -lvar.offset
490
                END;
487
                END;
491
                LISTS.push(variables, lvar)
488
                LISTS.push(variables, lvar)
492
            END
489
            END
Line 502... Line 499...
502
 
499
 
503
    DEC(unit.scopeLvl)
500
    DEC(unit.scopeLvl)
Line 504... Line 501...
504
END closeScope;
501
END closeScope;
505
 
502
 
506
 
503
 
Line 507... Line 504...
507
PROCEDURE frwPtr* (unit: UNIT; type: TYPE_; baseIdent: SCAN.IDENT; pos: SCAN.POSITION);
504
PROCEDURE frwPtr* (unit: UNIT; _type: _TYPE; baseIdent: SCAN.IDENT; pos: SCAN.POSITION);
508
VAR
505
VAR
509
    newptr: FRWPTR;
506
    newptr: FRWPTR;
510
 
507
 
Line 511... Line 508...
511
BEGIN
508
BEGIN
Line 512... Line 509...
512
    ASSERT(unit # NIL);
509
    ASSERT(unit # NIL);
513
    ASSERT(type # NIL);
510
    ASSERT(_type # NIL);
514
    ASSERT(baseIdent # NIL);
511
    ASSERT(baseIdent # NIL);
515
 
512
 
516
    NEW(newptr);
513
    NEW(newptr);
Line 537... Line 534...
537
 
534
 
538
    WHILE (item # NIL) & ~item.linked & (res = NIL) DO
535
    WHILE (item # NIL) & ~item.linked & (res = NIL) DO
Line 539... Line 536...
539
        ident := getIdent(unit, item.baseIdent, TRUE);
536
        ident := getIdent(unit, item.baseIdent, TRUE);
540
 
537
 
541
        IF (ident # NIL) THEN
538
        IF (ident # NIL) THEN
542
            IF (ident.typ = idTYPE) & (ident.type.typ = tRECORD) THEN
539
            IF (ident.typ = idTYPE) & (ident._type.typ = tRECORD) THEN
543
                item.type.base := ident.type;
540
                item._type.base := ident._type;
544
                item.linked := TRUE
541
                item.linked := TRUE
545
            ELSE
542
            ELSE
546
                item.notRecord := TRUE;
543
                item.notRecord := TRUE;
Line 556... Line 553...
556
 
553
 
557
    RETURN res
554
    RETURN res
Line 558... Line 555...
558
END linkPtr;
555
END linkPtr;
559
 
556
 
560
 
557
 
561
PROCEDURE isTypeEq* (t1, t2: TYPE_): BOOLEAN;
558
PROCEDURE isTypeEq* (t1, t2: _TYPE): BOOLEAN;
Line 562... Line 559...
562
VAR
559
VAR
Line 574... Line 571...
574
        param2 := t2.params.first;
571
        param2 := t2.params.first;
Line 575... Line 572...
575
 
572
 
Line 576... Line 573...
576
        res := ((t1.call = t2.call) OR (t1.call IN {code, _code}) OR (t2.call IN {code, _code})) & ((param1 # NIL) = (param2 # NIL));
573
        res := ((t1.call = t2.call) OR (t1.call IN {code, _code}) OR (t2.call IN {code, _code})) & ((param1 # NIL) = (param2 # NIL));
577
 
574
 
578
        WHILE res & (param1 # NIL) & (param2 # NIL) DO
575
        WHILE res & (param1 # NIL) & (param2 # NIL) DO
579
            res := (param1(PARAM).vPar = param2(PARAM).vPar) & isTypeEq(param1(PARAM).type, param2(PARAM).type);
576
            res := (param1(PARAM).vPar = param2(PARAM).vPar) & isTypeEq(param1(PARAM)._type, param2(PARAM)._type);
580
            param1 := param1.next;
577
            param1 := param1.next;
581
            param2 := param2.next;
578
            param2 := param2.next;
Line 592... Line 589...
592
 
589
 
593
    RETURN res
590
    RETURN res
Line 594... Line 591...
594
END isTypeEq;
591
END isTypeEq;
595
 
592
 
596
 
593
 
Line 597... Line 594...
597
PROCEDURE isBaseOf* (t0, t1: TYPE_): BOOLEAN;
594
PROCEDURE isBaseOf* (t0, t1: _TYPE): BOOLEAN;
598
VAR
595
VAR
Line 615... Line 612...
615
 
612
 
616
    RETURN res
613
    RETURN res
Line 617... Line 614...
617
END isBaseOf;
614
END isBaseOf;
618
 
615
 
619
 
616
 
Line 620... Line 617...
620
PROCEDURE isOpenArray* (t: TYPE_): BOOLEAN;
617
PROCEDURE isOpenArray* (t: _TYPE): BOOLEAN;
621
    RETURN (t.typ = tARRAY) & (t.length = 0)
618
    RETURN (t.typ = tARRAY) & (t.length = 0)
622
END isOpenArray;
619
END isOpenArray;
623
 
620
 
624
 
621
 
Line 625... Line 622...
625
PROCEDURE arrcomp* (src, dst: TYPE_): BOOLEAN;
622
PROCEDURE arrcomp* (src, dst: _TYPE): BOOLEAN;
626
    RETURN (dst.typ = tARRAY) & isOpenArray(src) &
623
    RETURN (dst.typ = tARRAY) & isOpenArray(src) &
627
            ~isOpenArray(src.base) & ~isOpenArray(dst.base) &
624
            ~isOpenArray(src.base) & ~isOpenArray(dst.base) &
Line 628... Line 625...
628
            isTypeEq(src.base, dst.base)
625
            isTypeEq(src.base, dst.base)
629
END arrcomp;
626
END arrcomp;
Line 640... Line 637...
640
 
637
 
641
    WHILE (item # NIL) & (item.name # name) DO
638
    WHILE (item # NIL) & (item.name # name) DO
642
        item := item.next(UNIT)
639
        item := item.next(UNIT)
Line 643... Line 640...
643
    END;
640
    END;
644
 
641
 
645
    IF (item = NIL) & (name.s = "SYSTEM") THEN
642
    IF (item = NIL) & ((name.s = "SYSTEM") OR LowerCase & (name.s = "system")) THEN
Line 646... Line 643...
646
        item := program.sysunit
643
        item := program.sysunit
647
    END
644
    END
Line 648... Line 645...
648
 
645
 
-
 
646
    RETURN item
-
 
647
END getUnit;
-
 
648
 
649
    RETURN item
649
 
650
END getUnit;
650
PROCEDURE enterStTypes (unit: UNIT);
-
 
651
 
Line 651... Line 652...
651
 
652
 
-
 
653
    PROCEDURE enter (unit: UNIT; name: SCAN.LEXSTR; _type: _TYPE);
652
 
654
    VAR
653
PROCEDURE enterStTypes (unit: UNIT; program: PROGRAM);
655
        ident: IDENT;
654
VAR
656
        upper: SCAN.LEXSTR;
655
    ident: IDENT;
657
 
656
 
658
    BEGIN
657
BEGIN
-
 
658
    ident      := addIdent(unit, SCAN.enterid("INTEGER"), idTYPE);
659
        IF LowerCase THEN
659
    ident.type := program.stTypes.tINTEGER;
660
            ident := addIdent(unit, SCAN.enterid(name), idTYPE);
-
 
661
            ident._type := _type
Line 660... Line -...
660
 
-
 
661
    ident      := addIdent(unit, SCAN.enterid("BYTE"), idTYPE);
-
 
Line -... Line 662...
-
 
662
        END;
662
    ident.type := program.stTypes.tBYTE;
663
        upper := name;
-
 
664
        STRINGS.UpCase(upper);
-
 
665
        ident := addIdent(unit, SCAN.enterid(upper), idTYPE);
-
 
666
        ident._type := _type
663
 
667
    END enter;
Line 664... Line 668...
664
    ident      := addIdent(unit, SCAN.enterid("CHAR"), idTYPE);
668
 
665
    ident.type := program.stTypes.tCHAR;
-
 
666
 
669
 
667
    ident      := addIdent(unit, SCAN.enterid("SET"), idTYPE);
670
BEGIN
Line 668... Line 671...
668
    ident.type := program.stTypes.tSET;
671
    enter(unit, "integer", program.stTypes.tINTEGER);
669
 
-
 
670
    ident      := addIdent(unit, SCAN.enterid("BOOLEAN"), idTYPE);
672
    enter(unit, "byte",    program.stTypes.tBYTE);
671
    ident.type := program.stTypes.tBOOLEAN;
673
    enter(unit, "char",    program.stTypes.tCHAR);
672
 
-
 
673
    IF TARGETS.RealSize # 0 THEN
674
    enter(unit, "set",     program.stTypes.tSET);
Line 674... Line 675...
674
        ident      := addIdent(unit, SCAN.enterid("REAL"), idTYPE);
675
    enter(unit, "boolean", program.stTypes.tBOOLEAN);
Line 675... Line 676...
675
        ident.type := program.stTypes.tREAL
676
 
676
    END;
677
    IF TARGETS.RealSize # 0 THEN
677
 
678
        enter(unit, "real", program.stTypes.tREAL)
-
 
679
    END;
-
 
680
 
678
    IF TARGETS.BitDepth >= 32 THEN
681
    IF TARGETS.BitDepth >= 32 THEN
-
 
682
        enter(unit, "wchar", program.stTypes.tWCHAR)
679
        ident      := addIdent(unit, SCAN.enterid("WCHAR"), idTYPE);
683
    END
-
 
684
END enterStTypes;
-
 
685
 
-
 
686
 
-
 
687
PROCEDURE enterStProcs (unit: UNIT);
-
 
688
 
-
 
689
 
680
        ident.type := program.stTypes.tWCHAR
690
    PROCEDURE EnterProc (unit: UNIT; name: SCAN.LEXSTR; proc: INTEGER);
-
 
691
    VAR
681
    END
692
        ident: IDENT;
Line 682... Line 693...
682
 
693
        upper: SCAN.LEXSTR;
683
END enterStTypes;
694
 
684
 
695
    BEGIN
-
 
696
        IF LowerCase THEN
-
 
697
            ident := addIdent(unit, SCAN.enterid(name), idSTPROC);
685
 
698
            ident.stproc := proc;
-
 
699
            ident._type := program.stTypes.tNONE
686
PROCEDURE enterStProcs (unit: UNIT);
700
        END;
-
 
701
        upper := name;
-
 
702
        STRINGS.UpCase(upper);
-
 
703
        ident := addIdent(unit, SCAN.enterid(upper), idSTPROC);
-
 
704
        ident.stproc := proc;
-
 
705
        ident._type := program.stTypes.tNONE
-
 
706
    END EnterProc;
687
 
707
 
-
 
708
 
688
 
709
    PROCEDURE EnterFunc (unit: UNIT; name: SCAN.LEXSTR; func: INTEGER);
Line 689... Line 710...
689
    PROCEDURE EnterProc (unit: UNIT; name: SCAN.LEXSTR; proc: INTEGER);
710
    VAR
690
    VAR
711
        ident: IDENT;
691
        ident: IDENT;
712
        upper: SCAN.LEXSTR;
692
    BEGIN
713
 
693
        ident := addIdent(unit, SCAN.enterid(name), idSTPROC);
714
    BEGIN
694
        ident.stproc := proc
715
        IF LowerCase THEN
695
    END EnterProc;
716
            ident := addIdent(unit, SCAN.enterid(name), idSTFUNC);
696
 
717
            ident.stproc := func;
697
 
718
            ident._type := program.stTypes.tNONE
698
    PROCEDURE EnterFunc (unit: UNIT; name: SCAN.LEXSTR; func: INTEGER);
719
        END;
699
    VAR
720
        upper := name;
700
        ident: IDENT;
721
        STRINGS.UpCase(upper);
701
    BEGIN
722
        ident := addIdent(unit, SCAN.enterid(upper), idSTFUNC);
702
        ident := addIdent(unit, SCAN.enterid(name), idSTFUNC);
723
        ident.stproc := func;
703
        ident.stproc := func
724
        ident._type := program.stTypes.tNONE
704
    END EnterFunc;
725
    END EnterFunc;
705
 
726
 
706
 
727
 
707
BEGIN
728
BEGIN
708
    EnterProc(unit, "ASSERT", stASSERT);
729
    EnterProc(unit, "assert", stASSERT);
709
    EnterProc(unit, "DEC",    stDEC);
730
    EnterProc(unit, "dec",    stDEC);
710
    EnterProc(unit, "EXCL",   stEXCL);
731
    EnterProc(unit, "excl",   stEXCL);
Line 711... Line 732...
711
    EnterProc(unit, "INC",    stINC);
732
    EnterProc(unit, "inc",    stINC);
712
    EnterProc(unit, "INCL",   stINCL);
733
    EnterProc(unit, "incl",   stINCL);
713
    EnterProc(unit, "NEW",    stNEW);
734
    EnterProc(unit, "new",    stNEW);
714
    EnterProc(unit, "COPY",   stCOPY);
735
    EnterProc(unit, "copy",   stCOPY);
715
 
736
 
716
    EnterFunc(unit, "ABS",    stABS);
737
    EnterFunc(unit, "abs",    stABS);
Line 717... Line 738...
717
    EnterFunc(unit, "ASR",    stASR);
738
    EnterFunc(unit, "asr",    stASR);
718
    EnterFunc(unit, "CHR",    stCHR);
739
    EnterFunc(unit, "chr",    stCHR);
719
    EnterFunc(unit, "LEN",    stLEN);
740
    EnterFunc(unit, "len",    stLEN);
Line 720... Line 741...
720
    EnterFunc(unit, "LSL",    stLSL);
741
    EnterFunc(unit, "lsl",    stLSL);
721
    EnterFunc(unit, "ODD",    stODD);
742
    EnterFunc(unit, "odd",    stODD);
722
    EnterFunc(unit, "ORD",    stORD);
743
    EnterFunc(unit, "ord",    stORD);
Line 723... Line 744...
723
    EnterFunc(unit, "ROR",    stROR);
744
    EnterFunc(unit, "ror",    stROR);
Line 724... Line 745...
724
    EnterFunc(unit, "BITS",   stBITS);
745
    EnterFunc(unit, "bits",   stBITS);
725
    EnterFunc(unit, "LSR",    stLSR);
746
    EnterFunc(unit, "lsr",    stLSR);
726
    EnterFunc(unit, "LENGTH", stLENGTH);
747
    EnterFunc(unit, "length", stLENGTH);
Line 727... Line 748...
727
    EnterFunc(unit, "MIN",    stMIN);
748
    EnterFunc(unit, "min",    stMIN);
728
    EnterFunc(unit, "MAX",    stMAX);
-
 
729
 
749
    EnterFunc(unit, "max",    stMAX);
Line 730... Line 750...
730
    IF TARGETS.RealSize # 0 THEN
750
 
Line 731... Line -...
731
        EnterProc(unit, "PACK",  stPACK);
-
 
732
        EnterProc(unit, "UNPK",  stUNPK);
751
    IF TARGETS.RealSize # 0 THEN
733
        EnterFunc(unit, "FLOOR", stFLOOR);
752
        EnterProc(unit, "pack",  stPACK);
734
        EnterFunc(unit, "FLT",   stFLT)
753
        EnterProc(unit, "unpk",  stUNPK);
735
    END;
754
        EnterFunc(unit, "floor", stFLOOR);
Line 736... Line 755...
736
 
755
        EnterFunc(unit, "flt",   stFLT)
Line 737... Line 756...
737
    IF TARGETS.BitDepth >= 32 THEN
756
    END;
738
        EnterFunc(unit, "WCHR", stWCHR)
757
 
Line 739... Line 758...
739
    END;
758
    IF TARGETS.BitDepth >= 32 THEN
Line 740... Line 759...
740
 
759
        EnterFunc(unit, "wchr", stWCHR)
Line 783... Line 802...
783
 
802
 
784
    RETURN unit
803
    RETURN unit
Line 785... Line 804...
785
END newUnit;
804
END newUnit;
786
 
805
 
787
 
806
 
Line 788... Line 807...
788
PROCEDURE getField* (self: TYPE_; name: SCAN.IDENT; unit: UNIT): FIELD;
807
PROCEDURE getField* (self: _TYPE; name: SCAN.IDENT; unit: UNIT): FIELD;
789
VAR
808
VAR
Line 815... Line 834...
815
 
834
 
816
    RETURN field
835
    RETURN field
Line 817... Line 836...
817
END getField;
836
END getField;
818
 
837
 
819
 
838
 
820
PROCEDURE addField* (self: TYPE_; name: SCAN.IDENT; export: BOOLEAN): BOOLEAN;
839
PROCEDURE addField* (self: _TYPE; name: SCAN.IDENT; export: BOOLEAN): BOOLEAN;
Line 821... Line 840...
821
VAR
840
VAR
Line 830... Line 849...
830
    IF res THEN
849
    IF res THEN
831
        NEW(field);
850
        NEW(field);
Line 832... Line 851...
832
 
851
 
833
        field.name   := name;
852
        field.name   := name;
834
        field.export := export;
853
        field.export := export;
835
        field.type   := NIL;
854
        field._type  := NIL;
Line 836... Line 855...
836
        field.offset := self.size;
855
        field.offset := self.size;
837
 
856
 
Line 838... Line 857...
838
        LISTS.push(self.fields, field)
857
        LISTS.push(self.fields, field)
839
    END
858
    END
Line 840... Line 859...
840
 
859
 
841
    RETURN res
860
    RETURN res
842
END addField;
861
END addField;
843
 
862
 
Line 844... Line 863...
844
 
863
 
845
PROCEDURE setFields* (self: TYPE_; type: TYPE_): BOOLEAN;
864
PROCEDURE setFields* (self: _TYPE; _type: _TYPE): BOOLEAN;
Line 846... Line 865...
846
VAR
865
VAR
Line 847... Line 866...
847
    item: FIELD;
866
    item: FIELD;
848
    res:  BOOLEAN;
867
    res:  BOOLEAN;
849
 
868
 
Line 850... Line 869...
850
BEGIN
869
BEGIN
Line 851... Line 870...
851
    ASSERT(type # NIL);
870
    ASSERT(_type # NIL);
852
 
871
 
853
    item := self.fields.first(FIELD);
872
    item := self.fields.first(FIELD);
854
 
873
 
855
    WHILE (item # NIL) & (item.type # NIL) DO
874
    WHILE (item # NIL) & (item._type # NIL) DO
856
        item := item.next(FIELD)
875
        item := item.next(FIELD)
857
    END;
876
    END;
858
 
877
 
859
    res := TRUE;
878
    res := TRUE;
860
 
879
 
861
    WHILE res & (item # NIL) & (item.type = NIL) DO
880
    WHILE res & (item # NIL) & (item._type = NIL) DO
862
        item.type := type;
881
        item._type := _type;
863
        IF ~self.noalign THEN
882
        IF ~self.noalign THEN
864
            res := UTILS.Align(self.size, type.align)
883
            res := UTILS.Align(self.size, _type.align)
Line 865... Line 884...
865
        ELSE
884
        ELSE
866
            res := TRUE
885
            res := TRUE
Line 867... Line 886...
867
        END;
886
        END;
868
        item.offset := self.size;
887
        item.offset := self.size;
869
        res := res & (UTILS.maxint - self.size >= type.size);
888
        res := res & (UTILS.maxint - self.size >= _type.size);
Line 870... Line 889...
870
        IF res THEN
889
        IF res THEN
871
            INC(self.size, type.size)
890
            INC(self.size, _type.size)
Line 892... Line 911...
892
 
911
 
893
    RETURN item
912
    RETURN item
Line 894... Line 913...
894
END getParam;
913
END getParam;
895
 
914
 
896
 
915
 
897
PROCEDURE addParam* (self: TYPE_; name: SCAN.IDENT; vPar: BOOLEAN): BOOLEAN;
916
PROCEDURE addParam* (self: _TYPE; name: SCAN.IDENT; vPar: BOOLEAN): BOOLEAN;
Line 898... Line 917...
898
VAR
917
VAR
Line 906... Line 925...
906
 
925
 
907
    IF res THEN
926
    IF res THEN
Line 908... Line 927...
908
        NEW(param);
927
        NEW(param);
909
 
928
 
910
        param.name := name;
929
        param.name  := name;
Line 911... Line 930...
911
        param.type := NIL;
930
        param._type := NIL;
912
        param.vPar := vPar;
931
        param.vPar  := vPar;
Line 913... Line 932...
913
 
932
 
914
        LISTS.push(self.params, param)
933
        LISTS.push(self.params, param)
Line 915... Line 934...
915
    END
934
    END
916
 
935
 
917
    RETURN res
936
    RETURN res
Line 918... Line 937...
918
END addParam;
937
END addParam;
919
 
938
 
Line 930... Line 949...
930
    END
949
    END
931
    RETURN res
950
    RETURN res
932
END Dim;
951
END Dim;
Line 933... Line 952...
933
 
952
 
934
 
953
 
935
PROCEDURE OpenBase* (t: TYPE_): TYPE_;
954
PROCEDURE OpenBase* (t: _TYPE): _TYPE;
936
BEGIN
955
BEGIN
937
    WHILE isOpenArray(t) DO t := t.base END
956
    WHILE isOpenArray(t) DO t := t.base END
Line 938... Line 957...
938
    RETURN t
957
    RETURN t
939
END OpenBase;
958
END OpenBase;
940
 
959
 
941
 
960
 
Line 942... Line 961...
942
PROCEDURE getFloatParamsPos* (self: TYPE_; maxoffs: INTEGER; VAR int, flt: INTEGER): SET;
961
PROCEDURE getFloatParamsPos* (self: _TYPE; maxoffs: INTEGER; VAR int, flt: INTEGER): SET;
943
VAR
962
VAR
944
    res: SET;
963
    res: SET;
945
    param: PARAM;
964
    param: PARAM;
946
 
965
 
947
BEGIN
966
BEGIN
948
    res := {};
967
    res := {};
949
    int := 0;
968
    int := 0;
950
    flt := 0;
969
    flt := 0;
951
    param := self.params.first(PARAM);
970
    param := self.params.first(PARAM);
952
    WHILE (param # NIL) & (param.offset <= maxoffs + STACK_FRAME) DO
971
    WHILE (param # NIL) & (param.offset <= maxoffs + STACK_FRAME) DO
953
        IF ~param.vPar & (param.type.typ = tREAL) THEN
972
        IF ~param.vPar & (param._type.typ = tREAL) THEN
Line 961... Line 980...
961
 
980
 
962
    RETURN res
981
    RETURN res
Line 963... Line 982...
963
END getFloatParamsPos;
982
END getFloatParamsPos;
964
 
983
 
965
 
984
 
966
PROCEDURE setParams* (self: TYPE_; type: TYPE_);
985
PROCEDURE setParams* (self: _TYPE; _type: _TYPE);
967
VAR
986
VAR
Line 968... Line 987...
968
    item: LISTS.ITEM;
987
    item: LISTS.ITEM;
969
    param: PARAM;
988
    param: PARAM;
Line 970... Line 989...
970
    word, size: INTEGER;
989
    word, size: INTEGER;
Line 971... Line 990...
971
 
990
 
Line 972... Line 991...
972
BEGIN
991
BEGIN
973
    ASSERT(type # NIL);
992
    ASSERT(_type # NIL);
974
 
993
 
Line 975... Line 994...
975
    word := UTILS.target.bit_depth DIV 8;
994
    word := UTILS.target.bit_depth DIV 8;
976
 
995
 
977
    item := self.params.first;
996
    item := self.params.first;
978
 
997
 
979
    WHILE (item # NIL) & (item(PARAM).type # NIL) DO
998
    WHILE (item # NIL) & (item(PARAM)._type # NIL) DO
980
        item := item.next
999
        item := item.next
981
    END;
1000
    END;
982
 
1001
 
983
    WHILE (item # NIL) & (item(PARAM).type = NIL) DO
1002
    WHILE (item # NIL) & (item(PARAM)._type = NIL) DO
984
        param := item(PARAM);
1003
        param := item(PARAM);
985
        param.type := type;
1004
        param._type := _type;
986
        IF param.vPar THEN
1005
        IF param.vPar THEN
987
            IF type.typ = tRECORD THEN
1006
            IF _type.typ = tRECORD THEN
988
                size := 2
1007
                size := 2
989
            ELSIF isOpenArray(type) THEN
1008
            ELSIF isOpenArray(_type) THEN
990
                size := Dim(type) + 1
1009
                size := Dim(_type) + 1
991
            ELSE
1010
            ELSE
992
                size := 1
1011
                size := 1
993
            END;
1012
            END;
994
            param.offset := self.parSize + ORD(type.typ = tRECORD) + Dim(type) + STACK_FRAME;
1013
            param.offset := self.parSize + ORD(_type.typ = tRECORD) + Dim(_type) + STACK_FRAME;
995
            INC(self.parSize, size)
1014
            INC(self.parSize, size)
996
        ELSE
1015
        ELSE
997
            IF type.typ IN {tRECORD, tARRAY} THEN
1016
            IF _type.typ IN {tRECORD, tARRAY} THEN
998
                IF isOpenArray(type) THEN
1017
                IF isOpenArray(_type) THEN
999
                    size := Dim(type) + 1
1018
                    size := Dim(_type) + 1
1000
                ELSE
1019
                ELSE
1001
                    size := 1
1020
                    size := 1
1002
                END
1021
                END
Line 1003... Line 1022...
1003
            ELSE
1022
            ELSE
1004
                size := type.size;
1023
                size := _type.size;
Line 1005... Line 1024...
1005
                ASSERT(UTILS.Align(size, word));
1024
                ASSERT(UTILS.Align(size, word));
Line 1006... Line 1025...
1006
                size := size DIV word
1025
                size := size DIV word
1007
            END;
1026
            END;
1008
            param.offset := self.parSize + Dim(type) + STACK_FRAME;
1027
            param.offset := self.parSize + Dim(_type) + STACK_FRAME;
Line 1009... Line 1028...
1009
            INC(self.parSize, size)
1028
            INC(self.parSize, size)
1010
        END;
1029
        END;
Line 1011... Line 1030...
1011
 
1030
 
Line 1036... Line 1055...
1036
    |16: t.call := default16
1055
    |16: t.call := default16
1037
    |32: t.call := default32
1056
    |32: t.call := default32
1038
    |64: t.call := default64
1057
    |64: t.call := default64
1039
    END;
1058
    END;
Line 1040... Line 1059...
1040
 
1059
 
1041
    t.import  := FALSE;
1060
    t._import := FALSE;
1042
    t.noalign := FALSE;
1061
    t.noalign := FALSE;
Line 1043... Line 1062...
1043
    t.parSize := 0;
1062
    t.parSize := 0;
1044
 
1063
 
Line 1056... Line 1075...
1056
 
1075
 
1057
    RETURN t
1076
    RETURN t
Line 1058... Line 1077...
1058
END enterType;
1077
END enterType;
1059
 
1078
 
1060
 
1079
 
Line 1061... Line 1080...
1061
PROCEDURE getType* (program: PROGRAM; typ: INTEGER): TYPE_;
1080
PROCEDURE getType* (typ: INTEGER): _TYPE;
Line 1062... Line 1081...
1062
VAR
1081
VAR
1063
    res: TYPE_;
1082
    res: _TYPE;
Line 1076... Line 1095...
1076
 
1095
 
1077
    RETURN res
1096
    RETURN res
Line 1078... Line 1097...
1078
END getType;
1097
END getType;
1079
 
1098
 
1080
 
1099
 
1081
PROCEDURE createSysUnit (program: PROGRAM);
1100
PROCEDURE createSysUnit;
Line 1082... Line 1101...
1082
VAR
1101
VAR
1083
    ident: IDENT;
1102
    ident: IDENT;
1084
    unit:  UNIT;
1103
    unit:  UNIT;
-
 
1104
 
-
 
1105
 
1085
 
1106
    PROCEDURE EnterProc (sys: UNIT; name: SCAN.LEXSTR; idtyp, proc: INTEGER);
-
 
1107
    VAR
1086
 
1108
        ident: IDENT;
1087
    PROCEDURE EnterProc (sys: UNIT; name: SCAN.LEXSTR; idtyp, proc: INTEGER);
1109
        upper: SCAN.LEXSTR;
-
 
1110
 
-
 
1111
    BEGIN
-
 
1112
        IF LowerCase THEN
-
 
1113
            ident := addIdent(sys, SCAN.enterid(name), idtyp);
-
 
1114
            ident.stproc := proc;
-
 
1115
            ident._type := program.stTypes.tNONE;
-
 
1116
            ident.export := TRUE
-
 
1117
        END;
1088
    VAR
1118
        upper := name;
1089
        ident: IDENT;
1119
        STRINGS.UpCase(upper);
Line 1090... Line 1120...
1090
    BEGIN
1120
        ident := addIdent(sys, SCAN.enterid(upper), idtyp);
1091
        ident := addIdent(sys, SCAN.enterid(name), idtyp);
1121
        ident.stproc := proc;
Line 1092... Line 1122...
1092
        ident.stproc := proc;
1122
        ident._type := program.stTypes.tNONE;
1093
        ident.export := TRUE
1123
        ident.export := TRUE
1094
    END EnterProc;
1124
    END EnterProc;
1095
 
1125
 
1096
 
1126
 
1097
BEGIN
1127
BEGIN
1098
    unit := newUnit(program, SCAN.enterid("$SYSTEM"));
1128
    unit := newUnit(SCAN.enterid("$SYSTEM"));
1099
 
1129
 
-
 
1130
    EnterProc(unit, "adr",    idSYSFUNC, sysADR);
1100
    EnterProc(unit, "ADR",    idSYSFUNC, sysADR);
1131
    EnterProc(unit, "size",   idSYSFUNC, sysSIZE);
1101
    EnterProc(unit, "SIZE",   idSYSFUNC, sysSIZE);
1132
    EnterProc(unit, "sadr",   idSYSFUNC, sysSADR);
1102
    EnterProc(unit, "SADR",   idSYSFUNC, sysSADR);
1133
    EnterProc(unit, "typeid", idSYSFUNC, sysTYPEID);
1103
    EnterProc(unit, "TYPEID", idSYSFUNC, sysTYPEID);
1134
 
1104
 
1135
    EnterProc(unit, "get",    idSYSPROC, sysGET);
1105
    EnterProc(unit, "GET",    idSYSPROC, sysGET);
1136
    EnterProc(unit, "get8",   idSYSPROC, sysGET8);
1106
    EnterProc(unit, "PUT8",   idSYSPROC, sysPUT8);
1137
    EnterProc(unit, "put",    idSYSPROC, sysPUT);
1107
    EnterProc(unit, "PUT",    idSYSPROC, sysPUT);
1138
    EnterProc(unit, "put8",   idSYSPROC, sysPUT8);
1108
    EnterProc(unit, "CODE",   idSYSPROC, sysCODE);
1139
    EnterProc(unit, "code",   idSYSPROC, sysCODE);
1109
    EnterProc(unit, "MOVE",   idSYSPROC, sysMOVE);
1140
    EnterProc(unit, "move",   idSYSPROC, sysMOVE);
1110
           (*
1141
           (*
1111
    IF program.target.sys = mConst.Target_iMSP430 THEN
1142
    IF program.target.sys = mConst.Target_iMSP430 THEN
Line 1112... Line 1143...
1112
        EnterProc(unit, "NOP",  idSYSPROC, sysNOP);
1143
        EnterProc(unit, "nop",  idSYSPROC, sysNOP);
1113
        EnterProc(unit, "EINT", idSYSPROC, sysEINT);
1144
        EnterProc(unit, "eint", idSYSPROC, sysEINT);
1114
        EnterProc(unit, "DINT", idSYSPROC, sysDINT)
1145
        EnterProc(unit, "dint", idSYSPROC, sysDINT)
Line 1115... Line 1146...
1115
    END;
1146
    END;
1116
         *)
1147
         *)
-
 
1148
    IF TARGETS.RealSize # 0 THEN
1117
    IF TARGETS.RealSize # 0 THEN
1149
        EnterProc(unit, "inf",    idSYSFUNC, sysINF);
1118
        EnterProc(unit, "INF",    idSYSFUNC, sysINF);
1150
    END;
-
 
1151
 
1119
    END;
1152
    IF TARGETS.CPU IN {TARGETS.cpuX86, TARGETS.cpuAMD64} THEN
-
 
1153
        EnterProc(unit, "copy",   idSYSPROC, sysCOPY)
1120
 
1154
    END;
1121
    IF TARGETS.CPU IN {TARGETS.cpuX86, TARGETS.cpuAMD64} THEN
1155
 
1122
        EnterProc(unit, "COPY",   idSYSPROC, sysCOPY)
1156
    IF TARGETS.BitDepth >= 32 THEN
1123
    END;
1157
        EnterProc(unit, "wsadr",  idSYSFUNC, sysWSADR);
-
 
1158
        EnterProc(unit, "put16",  idSYSPROC, sysPUT16);
-
 
1159
        EnterProc(unit, "put32",  idSYSPROC, sysPUT32);
-
 
1160
        EnterProc(unit, "get16",  idSYSPROC, sysGET16);
-
 
1161
        EnterProc(unit, "get32",  idSYSPROC, sysGET32);
Line 1124... Line 1162...
1124
 
1162
 
Line 1125... Line 1163...
1125
    IF TARGETS.BitDepth >= 32 THEN
1163
        IF LowerCase THEN
1126
        EnterProc(unit, "WSADR",  idSYSFUNC, sysWSADR);
1164
            ident := addIdent(unit, SCAN.enterid("card32"), idTYPE);
Line 1127... Line 1165...
1127
        EnterProc(unit, "PUT32",  idSYSPROC, sysPUT32);
1165
            ident._type := program.stTypes.tCARD32;
1128
        EnterProc(unit, "PUT16",  idSYSPROC, sysPUT16);
1166
            ident.export := TRUE
1129
 
1167
        END;
1130
        ident := addIdent(unit, SCAN.enterid("CARD32"), idTYPE);
1168
        ident := addIdent(unit, SCAN.enterid("CARD32"), idTYPE);
Line 1178... Line 1216...
1178
 
1216
 
Line 1179... Line 1217...
1179
    proc := program.procs.first(PROC);
1217
    proc := program.procs.first(PROC);
1180
 
1218
 
1181
    WHILE proc # NIL DO
1219
    WHILE proc # NIL DO
1182
        IF ~proc.used THEN
1220
        IF ~proc.used THEN
1183
            IF proc.import = NIL THEN
1221
            IF proc._import = NIL THEN
1184
                IL.delete2(proc.enter, proc.leave)
1222
                IL.delete2(proc.enter, proc.leave)
1185
            ELSE
1223
            ELSE
1186
                DelImport(proc.import)
1224
                DelImport(proc._import)
1187
            END
1225
            END
1188
        END;
1226
        END;
Line 1189... Line 1227...
1189
        proc := proc.next(PROC)
1227
        proc := proc.next(PROC)
Line 1190... Line 1228...
1190
    END
1228
    END
1191
 
1229
 
1192
END DelUnused;
1230
END DelUnused;
-
 
1231
 
Line -... Line 1232...
-
 
1232
 
-
 
1233
PROCEDURE ResetLocSize*;
1193
 
1234
BEGIN
-
 
1235
    program.locsize := 0
-
 
1236
END ResetLocSize;
1194
 
1237
 
Line 1195... Line 1238...
1195
PROCEDURE create* (options: OPTIONS): PROGRAM;
1238
 
1196
VAR
-
 
Line 1197... Line 1239...
1197
    program: PROGRAM;
1239
PROCEDURE create* (options: OPTIONS);
Line 1198... Line 1240...
1198
 
1240
BEGIN
1199
BEGIN
1241
    LowerCase := options.lower;
1200
    idents := C.create();
1242
    SCAN.init(options.lower);
1201
 
1243
    idents := C.create();
1202
    UTILS.SetBitDepth(TARGETS.BitDepth, TARGETS.RealSize = 8);
1244
 
1203
    NEW(program);
1245
    UTILS.SetBitDepth(TARGETS.BitDepth, TARGETS.RealSize = 8);
1204
 
1246
 
1205
    program.options := options;
1247
    program.options := options;
Line 1206... Line 1248...
1206
 
1248
 
1207
    CASE TARGETS.OS OF
1249
    CASE TARGETS.OS OF
Line 1208... Line 1250...
1208
    |TARGETS.osWIN32:    program.sysflags := {sf_windows, sf_stdcall, sf_ccall, sf_ccall16, sf_noalign}
1250
    |TARGETS.osWIN32:    program.sysflags := {sf_oberon, sf_windows, sf_stdcall, sf_ccall, sf_ccall16, sf_noalign}
1209
    |TARGETS.osLINUX32:  program.sysflags := {sf_linux, sf_stdcall, sf_ccall, sf_ccall16, sf_noalign}
1251
    |TARGETS.osLINUX32:  program.sysflags := {sf_oberon, sf_linux, sf_stdcall, sf_ccall, sf_ccall16, sf_noalign}
1210
    |TARGETS.osKOS:      program.sysflags := {sf_stdcall, sf_ccall, sf_ccall16, sf_noalign}
1252
    |TARGETS.osKOS:      program.sysflags := {sf_oberon, sf_stdcall, sf_ccall, sf_ccall16, sf_noalign}
Line 1211... Line 1253...
1211
    |TARGETS.osWIN64:    program.sysflags := {sf_windows, sf_stdcall64, sf_win64, sf_systemv, sf_noalign}
1253
    |TARGETS.osWIN64:    program.sysflags := {sf_oberon, sf_windows, sf_stdcall64, sf_win64, sf_systemv, sf_noalign}
1212
    |TARGETS.osLINUX64:  program.sysflags := {sf_linux, sf_stdcall64, sf_win64, sf_systemv, sf_noalign}
1254
    |TARGETS.osLINUX64:  program.sysflags := {sf_oberon, sf_linux, sf_stdcall64, sf_win64, sf_systemv, sf_noalign}
1213
    |TARGETS.osNONE:     program.sysflags := {sf_code}
1255
    |TARGETS.osNONE:     program.sysflags := {sf_code}
1214
    END;
1256
    END;
1215
 
1257
 
Line 1216... Line 1258...
1216
    program.recCount := -1;
1258
    program.recCount := -1;
1217
    program.bss := 0;
1259
    program.bss := 0;
1218
 
1260
 
1219
    program.units := LISTS.create(NIL);
1261
    program.units := LISTS.create(NIL);
1220
    program.types := LISTS.create(NIL);
1262
    program.types := LISTS.create(NIL);
Line 1221... Line 1263...
1221
    program.procs := LISTS.create(NIL);
1263
    program.procs := LISTS.create(NIL);
1222
 
1264
 
1223
    program.stTypes.tINTEGER := enterType(program, tINTEGER, TARGETS.WordSize, 0, NIL);
1265
    program.stTypes.tINTEGER := enterType(tINTEGER, TARGETS.WordSize, 0, NIL);
1224
    program.stTypes.tBYTE    := enterType(program, tBYTE,                   1, 0, NIL);
1266
    program.stTypes.tBYTE    := enterType(tBYTE,                   1, 0, NIL);
1225
    program.stTypes.tCHAR    := enterType(program, tCHAR,                   1, 0, NIL);
1267
    program.stTypes.tCHAR    := enterType(tCHAR,                   1, 0, NIL);
1226
    program.stTypes.tSET     := enterType(program, tSET,     TARGETS.WordSize, 0, NIL);
1268
    program.stTypes.tSET     := enterType(tSET,     TARGETS.WordSize, 0, NIL);
Line 1227... Line 1269...
1227
    program.stTypes.tBOOLEAN := enterType(program, tBOOLEAN,                1, 0, NIL);
1269
    program.stTypes.tBOOLEAN := enterType(tBOOLEAN,                1, 0, NIL);
1228
 
1270
 
1229
    program.stTypes.tINTEGER.align := TARGETS.WordSize;
1271
    program.stTypes.tINTEGER.align := TARGETS.WordSize;
1230
    program.stTypes.tBYTE.align    := 1;
1272
    program.stTypes.tBYTE.align    := 1;
Line 1231... Line 1273...
1231
    program.stTypes.tCHAR.align    := 1;
1273
    program.stTypes.tCHAR.align    := 1;
1232
    program.stTypes.tSET.align     := TARGETS.WordSize;
1274
    program.stTypes.tSET.align     := TARGETS.WordSize;
1233
    program.stTypes.tBOOLEAN.align := 1;
-
 
-
 
1275
    program.stTypes.tBOOLEAN.align := 1;
1234
 
1276
 
1235
    IF TARGETS.BitDepth >= 32 THEN
1277
    IF TARGETS.BitDepth >= 32 THEN
Line 1236... Line 1278...
1236
        program.stTypes.tWCHAR  := enterType(program, tWCHAR,  2, 0, NIL);
1278
        program.stTypes.tWCHAR  := enterType(tWCHAR,  2, 0, NIL);
1237
        program.stTypes.tCARD32 := enterType(program, tCARD32, 4, 0, NIL);
-
 
1238
        program.stTypes.tWCHAR.align  := 2;
-
 
1239
        program.stTypes.tCARD32.align := 4
1279
        program.stTypes.tCARD32 := enterType(tCARD32, 4, 0, NIL);
Line 1240... Line 1280...
1240
    END;
1280
        program.stTypes.tWCHAR.align  := 2;
1241
 
1281
        program.stTypes.tCARD32.align := 4