Subversion Repositories Kolibri OS

Rev

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

Rev 7597 Rev 7693
Line 5... Line 5...
5
    All rights reserved.
5
    All rights reserved.
6
*)
6
*)
Line 7... Line 7...
7
 
7
 
Line 8... Line 8...
8
MODULE PARS;
8
MODULE PARS;
Line 9... Line 9...
9
 
9
 
Line 10... Line 10...
10
IMPORT PROG, SCAN, ARITH, STRINGS, ERRORS, LISTS, CODE, CONSOLE, PATHS, MACHINE, C := COLLECTIONS, mConst := CONSTANTS;
10
IMPORT PROG, SCAN, ARITH, STRINGS, ERRORS, LISTS, IL, CONSOLE, PATHS, UTILS, C := COLLECTIONS, mConst := CONSTANTS;
Line 22... Line 22...
22
 
22
 
Line 23... Line 23...
23
    PATH* = PATHS.PATH;
23
    PATH* = PATHS.PATH;
Line -... Line 24...
-
 
24
 
-
 
25
    PARSER* = POINTER TO rPARSER;
-
 
26
 
-
 
27
    POSITION* = RECORD (SCAN.POSITION)
-
 
28
 
-
 
29
        parser*: PARSER
24
 
30
 
Line 25... Line 31...
25
    PARSER* = POINTER TO rPARSER;
31
    END;
26
 
32
 
27
    EXPR* = RECORD
33
    EXPR* = RECORD
Line 35... Line 41...
35
 
41
 
Line 36... Line 42...
36
    END;
42
    END;
37
 
43
 
38
    STATPROC  = PROCEDURE (parser: PARSER);
44
    STATPROC  = PROCEDURE (parser: PARSER);
Line 39... Line 45...
39
    EXPRPROC  = PROCEDURE (parser: PARSER; VAR e: EXPR);
45
    EXPRPROC  = PROCEDURE (parser: PARSER; VAR e: EXPR);
Line 40... Line 46...
40
    RETPROC   = PROCEDURE (parser: PARSER; e: EXPR; t: PROG.TYPE_; pos: SCAN.POSITION): BOOLEAN;
46
    RETPROC   = PROCEDURE (parser: PARSER; e: EXPR; t: PROG.TYPE_; pos: POSITION): BOOLEAN;
41
 
47
 
Line 81... Line 87...
81
    C.push(parsers, parser);
87
    C.push(parsers, parser);
82
    parser := NIL
88
    parser := NIL
83
END destroy;
89
END destroy;
Line -... Line 90...
-
 
90
 
-
 
91
 
-
 
92
PROCEDURE getpos (parser: PARSER; VAR pos: POSITION);
-
 
93
BEGIN
-
 
94
    pos.line   := parser.lex.pos.line;
-
 
95
    pos.col    := parser.lex.pos.col;
-
 
96
    pos.parser := parser
-
 
97
END getpos;
84
 
98
 
85
 
99
 
86
PROCEDURE error* (parser: PARSER; pos: SCAN.POSITION; errno: INTEGER);
100
PROCEDURE error* (pos: POSITION; errno: INTEGER);
87
BEGIN
101
BEGIN
Line 88... Line 102...
88
    ERRORS.errormsg(parser.fname, pos.line, pos.col, errno)
102
    ERRORS.ErrorMsg(pos.parser.fname, pos.line, pos.col, errno)
89
END error;
103
END error;
90
 
104
 
91
 
105
 
92
PROCEDURE check* (condition: BOOLEAN; parser: PARSER; pos: SCAN.POSITION; errno: INTEGER);
106
PROCEDURE check* (condition: BOOLEAN; pos: POSITION; errno: INTEGER);
93
BEGIN
107
BEGIN
Line 94... Line 108...
94
    IF ~condition THEN
108
    IF ~condition THEN
-
 
109
        error(pos, errno)
-
 
110
    END
-
 
111
END check;
95
        error(parser, pos, errno)
112
 
96
    END
113
 
-
 
114
PROCEDURE check1* (condition: BOOLEAN; parser: PARSER; errno: INTEGER);
97
END check;
115
VAR
98
 
116
    pos: POSITION;
99
 
117
 
Line 100... Line -...
100
PROCEDURE check1* (condition: BOOLEAN; parser: PARSER; errno: INTEGER);
-
 
101
BEGIN
-
 
102
    IF ~condition THEN
-
 
103
        error(parser, parser.lex.pos, errno)
-
 
104
    END
-
 
105
END check1;
-
 
106
 
118
BEGIN
107
 
119
    IF ~condition THEN
108
PROCEDURE getpos (parser: PARSER; VAR pos: SCAN.POSITION);
120
        getpos(parser, pos);
Line 109... Line 121...
109
BEGIN
121
        error(pos, errno)
110
    pos := parser.lex.pos
122
    END
111
END getpos;
123
END check1;
-
 
124
 
-
 
125
 
-
 
126
PROCEDURE Next* (parser: PARSER);
-
 
127
VAR
-
 
128
    errno: INTEGER;
-
 
129
 
-
 
130
BEGIN
-
 
131
    SCAN.Next(parser.scanner, parser.lex);
112
 
132
    errno := parser.lex.error;
113
 
133
    IF (errno = 0) & (program.target.sys = mConst.Target_iMSP430) THEN
114
PROCEDURE Next* (parser: PARSER);
134
        IF parser.lex.sym = SCAN.lxFLOAT THEN
115
VAR
135
            errno := -SCAN.lxERROR13
116
    errno: INTEGER;
136
        ELSIF (parser.lex.sym = SCAN.lxCHAR) & (parser.lex.value.typ = ARITH.tWCHAR) THEN
Line 117... Line 137...
117
 
137
            errno := -SCAN.lxERROR10
118
BEGIN
138
        END
119
    SCAN.Next(parser.scanner, parser.lex);
139
    END;
120
    errno := parser.lex.error;
140
 
121
    IF errno # 0 THEN
141
    IF errno # 0 THEN
Line 122... Line 142...
122
        check1(FALSE, parser, errno)
142
        check1(FALSE, parser, errno)
123
    END;
143
    END;
Line 178... Line 198...
178
 
198
 
179
PROCEDURE ImportList (parser: PARSER);
199
PROCEDURE ImportList (parser: PARSER);
180
VAR
200
VAR
181
    name:       SCAN.IDENT;
201
    name:    SCAN.IDENT;
182
    parser2:    PARSER;
202
    parser2: PARSER;
183
    pos:        SCAN.POSITION;
203
    pos:     POSITION;
184
    alias:      BOOLEAN;
204
    alias:   BOOLEAN;
185
    unit:       PROG.UNIT;
205
    unit:    PROG.UNIT;
186
    ident:      PROG.IDENT;
-
 
Line 187... Line 206...
187
    units:      PROG.UNITS;
206
    ident:   PROG.IDENT;
188
 
-
 
189
BEGIN
-
 
190
    units := program.units;
207
 
Line 191... Line 208...
191
 
208
BEGIN
Line 192... Line 209...
192
    alias := FALSE;
209
    alias := FALSE;
193
 
210
 
Line 194... Line 211...
194
    REPEAT
211
    REPEAT
Line 195... Line 212...
195
 
212
 
196
        ExpectSym(parser, SCAN.lxIDENT);
213
        ExpectSym(parser, SCAN.lxIDENT);
197
        name := parser.lex.ident;
214
        name := parser.lex.ident;
198
 
215
 
Line 199... Line 216...
199
        getpos(parser, pos);
216
        getpos(parser, pos);
Line 200... Line 217...
200
 
217
 
201
        IF ~alias THEN
218
        IF ~alias THEN
202
            ident := parser.unit.idents.add(parser.unit, name, PROG.idMODULE);
219
            ident := PROG.addIdent(parser.unit, name, PROG.idMODULE);
Line 203... Line 220...
203
            check(ident # NIL, parser, pos, 30)
220
            check(ident # NIL, pos, 30)
204
        END;
221
        END;
205
 
222
 
206
        Next(parser);
223
        Next(parser);
207
 
224
 
Line 208... Line 225...
208
        IF (parser.sym = SCAN.lxCOMMA) OR (parser.sym = SCAN.lxSEMI) THEN
225
        IF (parser.sym = SCAN.lxCOMMA) OR (parser.sym = SCAN.lxSEMI) THEN
209
            alias := FALSE;
226
            alias := FALSE;
210
            unit := units.get(units, name);
227
            unit := PROG.getUnit(program, name);
211
 
228
 
212
            IF unit # NIL THEN
229
            IF unit # NIL THEN
213
                check(unit.closed, parser, pos, 31)
230
                check(unit.closed, pos, 31)
214
            ELSE
231
            ELSE
215
                parser2 := parser.create(parser.path, parser.lib_path,
232
                parser2 := parser.create(parser.path, parser.lib_path,
216
                    parser.StatSeq, parser.expression, parser.designator, parser.chkreturn);
233
                    parser.StatSeq, parser.expression, parser.designator, parser.chkreturn);
217
 
234
 
Line 218... Line 235...
218
                IF ~parser2.open(parser2, name.s) THEN
235
                IF ~parser2.open(parser2, name.s) THEN
219
                    IF parser.path # parser.lib_path THEN
236
                    IF parser.path # parser.lib_path THEN
Line 255... Line 272...
255
    unit:  PROG.UNIT;
272
    unit:  PROG.UNIT;
Line 256... Line 273...
256
 
273
 
257
BEGIN
274
BEGIN
Line 258... Line 275...
258
    ASSERT(parser.sym = SCAN.lxIDENT);
275
    ASSERT(parser.sym = SCAN.lxIDENT);
Line 259... Line 276...
259
 
276
 
260
    ident := parser.unit.idents.get(parser.unit, parser.lex.ident, FALSE);
277
    ident := PROG.getIdent(parser.unit, parser.lex.ident, FALSE);
261
 
278
 
Line 262... Line 279...
262
    IF ~forward THEN
279
    IF ~forward THEN
263
        check1(ident # NIL, parser, 48)
280
        check1(ident # NIL, parser, 48)
264
    END;
281
    END;
265
 
282
 
266
    IF (ident # NIL) & (ident.typ = PROG.idMODULE) THEN
283
    IF (ident # NIL) & (ident.typ = PROG.idMODULE) THEN
267
        unit := ident.unit;
284
        unit := ident.unit;
268
        ExpectSym(parser, SCAN.lxPOINT);
285
        ExpectSym(parser, SCAN.lxPOINT);
Line 269... Line 286...
269
        ExpectSym(parser, SCAN.lxIDENT);
286
        ExpectSym(parser, SCAN.lxIDENT);
270
        ident := unit.idents.get(unit, parser.lex.ident, FALSE);
287
        ident := PROG.getIdent(unit, parser.lex.ident, FALSE);
Line 310... Line 327...
310
    |SCAN.lxLE: bool := string1.s <= string2.s
327
    |SCAN.lxLE: bool := string1.s <= string2.s
311
    |SCAN.lxGE: bool := string1.s >= string2.s
328
    |SCAN.lxGE: bool := string1.s >= string2.s
312
    END;
329
    END;
Line 313... Line 330...
313
 
330
 
314
    ARITH.setbool(v, bool)
-
 
315
 
331
    ARITH.setbool(v, bool)
Line 316... Line 332...
316
END strcmp;
332
END strcmp;
317
 
333
 
318
 
334
 
319
PROCEDURE ConstExpression* (parser: PARSER; VAR v: ARITH.VALUE);
335
PROCEDURE ConstExpression* (parser: PARSER; VAR v: ARITH.VALUE);
Line 320... Line 336...
320
VAR
336
VAR
321
    e: EXPR;
337
    e: EXPR;
322
    pos: SCAN.POSITION;
338
    pos: POSITION;
323
 
339
 
324
BEGIN
340
BEGIN
325
    getpos(parser, pos);
341
    getpos(parser, pos);
326
    parser.constexp := TRUE;
342
    parser.constexp := TRUE;
327
    parser.expression(parser, e);
343
    parser.expression(parser, e);
Line 328... Line 344...
328
    parser.constexp := FALSE;
344
    parser.constexp := FALSE;
329
    check(e.obj = eCONST, parser, pos, 62);
345
    check(e.obj = eCONST, pos, 62);
330
    v := e.value
346
    v := e.value
331
END ConstExpression;
347
END ConstExpression;
332
 
348
 
Line 333... Line 349...
333
 
349
 
334
PROCEDURE FieldList (parser: PARSER; rec: PROG.TYPE_);
350
PROCEDURE FieldList (parser: PARSER; rec: PROG.TYPE_);
Line 335... Line 351...
335
VAR
351
VAR
Line 353... Line 369...
353
        IF export THEN
369
        IF export THEN
354
            check1(parser.unit.scopeLvl = 0, parser, 61);
370
            check1(parser.unit.scopeLvl = 0, parser, 61);
355
            Next(parser)
371
            Next(parser)
356
        END;
372
        END;
Line 357... Line 373...
357
 
373
 
Line 358... Line 374...
358
        check(rec.fields.add(rec, name, export), parser, pos, 30);
374
        check(PROG.addField(rec, name, export), pos, 30);
359
 
375
 
360
        IF parser.sym = SCAN.lxCOMMA THEN
376
        IF parser.sym = SCAN.lxCOMMA THEN
361
            ExpectSym(parser, SCAN.lxIDENT)
377
            ExpectSym(parser, SCAN.lxIDENT)
Line 389... Line 405...
389
 
405
 
390
        checklex(parser, SCAN.lxIDENT);
406
        checklex(parser, SCAN.lxIDENT);
Line 391... Line 407...
391
        exit := FALSE;
407
        exit := FALSE;
392
 
408
 
393
        WHILE (parser.sym = SCAN.lxIDENT) & ~exit DO
409
        WHILE (parser.sym = SCAN.lxIDENT) & ~exit DO
394
            check1(type.params.add(type, parser.lex.ident, vPar), parser, 30);
410
            check1(PROG.addParam(type, parser.lex.ident, vPar), parser, 30);
395
            Next(parser);
411
            Next(parser);
396
            IF parser.sym = SCAN.lxCOMMA THEN
412
            IF parser.sym = SCAN.lxCOMMA THEN
397
                ExpectSym(parser, SCAN.lxIDENT)
413
                ExpectSym(parser, SCAN.lxIDENT)
Line 410... Line 426...
410
 
426
 
411
                t0 := ident.type;
427
                t0 := ident.type;
Line 412... Line 428...
412
                t1 := t0;
428
                t1 := t0;
413
 
429
 
414
                WHILE dim > 0 DO
430
                WHILE dim > 0 DO
415
                    t1 := program.enterType(program, PROG.tARRAY, -1, 0, parser.unit);
431
                    t1 := PROG.enterType(program, PROG.tARRAY, -1, 0, parser.unit);
416
                    t1.base := t0;
432
                    t1.base := t0;
417
                    t0 := t1;
433
                    t0 := t1;
Line 418... Line 434...
418
                    DEC(dim)
434
                    DEC(dim)
419
                END;
435
                END;
420
 
436
 
421
                type.params.set(type, t1);
437
                PROG.setParams(type, t1);
422
                Next(parser);
438
                Next(parser);
423
                exit := TRUE
439
                exit := TRUE
Line 447... Line 463...
447
 
463
 
448
        IF parser.sym = SCAN.lxCOLON THEN
464
        IF parser.sym = SCAN.lxCOLON THEN
449
            ExpectSym(parser, SCAN.lxIDENT);
465
            ExpectSym(parser, SCAN.lxIDENT);
450
            ident := QIdent(parser, FALSE);
466
            ident := QIdent(parser, FALSE);
451
            check1(ident.typ = PROG.idTYPE, parser, 68);
467
            check1(ident.typ = PROG.idTYPE, parser, 68);
452
            check1((ident.type.typ # PROG.tRECORD) & (ident.type.typ # PROG.tARRAY), parser, 69);
468
            check1(~(ident.type.typ IN {PROG.tRECORD, PROG.tARRAY}), parser, 69);
453
            check1( ~(ODD(type.call) & (ident.type.typ = PROG.tREAL)), parser, 113);
469
            check1( ~(ODD(type.call) & (ident.type.typ = PROG.tREAL)), parser, 113);
454
            type.base := ident.type;
470
            type.base := ident.type;
455
            Next(parser)
471
            Next(parser)
456
        ELSE
472
        ELSE
Line 459... Line 475...
459
 
475
 
460
    END
476
    END
Line 461... Line 477...
461
END FormalParameters;
477
END FormalParameters;
462
 
478
 
463
 
479
 
Line 464... Line 480...
464
PROCEDURE sysflag (parser: PARSER): INTEGER;
480
PROCEDURE sysflag (parser: PARSER; proc: BOOLEAN): INTEGER;
465
VAR
481
VAR
466
    res: INTEGER;
482
    res, sf: INTEGER;
467
 
483
 
468
BEGIN
484
BEGIN
469
    IF parser.lex.s = "stdcall" THEN
485
    IF parser.lex.s = "stdcall" THEN
470
        res := PROG.stdcall
486
        sf := PROG.sf_stdcall
471
    ELSIF parser.lex.s = "stdcall64" THEN
487
    ELSIF parser.lex.s = "stdcall64" THEN
472
        res := PROG.stdcall64
488
        sf := PROG.sf_stdcall64
473
    ELSIF parser.lex.s = "ccall" THEN
489
    ELSIF parser.lex.s = "ccall" THEN
474
        res := PROG.ccall
490
        sf := PROG.sf_ccall
475
    ELSIF parser.lex.s = "ccall16" THEN
491
    ELSIF parser.lex.s = "ccall16" THEN
476
        res := PROG.ccall16
492
        sf := PROG.sf_ccall16
477
    ELSIF parser.lex.s = "win64" THEN
493
    ELSIF parser.lex.s = "win64" THEN
-
 
494
        sf := PROG.sf_win64
-
 
495
    ELSIF parser.lex.s = "systemv" THEN
-
 
496
        sf := PROG.sf_systemv
-
 
497
    ELSIF parser.lex.s = "windows" THEN
-
 
498
        sf := PROG.sf_windows
-
 
499
    ELSIF parser.lex.s = "linux" THEN
-
 
500
        sf := PROG.sf_linux
-
 
501
    ELSIF parser.lex.s = "code" THEN
-
 
502
        sf := PROG.sf_code
-
 
503
    ELSIF parser.lex.s = "noalign" THEN
-
 
504
        sf := PROG.sf_noalign
-
 
505
    ELSE
-
 
506
        check1(FALSE, parser, 124)
-
 
507
    END;
-
 
508
 
-
 
509
    check1(sf IN program.target.sysflags, parser, 125);
-
 
510
 
-
 
511
    IF proc THEN
-
 
512
        check1(sf IN PROG.proc_flags, parser, 123)
-
 
513
    ELSE
-
 
514
        check1(sf IN PROG.rec_flags, parser, 123)
-
 
515
    END;
-
 
516
 
-
 
517
    CASE sf OF
-
 
518
    |PROG.sf_stdcall:
-
 
519
        res := PROG.stdcall
-
 
520
    |PROG.sf_stdcall64:
-
 
521
        res := PROG.stdcall64
-
 
522
    |PROG.sf_ccall:
-
 
523
        res := PROG.ccall
-
 
524
    |PROG.sf_ccall16:
-
 
525
        res := PROG.ccall16
-
 
526
    |PROG.sf_win64:
-
 
527
        res := PROG.win64
-
 
528
    |PROG.sf_systemv:
478
        res := PROG.win64
529
        res := PROG.systemv
479
    ELSIF parser.lex.s = "systemv" THEN
530
    |PROG.sf_code:
480
        res := PROG.systemv
531
        res := PROG.code
481
    ELSIF parser.lex.s = "windows" THEN
532
    |PROG.sf_windows:
482
        IF program.target.sys IN {mConst.Target_iConsole, mConst.Target_iGUI, mConst.Target_iDLL} THEN
-
 
483
            res := PROG.stdcall
-
 
484
        ELSIF program.target.sys IN {mConst.Target_iConsole64, mConst.Target_iGUI64, mConst.Target_iDLL64} THEN
533
        IF program.target.sys IN {mConst.Target_iConsole, mConst.Target_iGUI, mConst.Target_iDLL} THEN
485
            res := PROG.win64
534
            res := PROG.stdcall
486
        ELSE
535
        ELSIF program.target.sys IN {mConst.Target_iConsole64, mConst.Target_iGUI64, mConst.Target_iDLL64} THEN
487
            check1(FALSE, parser, 118)
536
            res := PROG.win64
488
        END
537
        END
489
    ELSIF parser.lex.s = "linux" THEN
538
    |PROG.sf_linux:
490
        IF program.target.sys = mConst.Target_iELF32 THEN
-
 
491
            res := PROG.ccall16
-
 
492
        ELSIF program.target.sys = mConst.Target_iELF64 THEN
539
        IF program.target.sys IN {mConst.Target_iELF32, mConst.Target_iELFSO32} THEN
493
            res := PROG.systemv
540
            res := PROG.ccall16
494
        ELSE
541
        ELSIF program.target.sys IN {mConst.Target_iELF64, mConst.Target_iELFSO64} THEN
495
            check1(FALSE, parser, 119)
-
 
496
        END
-
 
497
    ELSIF parser.lex.s = "noalign" THEN
542
            res := PROG.systemv
Line 498... Line 543...
498
        res := PROG.noalign
543
        END
499
    ELSE
544
    |PROG.sf_noalign:
Line 500... Line 545...
500
        res := 0
545
        res := PROG.noalign
501
    END
546
    END
502
 
547
 
503
    RETURN res
548
    RETURN res
504
END sysflag;
549
END sysflag;
Line 505... Line 550...
505
 
550
 
Line 506... Line 551...
506
 
551
 
Line 507... Line 552...
507
PROCEDURE procflag (parser: PARSER; VAR import: CODE.IMPORT_PROC; isProc: BOOLEAN): INTEGER;
552
PROCEDURE procflag (parser: PARSER; VAR import: IL.IMPORT_PROC; isProc: BOOLEAN): INTEGER;
508
VAR
553
VAR
509
    call: INTEGER;
554
    call: INTEGER;
510
    dll, proc: SCAN.LEXSTR;
555
    dll, proc: SCAN.LEXSTR;
511
    pos:  SCAN.POSITION;
556
    pos: POSITION;
512
 
-
 
513
BEGIN
-
 
514
 
-
 
515
    import := NIL;
-
 
516
 
-
 
517
    IF parser.sym = SCAN.lxLSQUARE THEN
557
 
518
        getpos(parser, pos);
558
BEGIN
519
        check1(parser.unit.sysimport, parser, 54);
559
 
520
        Next(parser);
560
    import := NIL;
521
        call := sysflag(parser);
561
 
Line 537... Line 577...
537
            dll := parser.lex.s;
577
            dll := parser.lex.s;
538
            ExpectSym(parser, SCAN.lxCOMMA);
578
            ExpectSym(parser, SCAN.lxCOMMA);
539
            ExpectSym(parser, SCAN.lxSTRING);
579
            ExpectSym(parser, SCAN.lxSTRING);
540
            proc := parser.lex.s;
580
            proc := parser.lex.s;
541
            Next(parser);
581
            Next(parser);
542
            import := CODE.AddImp(dll, proc)
582
            import := IL.AddImp(dll, proc)
543
        END;
583
        END;
544
        checklex(parser, SCAN.lxRSQUARE);
584
        checklex(parser, SCAN.lxRSQUARE);
545
        Next(parser)
585
        Next(parser)
546
    ELSE
586
    ELSE
547
        IF program.target.bit_depth = 32 THEN
587
        CASE program.target.bit_depth OF
548
            call := PROG.default
588
        |16: call := PROG.default16
549
        ELSIF program.target.bit_depth = 64 THEN
589
        |32: call := PROG.default32
550
            call := PROG.default64
590
        |64: call := PROG.default64
551
        END
591
        END
552
    END;
592
    END;
Line 553... Line 593...
553
 
593
 
554
    IF import # NIL THEN
594
    IF import # NIL THEN
-
 
595
        check(~(program.target.sys IN {mConst.Target_iELF32, mConst.Target_iELF64, mConst.Target_iELFSO32,
555
        check(~(program.target.sys IN {mConst.Target_iELF32, mConst.Target_iELF64}), parser, pos, 70)
596
            mConst.Target_iELFSO64, mConst.Target_iMSP430}), pos, 70)
Line 556... Line 597...
556
    END
597
    END
557
 
598
 
Line 568... Line 609...
568
VAR
609
VAR
569
    arrLen:     ARITH.VALUE;
610
    arrLen:     ARITH.VALUE;
570
    typeSize:   ARITH.VALUE;
611
    typeSize:   ARITH.VALUE;
571
    ident:      PROG.IDENT;
612
    ident:      PROG.IDENT;
572
    unit:       PROG.UNIT;
613
    unit:       PROG.UNIT;
573
    pos, pos2:  SCAN.POSITION;
614
    pos, pos2:  POSITION;
574
    fieldType:  PROG.TYPE_;
615
    fieldType:  PROG.TYPE_;
575
    baseIdent:  SCAN.IDENT;
616
    baseIdent:  SCAN.IDENT;
576
    a, b:       INTEGER;
617
    a, b:       INTEGER;
577
    RecFlag:    INTEGER;
618
    RecFlag:    INTEGER;
578
    import:     CODE.IMPORT_PROC;
619
    import:     IL.IMPORT_PROC;
Line 579... Line 620...
579
 
620
 
580
BEGIN
621
BEGIN
581
    unit := parser.unit;
622
    unit := parser.unit;
Line 602... Line 643...
602
        END;
643
        END;
603
        NextPos(parser, pos);
644
        NextPos(parser, pos);
Line 604... Line 645...
604
 
645
 
Line 605... Line 646...
605
        ConstExpression(parser, arrLen);
646
        ConstExpression(parser, arrLen);
606
 
647
 
607
        check(arrLen.typ = ARITH.tINTEGER, parser, pos, 43);
648
        check(arrLen.typ = ARITH.tINTEGER, pos, 43);
Line 608... Line 649...
608
        check(ARITH.check(arrLen),         parser, pos, 39);
649
        check(ARITH.check(arrLen),         pos, 39);
Line 609... Line 650...
609
        check(ARITH.getInt(arrLen) > 0,    parser, pos, 51);
650
        check(ARITH.getInt(arrLen) > 0,    pos, 51);
610
 
651
 
611
        t := program.enterType(program, PROG.tARRAY, -1, ARITH.getInt(arrLen), unit);
652
        t := PROG.enterType(program, PROG.tARRAY, -1, ARITH.getInt(arrLen), unit);
612
 
653
 
Line 621... Line 662...
621
 
662
 
Line 622... Line 663...
622
        t.align := t.base.align;
663
        t.align := t.base.align;
623
 
664
 
624
        a := t.length;
665
        a := t.length;
625
        b := t.base.size;
666
        b := t.base.size;
626
        check(ARITH.mulInt(a, b), parser, pos2, 104);
667
        check(ARITH.mulInt(a, b), pos2, 104);
Line 627... Line 668...
627
        check(ARITH.setInt(typeSize, a), parser, pos2, 104);
668
        check(ARITH.setInt(typeSize, a), pos2, 104);
Line 628... Line 669...
628
        t.size := a;
669
        t.size := a;
629
 
670
 
630
        t.closed := TRUE
671
        t.closed := TRUE
Line 631... Line 672...
631
 
672
 
632
    ELSIF parser.sym = SCAN.lxRECORD THEN
673
    ELSIF parser.sym = SCAN.lxRECORD THEN
Line 633... Line 674...
633
        getpos(parser, pos2);
674
        getpos(parser, pos2);
634
        Next(parser);
675
        Next(parser);
635
 
676
 
636
        t := program.enterType(program, PROG.tRECORD, 0, 0, unit);
677
        t := PROG.enterType(program, PROG.tRECORD, 0, 0, unit);
637
        t.align := 1;
678
        t.align := 1;
638
 
-
 
639
        IF parser.sym = SCAN.lxLSQUARE THEN
-
 
640
            check1(parser.unit.sysimport, parser, 54);
-
 
641
            Next(parser);
-
 
642
            RecFlag := sysflag(parser);
-
 
643
            IF RecFlag = PROG.noalign THEN
679
 
644
                t.noalign := TRUE
680
        IF parser.sym = SCAN.lxLSQUARE THEN
645
            ELSE
681
            check1(parser.unit.sysimport, parser, 54);
Line 646... Line 682...
646
                check1(FALSE, parser, 110)
682
            Next(parser);
Line 655... Line 691...
655
            ExpectSym(parser, SCAN.lxIDENT);
691
            ExpectSym(parser, SCAN.lxIDENT);
656
            getpos(parser, pos);
692
            getpos(parser, pos);
Line 657... Line 693...
657
 
693
 
Line 658... Line 694...
658
            type(parser, t.base, {closed});
694
            type(parser, t.base, {closed});
Line 659... Line 695...
659
 
695
 
660
            check(t.base.typ IN {PROG.tRECORD, PROG.tPOINTER}, parser, pos, 52);
696
            check(t.base.typ IN {PROG.tRECORD, PROG.tPOINTER}, pos, 52);
661
 
697
 
662
            IF t.base.typ = PROG.tPOINTER THEN
698
            IF t.base.typ = PROG.tPOINTER THEN
Line 663... Line 699...
663
                t.base := t.base.base;
699
                t.base := t.base.base;
Line 664... Line 700...
664
                check(t.base # NIL, parser, pos, 55)
700
                check(t.base # NIL, pos, 55)
665
            END;
701
            END;
Line 666... Line 702...
666
 
702
 
Line 682... Line 718...
682
 
718
 
683
            ASSERT(parser.sym = SCAN.lxCOLON);
719
            ASSERT(parser.sym = SCAN.lxCOLON);
Line 684... Line 720...
684
            Next(parser);
720
            Next(parser);
685
 
721
 
Line 686... Line 722...
686
            type(parser, fieldType, {closed});
722
            type(parser, fieldType, {closed});
687
            check(t.fields.set(t, fieldType), parser, pos2, 104);
723
            check(PROG.setFields(t, fieldType), pos2, 104);
688
 
724
 
Line 697... Line 733...
697
            END
733
            END
698
        END;
734
        END;
Line 699... Line 735...
699
 
735
 
Line 700... Line 736...
700
        t.closed := TRUE;
736
        t.closed := TRUE;
Line 701... Line 737...
701
 
737
 
702
        CODE.AddRec(t.base.num);
738
        IL.AddRec(t.base.num);
703
 
739
 
704
        IF ~t.noalign THEN
740
        IF ~t.noalign THEN
Line 705... Line 741...
705
            check(MACHINE.Align(t.size, t.align), parser, pos2, 104);
741
            check(UTILS.Align(t.size, t.align), pos2, 104);
706
            check(ARITH.setInt(typeSize, t.size), parser, pos2, 104)
742
            check(ARITH.setInt(typeSize, t.size), pos2, 104)
Line 707... Line 743...
707
        END;
743
        END;
708
 
744
 
709
        checklex(parser, SCAN.lxEND);
745
        checklex(parser, SCAN.lxEND);
Line 710... Line 746...
710
        Next(parser)
746
        Next(parser)
711
 
747
 
Line 712... Line 748...
712
    ELSIF parser.sym = SCAN.lxPOINTER   THEN
748
    ELSIF parser.sym = SCAN.lxPOINTER THEN
Line 713... Line 749...
713
        ExpectSym(parser, SCAN.lxTO);
749
        ExpectSym(parser, SCAN.lxTO);
Line 723... Line 759...
723
        END;
759
        END;
Line 724... Line 760...
724
 
760
 
Line 725... Line 761...
725
        type(parser, t.base, {forward});
761
        type(parser, t.base, {forward});
726
 
762
 
727
        IF t.base # NIL THEN
763
        IF t.base # NIL THEN
728
            check(t.base.typ = PROG.tRECORD, parser, pos, 58)
764
            check(t.base.typ = PROG.tRECORD, pos, 58)
729
        ELSE
765
        ELSE
Line 730... Line 766...
730
            unit.pointers.add(unit, t, baseIdent, pos)
766
            PROG.frwPtr(unit, t, baseIdent, pos)
731
        END
767
        END
732
 
768
 
733
    ELSIF parser.sym = SCAN.lxPROCEDURE THEN
769
    ELSIF parser.sym = SCAN.lxPROCEDURE THEN
734
        NextPos(parser, pos);
770
        NextPos(parser, pos);
735
        t := program.enterType(program, PROG.tPROCEDURE, program.target.adr, 0, unit);
771
        t := PROG.enterType(program, PROG.tPROCEDURE, program.target.adr, 0, unit);
736
        t.align := program.target.adr;
772
        t.align := program.target.adr;
737
        t.call := procflag(parser, import, FALSE);
773
        t.call := procflag(parser, import, FALSE);
Line 744... Line 780...
744
 
780
 
745
 
781
 
746
PROCEDURE IdentDef (parser: PARSER; typ: INTEGER; VAR name: SCAN.IDENT): PROG.IDENT;
782
PROCEDURE IdentDef (parser: PARSER; typ: INTEGER; VAR name: SCAN.IDENT): PROG.IDENT;
747
VAR
783
VAR
Line 748... Line 784...
748
    ident:  PROG.IDENT;
784
    ident:  PROG.IDENT;
749
    pos:    SCAN.POSITION;
785
    pos:    POSITION;
Line 750... Line 786...
750
 
786
 
751
BEGIN
787
BEGIN
752
    ASSERT(parser.sym = SCAN.lxIDENT);
788
    ASSERT(parser.sym = SCAN.lxIDENT);
753
 
789
 
754
    name := parser.lex.ident;
790
    name := parser.lex.ident;
755
    getpos(parser, pos);
791
    getpos(parser, pos);
Line 756... Line 792...
756
    ident := parser.unit.idents.add(parser.unit, name, typ);
792
    ident := PROG.addIdent(parser.unit, name, typ);
757
    check(ident # NIL, parser, pos, 30);
793
    check(ident # NIL, pos, 30);
Line 770... Line 806...
770
 
806
 
771
PROCEDURE ConstTypeDeclaration (parser: PARSER; const: BOOLEAN);
807
PROCEDURE ConstTypeDeclaration (parser: PARSER; const: BOOLEAN);
772
VAR
808
VAR
773
    ident:  PROG.IDENT;
809
    ident: PROG.IDENT;
774
    name:   SCAN.IDENT;
810
    name:  SCAN.IDENT;
Line 775... Line 811...
775
    pos:    SCAN.POSITION;
811
    pos:   POSITION;
776
 
812
 
777
BEGIN
813
BEGIN
778
    IF const THEN
814
    IF const THEN
Line 785... Line 821...
785
    NextPos(parser, pos);
821
    NextPos(parser, pos);
Line 786... Line 822...
786
 
822
 
787
    IF const THEN
823
    IF const THEN
788
        ConstExpression(parser, ident.value);
824
        ConstExpression(parser, ident.value);
789
        IF ident.value.typ = ARITH.tINTEGER THEN
825
        IF ident.value.typ = ARITH.tINTEGER THEN
790
            check(ARITH.check(ident.value), parser, pos, 39)
826
            check(ARITH.check(ident.value), pos, 39)
791
        ELSIF ident.value.typ = ARITH.tREAL THEN
827
        ELSIF ident.value.typ = ARITH.tREAL THEN
792
            check(ARITH.check(ident.value), parser, pos, 40)
828
            check(ARITH.check(ident.value), pos, 40)
793
        END;
829
        END;
794
        ident.typ  := PROG.idCONST;
830
        ident.typ  := PROG.idCONST;
795
        ident.type := program.getType(program, ident.value.typ)
831
        ident.type := PROG.getType(program, ident.value.typ)
796
    ELSE
832
    ELSE
797
        type(parser, ident.type, {})
833
        type(parser, ident.type, {})
Line 798... Line 834...
798
    END;
834
    END;
Line 817... Line 853...
817
        IF parser.sym = SCAN.lxCOMMA THEN
853
        IF parser.sym = SCAN.lxCOMMA THEN
818
            ExpectSym(parser, SCAN.lxIDENT)
854
            ExpectSym(parser, SCAN.lxIDENT)
819
        ELSIF parser.sym = SCAN.lxCOLON THEN
855
        ELSIF parser.sym = SCAN.lxCOLON THEN
820
            Next(parser);
856
            Next(parser);
821
            type(parser, t, {});
857
            type(parser, t, {});
822
            parser.unit.setvars(parser.unit, t);
858
            PROG.setVarsType(parser.unit, t);
823
            checklex(parser, SCAN.lxSEMI);
859
            checklex(parser, SCAN.lxSEMI);
824
            Next(parser)
860
            Next(parser)
825
        ELSE
861
        ELSE
826
            checklex(parser, SCAN.lxCOLON)
862
            checklex(parser, SCAN.lxCOLON)
827
        END
863
        END
Line 833... Line 869...
833
 
869
 
834
PROCEDURE DeclarationSequence (parser: PARSER): BOOLEAN;
870
PROCEDURE DeclarationSequence (parser: PARSER): BOOLEAN;
835
VAR
871
VAR
836
    ptr: PROG.FRWPTR;
872
    ptr: PROG.FRWPTR;
-
 
873
    endmod: BOOLEAN;
Line 837... Line 874...
837
    endmod: BOOLEAN;
874
    pos: POSITION;
838
 
875
 
839
 
876
 
840
    PROCEDURE ProcDeclaration (parser: PARSER): BOOLEAN;
877
    PROCEDURE ProcDeclaration (parser: PARSER): BOOLEAN;
841
    VAR
878
    VAR
842
        proc:       PROG.IDENT;
879
        proc:       PROG.IDENT;
843
        endname,
880
        endname,
844
        name:       SCAN.IDENT;
881
        name:       SCAN.IDENT;
845
        param:      LISTS.ITEM;
882
        param:      PROG.PARAM;
-
 
883
        unit:       PROG.UNIT;
846
        unit:       PROG.UNIT;
884
        ident:      PROG.IDENT;
847
        ident:      PROG.IDENT;
885
        e:          EXPR;
848
        e:          EXPR;
886
        pos, pos1,
849
        pos:        SCAN.POSITION;
887
        pos2:       POSITION;
850
        label:      INTEGER;
888
        label:      INTEGER;
851
        enter:      CODE.COMMAND;
889
        enter:      IL.COMMAND;
852
        call:       INTEGER;
890
        call:       INTEGER;
853
        t:          PROG.TYPE_;
891
        t:          PROG.TYPE_;
854
        import:     CODE.IMPORT_PROC;
892
        import:     IL.IMPORT_PROC;
855
        endmod, b:  BOOLEAN;
893
        endmod, b:  BOOLEAN;
-
 
894
        fparams:    SET;
-
 
895
        variables:  LISTS.LIST;
-
 
896
        int, flt:   INTEGER;
Line 856... Line 897...
856
        fparams:    SET;
897
        comma:      BOOLEAN;
857
        variables:  LISTS.LIST;
898
        code:       ARITH.VALUE;
Line 858... Line 899...
858
        int, flt:   INTEGER;
899
        codeProc:   BOOLEAN;
Line 859... Line 900...
859
 
900
 
Line 860... Line 901...
860
    BEGIN
901
    BEGIN
-
 
902
        endmod := FALSE;
861
        endmod := FALSE;
903
 
Line 862... Line 904...
862
 
904
        unit := parser.unit;
863
        unit := parser.unit;
905
 
864
 
906
        call := procflag(parser, import, TRUE);
865
        call := procflag(parser, import, TRUE);
907
 
866
 
908
        getpos(parser, pos);
867
        getpos(parser, pos);
909
        pos1 := pos;
868
        checklex(parser, SCAN.lxIDENT);
910
        checklex(parser, SCAN.lxIDENT);
Line 869... Line 911...
869
 
911
 
Line 870... Line 912...
870
        IF import # NIL THEN
912
        IF import # NIL THEN
871
            proc := IdentDef(parser, PROG.idIMP, name);
913
            proc := IdentDef(parser, PROG.idIMP, name);
872
            proc.import := import;
914
            proc.import := import;
873
            program.procs.last(PROG.PROC).import := import
915
            program.procs.last(PROG.PROC).import := import
Line 874... Line 916...
874
        ELSE
916
        ELSE
Line -... Line 917...
-
 
917
            proc := IdentDef(parser, PROG.idPROC, name)
-
 
918
        END;
875
            proc := IdentDef(parser, PROG.idPROC, name)
919
 
876
        END;
920
        check(PROG.openScope(unit, proc.proc), pos, 116);
877
 
921
 
Line 878... Line 922...
878
        check(unit.scope.open(unit, proc.proc), parser, pos, 116);
922
        proc.type := PROG.enterType(program, PROG.tPROCEDURE, program.target.adr, 0, unit);
879
 
923
        t := proc.type;
880
        proc.type := program.enterType(program, PROG.tPROCEDURE, program.target.adr, 0, unit);
924
        t.align := program.target.adr;
881
        t := proc.type;
925
        t.call  := call;
882
        t.align  := program.target.adr;
926
 
883
        t.call   := call;
927
        FormalParameters(parser, t);
884
 
928
 
885
        FormalParameters(parser, t);
929
        codeProc := call IN {PROG.code, PROG._code};
886
        
930
 
887
        IF call IN {PROG.systemv, PROG._systemv} THEN
931
        IF call IN {PROG.systemv, PROG._systemv} THEN
-
 
932
            check(t.parSize <= PROG.MAXSYSVPARAM, pos, 120)
-
 
933
        END;
-
 
934
 
-
 
935
        param := t.params.first(PROG.PARAM);
-
 
936
        WHILE param # NIL DO
-
 
937
            ident := PROG.addIdent(unit, param.name, PROG.idPARAM);
-
 
938
            ASSERT(ident # NIL);
-
 
939
            ident.type := param.type;
-
 
940
            ident.offset := param.offset;
-
 
941
            IF param.vPar THEN
-
 
942
                ident.typ := PROG.idVPAR
-
 
943
            END;
-
 
944
            param := param.next(PROG.PARAM)
-
 
945
        END;
-
 
946
 
-
 
947
        IF import = NIL THEN
-
 
948
            label := IL.NewLabel();
-
 
949
            proc.proc.label := label
-
 
950
        END;
-
 
951
 
-
 
952
        IF codeProc THEN
-
 
953
            enter := IL.EnterC(label);
-
 
954
            comma := FALSE;
-
 
955
            WHILE (parser.sym # SCAN.lxSEMI) OR comma DO
-
 
956
                getpos(parser, pos2);
888
            check(t.params.size <= PROG.MAXSYSVPARAM, parser, pos, 120)
957
                ConstExpression(parser, code);
Line 889... Line 958...
889
        END;
958
                check(code.typ = ARITH.tINTEGER, pos2, 43);
890
 
959
                IF program.target.sys # mConst.Target_iMSP430 THEN
Line 891... Line 960...
891
        param := t.params.first;
960
                    check(ARITH.range(code, 0, 255), pos2, 42)
Line 892... Line -...
892
        WHILE param # NIL DO
-
 
893
            ident := unit.idents.add(unit, param(PROG.PARAM).name, PROG.idPARAM);
-
 
894
            ASSERT(ident # NIL);
-
 
895
            ident.type := param(PROG.PARAM).type;
961
                END;
896
            ident.offset := param(PROG.PARAM).offset;
962
                IL.AddCmd(IL.opCODE, ARITH.getInt(code));
897
            IF param(PROG.PARAM).vPar THEN
963
                comma := parser.sym = SCAN.lxCOMMA;
898
                ident.typ := PROG.idVPAR
964
                IF comma THEN
899
            END;
965
                    Next(parser)
900
            param := param.next
966
                ELSE
901
        END;
967
                    checklex(parser, SCAN.lxSEMI)
Line -... Line 968...
-
 
968
                END
902
 
969
            END
-
 
970
        END;
Line 903... Line 971...
903
        checklex(parser, SCAN.lxSEMI);
971
 
904
        Next(parser);
972
        checklex(parser, SCAN.lxSEMI);
905
 
973
        Next(parser);
906
        IF import = NIL THEN
974
 
907
 
975
        IF import = NIL THEN
908
            label := CODE.NewLabel();
976
 
909
            proc.proc.label := label;
977
            IF parser.main & proc.export & program.dll THEN
-
 
978
                IF program.obj THEN
-
 
979
                    check((proc.name.s # "lib_init") & (proc.name.s # "version"), pos, 114)
910
 
980
                END;
911
            IF parser.main & proc.export & program.dll THEN
981
                IL.AddExp(label, proc.name.s);
912
                IF program.obj THEN
982
                proc.proc.used := TRUE
913
                    check((proc.name.s # "lib_init") & (proc.name.s # "version"), parser, pos, 114)
983
            END;
Line 914... Line 984...
914
                END;
984
 
915
                CODE.AddExp(label, proc.name.s);
985
            IF ~codeProc THEN
916
                proc.proc.used := TRUE
986
                b := DeclarationSequence(parser)
917
            END;
987
            END;
Line 918... Line 988...
918
 
988
 
919
            b := DeclarationSequence(parser);
989
            program.locsize := 0;
920
 
990
            IF call IN {PROG._win64, PROG.win64} THEN
921
            program.locsize := 0;
991
                fparams := PROG.getFloatParamsPos(proc.type, 3, int, flt);
922
            IF call IN {PROG._win64, PROG.win64} THEN
992
                enter := IL.Enter(label, LSL(ORD(fparams), 5) + MIN(proc.type.parSize, 4))
923
                fparams := proc.type.params.getfparams(proc.type, 3, int, flt);
993
            ELSIF call IN {PROG._systemv, PROG.systemv} THEN
Line -... Line 994...
-
 
994
                fparams := PROG.getFloatParamsPos(proc.type, PROG.MAXSYSVPARAM - 1, int, flt);
924
                enter := CODE.Enter(label, LSL(ORD(fparams), 5) + MIN(proc.type.params.size, 4))
995
                enter := IL.Enter(label, -(LSL(ORD(fparams), 5) + proc.type.parSize))
925
            ELSIF call IN {PROG._systemv, PROG.systemv} THEN
996
            ELSIF codeProc THEN
926
                fparams := proc.type.params.getfparams(proc.type, PROG.MAXSYSVPARAM - 1, int, flt);
997
 
927
                enter := CODE.Enter(label, -(LSL(ORD(fparams), 5) + proc.type.params.size))
998
            ELSE
-
 
999
                enter := IL.Enter(label, 0)
-
 
1000
            END;
-
 
1001
            proc.proc.enter := enter;
-
 
1002
 
-
 
1003
            IF ~codeProc & (parser.sym = SCAN.lxBEGIN) THEN
-
 
1004
                Next(parser);
-
 
1005
                parser.StatSeq(parser)
928
            ELSE
1006
            END;
Line 929... Line 1007...
929
                enter := CODE.Enter(label, 0)
1007
 
930
            END;
1008
            IF ~codeProc & (t.base # NIL) THEN
931
            proc.proc.enter := enter;
1009
                checklex(parser, SCAN.lxRETURN);
932
 
1010
                NextPos(parser, pos);
933
            IF parser.sym = SCAN.lxBEGIN THEN
1011
                parser.expression(parser, e);
934
                Next(parser);
1012
                check(parser.chkreturn(parser, e, t.base, pos), pos, 87)
935
                parser.StatSeq(parser)
1013
            END;
936
            END;
1014
 
937
 
1015
            IF ~codeProc THEN
938
            IF t.base # NIL THEN
1016
                proc.proc.leave := IL.Leave(t.base # NIL, (t.base # NIL) & (t.base.typ = PROG.tREAL), program.locsize,
939
                checklex(parser, SCAN.lxRETURN);
1017
                    t.parSize * ORD((t.call IN PROG.callee_clean_up) OR (t.call IN {PROG.systemv, PROG._systemv})));
Line 963... Line 1041...
963
                    endmod := TRUE
1041
                    endmod := TRUE
964
                ELSIF endname = name THEN
1042
                ELSIF endname = name THEN
965
                    ExpectSym(parser, SCAN.lxSEMI);
1043
                    ExpectSym(parser, SCAN.lxSEMI);
966
                    Next(parser)
1044
                    Next(parser)
967
                ELSE
1045
                ELSE
968
                    check(FALSE, parser, pos, 60)
1046
                    error(pos, 60)
969
                END
1047
                END
970
            END
1048
            END
971
        END;
1049
        END;
Line 972... Line 1050...
972
 
1050
 
973
        IF import = NIL THEN
1051
        IF ~codeProc & (import = NIL) THEN
974
            variables := LISTS.create(NIL);
1052
            variables := LISTS.create(NIL);
975
        ELSE
1053
        ELSE
976
            variables := NIL
1054
            variables := NIL
Line 977... Line 1055...
977
        END;
1055
        END;
Line 978... Line 1056...
978
 
1056
 
979
        unit.scope.close(unit, variables);
1057
        PROG.closeScope(unit, variables);
980
 
1058
 
Line 981... Line 1059...
981
        IF import = NIL THEN
1059
        IF ~codeProc & (import = NIL) THEN
982
            enter.variables := variables
1060
            enter.variables := variables
Line 999... Line 1077...
999
        WHILE parser.sym = SCAN.lxIDENT DO
1077
        WHILE parser.sym = SCAN.lxIDENT DO
1000
            ConstTypeDeclaration(parser, FALSE)
1078
            ConstTypeDeclaration(parser, FALSE)
1001
        END
1079
        END
1002
    END;
1080
    END;
Line 1003... Line 1081...
1003
 
1081
 
1004
    ptr := parser.unit.pointers.link(parser.unit);
1082
    ptr := PROG.linkPtr(parser.unit);
-
 
1083
    IF ptr # NIL THEN
-
 
1084
        pos.line := ptr.pos.line;
-
 
1085
        pos.col  := ptr.pos.col;
1005
    IF ptr # NIL THEN
1086
        pos.parser := parser;
1006
        IF ptr.notRecord THEN
1087
        IF ptr.notRecord THEN
1007
            error(parser, ptr.pos, 58)
1088
            error(pos, 58)
1008
        ELSE
1089
        ELSE
1009
            error(parser, ptr.pos, 48)
1090
            error(pos, 48)
1010
        END
1091
        END
Line 1011... Line 1092...
1011
    END;
1092
    END;
1012
 
1093
 
Line 1031... Line 1112...
1031
VAR
1112
VAR
1032
    unit:    PROG.UNIT;
1113
    unit:     PROG.UNIT;
1033
    label:   INTEGER;
1114
    label:    INTEGER;
1034
    name:    INTEGER;
1115
    name:     INTEGER;
1035
    endmod:  BOOLEAN;
1116
    endmod:   BOOLEAN;
-
 
1117
    errlabel: INTEGER;
-
 
1118
    errno:    INTEGER;
Line 1036... Line 1119...
1036
 
1119
 
1037
BEGIN
1120
BEGIN
1038
    ASSERT(parser # NIL);
1121
    ASSERT(parser # NIL);
Line 1043... Line 1126...
1043
 
1126
 
1044
    IF ~parser.main THEN
1127
    IF ~parser.main THEN
1045
        check1(parser.lex.s = parser.modname, parser, 23)
1128
        check1(parser.lex.s = parser.modname, parser, 23)
Line 1046... Line 1129...
1046
    END;
1129
    END;
Line 1047... Line 1130...
1047
 
1130
 
Line 1048... Line 1131...
1048
    unit := program.units.create(program.units, parser.lex.ident);
1131
    unit := PROG.newUnit(program, parser.lex.ident);
Line 1060... Line 1143...
1060
    IF parser.unit.sysimport THEN
1143
    IF parser.unit.sysimport THEN
1061
        CONSOLE.String(" (SYSTEM)")
1144
        CONSOLE.String(" (SYSTEM)")
1062
    END;
1145
    END;
1063
    CONSOLE.Ln;
1146
    CONSOLE.Ln;
Line 1064... Line 1147...
1064
 
1147
 
1065
    label := CODE.NewLabel();
1148
    label := IL.NewLabel();
Line 1066... Line 1149...
1066
    CODE.AddJmpCmd(CODE.opJMP, label);
1149
    IL.AddJmpCmd(IL.opJMP, label);
Line -... Line 1150...
-
 
1150
 
1067
 
1151
    name := IL.putstr(unit.name.s);
-
 
1152
 
-
 
1153
    errlabel := IL.NewLabel();
1068
    name := CODE.putstr(unit.name.s);
1154
    IL.SetLabel(errlabel);
-
 
1155
    IL.StrAdr(name);
-
 
1156
    IL.Param1;
-
 
1157
    IL.AddCmd0(IL.opERR);
1069
 
1158
 
1070
    CODE.SetErrLabel;
1159
    FOR errno := 1 TO LEN(IL.codes.errlabels) - 1 DO
-
 
1160
        IL.SetErrLabel(errno);
Line 1071... Line 1161...
1071
    CODE.AddCmd(CODE.opSADR, name);
1161
        IL.AddCmd(IL.opPUSHC, errno);
Line 1072... Line 1162...
1072
    CODE.AddCmd(CODE.opPARAM, 1);
1162
        IL.AddJmpCmd(IL.opJMP, errlabel)
Line 1073... Line 1163...
1073
    CODE.AddCmd0(CODE.opERR);
1163
    END;
Line 1074... Line 1164...
1074
 
1164
 
1075
    endmod := DeclarationSequence(parser);
1165
    endmod := DeclarationSequence(parser);
Line 1089... Line 1179...
1089
        check1(parser.lex.s = unit.name.s, parser, 25);
1179
        check1(parser.lex.s = unit.name.s, parser, 25);
1090
        ExpectSym(parser, SCAN.lxPOINT)
1180
        ExpectSym(parser, SCAN.lxPOINT)
Line 1091... Line 1181...
1091
 
1181
 
Line 1092... Line 1182...
1092
    END;
1182
    END;
1093
 
-
 
1094
    unit.close(unit)
1183
 
Line 1095... Line 1184...
1095
 
1184
    PROG.closeUnit(unit)
1096
END parse;
1185
END parse;
Line 1154... Line 1243...
1154
 
1243
 
1155
    RETURN parser
1244
    RETURN parser
Line 1156... Line 1245...
1156
END create;
1245
END create;
1157
 
1246
 
1158
 
1247
 
1159
PROCEDURE init* (bit_depth, sys: INTEGER);
1248
PROCEDURE init* (bit_depth, target: INTEGER; options: PROG.OPTIONS);
1160
BEGIN
1249
BEGIN
Line 1161... Line 1250...
1161
    program := PROG.create(bit_depth, sys);
1250
    program := PROG.create(bit_depth, target, options);
1162
    parsers := C.create()
1251
    parsers := C.create()