Subversion Repositories Kolibri OS

Rev

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

Rev 7696 Rev 7983
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
 
-
 
8
MODULE PARS;
Line 8... Line 9...
8
MODULE PARS;
9
 
Line 9... Line 10...
9
 
10
IMPORT PROG, SCAN, ARITH, STRINGS, ERRORS, LISTS, IL, CONSOLE, PATHS, UTILS,
Line 75... Line 76...
75
 
76
 
Line 76... Line 77...
76
    program*: PROG.PROGRAM;
77
    program*: PROG.PROGRAM;
Line 77... Line 78...
77
 
78
 
Line 78... Line 79...
78
    parsers: C.COLLECTION;
79
    parsers: C.COLLECTION;
79
 
80
 
80
    lines*: INTEGER;
81
    lines*, modules: INTEGER;
Line 130... Line 131...
130
    errno: INTEGER;
131
    errno: INTEGER;
Line 131... Line 132...
131
 
132
 
132
BEGIN
133
BEGIN
133
    SCAN.Next(parser.scanner, parser.lex);
134
    SCAN.Next(parser.scanner, parser.lex);
134
    errno := parser.lex.error;
135
    errno := parser.lex.error;
135
    IF (errno = 0) & (program.target.sys = mConst.Target_iMSP430) THEN
136
    IF (errno = 0) & (TARGETS.CPU = TARGETS.cpuMSP430) THEN
136
        IF parser.lex.sym = SCAN.lxFLOAT THEN
137
        IF parser.lex.sym = SCAN.lxFLOAT THEN
137
            errno := -SCAN.lxERROR13
138
            errno := -SCAN.lxERROR13
138
        ELSIF (parser.lex.sym = SCAN.lxCHAR) & (parser.lex.value.typ = ARITH.tWCHAR) THEN
139
        ELSIF (parser.lex.sym = SCAN.lxCHAR) & (parser.lex.value.typ = ARITH.tWCHAR) THEN
139
            errno := -SCAN.lxERROR10
140
            errno := -SCAN.lxERROR10
Line 506... Line 507...
506
        sf := PROG.sf_noalign
507
        sf := PROG.sf_noalign
507
    ELSE
508
    ELSE
508
        check1(FALSE, parser, 124)
509
        check1(FALSE, parser, 124)
509
    END;
510
    END;
Line 510... Line 511...
510
 
511
 
Line 511... Line 512...
511
    check1(sf IN program.target.sysflags, parser, 125);
512
    check1(sf IN program.sysflags, parser, 125);
512
 
513
 
513
    IF proc THEN
514
    IF proc THEN
514
        check1(sf IN PROG.proc_flags, parser, 123)
515
        check1(sf IN PROG.proc_flags, parser, 123)
Line 530... Line 531...
530
    |PROG.sf_systemv:
531
    |PROG.sf_systemv:
531
        res := PROG.systemv
532
        res := PROG.systemv
532
    |PROG.sf_code:
533
    |PROG.sf_code:
533
        res := PROG.code
534
        res := PROG.code
534
    |PROG.sf_windows:
535
    |PROG.sf_windows:
535
        IF program.target.sys IN {mConst.Target_iConsole, mConst.Target_iGUI, mConst.Target_iDLL} THEN
536
        IF TARGETS.OS = TARGETS.osWIN32 THEN
536
            res := PROG.stdcall
537
            res := PROG.stdcall
537
        ELSIF program.target.sys IN {mConst.Target_iConsole64, mConst.Target_iGUI64, mConst.Target_iDLL64} THEN
538
        ELSIF TARGETS.OS = TARGETS.osWIN64 THEN
538
            res := PROG.win64
539
            res := PROG.win64
539
        END
540
        END
540
    |PROG.sf_linux:
541
    |PROG.sf_linux:
541
        IF program.target.sys IN {mConst.Target_iELF32, mConst.Target_iELFSO32} THEN
542
        IF TARGETS.OS = TARGETS.osLINUX32 THEN
542
            res := PROG.ccall16
543
            res := PROG.ccall16
543
        ELSIF program.target.sys IN {mConst.Target_iELF64, mConst.Target_iELFSO64} THEN
544
        ELSIF TARGETS.OS = TARGETS.osLINUX64 THEN
544
            res := PROG.systemv
545
            res := PROG.systemv
545
        END
546
        END
546
    |PROG.sf_noalign:
547
    |PROG.sf_noalign:
547
        res := PROG.noalign
548
        res := PROG.noalign
548
    END
549
    END
Line 575... Line 576...
575
            checklex(parser, SCAN.lxRSQUARE)
576
            checklex(parser, SCAN.lxRSQUARE)
576
        END;
577
        END;
577
        IF parser.sym = SCAN.lxCOMMA THEN
578
        IF parser.sym = SCAN.lxCOMMA THEN
578
            ExpectSym(parser, SCAN.lxSTRING);
579
            ExpectSym(parser, SCAN.lxSTRING);
579
            dll := parser.lex.s;
580
            dll := parser.lex.s;
-
 
581
            STRINGS.UpCase(dll);
580
            ExpectSym(parser, SCAN.lxCOMMA);
582
            ExpectSym(parser, SCAN.lxCOMMA);
581
            ExpectSym(parser, SCAN.lxSTRING);
583
            ExpectSym(parser, SCAN.lxSTRING);
582
            proc := parser.lex.s;
584
            proc := parser.lex.s;
583
            Next(parser);
585
            Next(parser);
584
            import := IL.AddImp(dll, proc)
586
            import := IL.AddImp(dll, proc)
585
        END;
587
        END;
586
        checklex(parser, SCAN.lxRSQUARE);
588
        checklex(parser, SCAN.lxRSQUARE);
587
        Next(parser)
589
        Next(parser)
588
    ELSE
590
    ELSE
589
        CASE program.target.bit_depth OF
591
        CASE TARGETS.BitDepth OF
590
        |16: call := PROG.default16
592
        |16: call := PROG.default16
-
 
593
        |32: IF TARGETS.target = TARGETS.STM32CM3 THEN
-
 
594
                 call := PROG.ccall
-
 
595
             ELSE
591
        |32: call := PROG.default32
596
                 call := PROG.default32
-
 
597
             END
592
        |64: call := PROG.default64
598
        |64: call := PROG.default64
593
        END
599
        END
594
    END;
600
    END;
Line 595... Line 601...
595
 
601
 
596
    IF import # NIL THEN
-
 
597
        check(~(program.target.sys IN {mConst.Target_iELF32, mConst.Target_iELF64, mConst.Target_iELFSO32,
602
    IF import # NIL THEN
598
            mConst.Target_iELFSO64, mConst.Target_iMSP430}), pos, 70)
603
        check(TARGETS.Import, pos, 70)
Line 599... Line 604...
599
    END
604
    END
600
 
605
 
Line 749... Line 754...
749
 
754
 
750
    ELSIF parser.sym = SCAN.lxPOINTER THEN
755
    ELSIF parser.sym = SCAN.lxPOINTER THEN
751
        ExpectSym(parser, SCAN.lxTO);
756
        ExpectSym(parser, SCAN.lxTO);
Line 752... Line 757...
752
        Next(parser);
757
        Next(parser);
753
 
758
 
Line 754... Line 759...
754
        t := PROG.enterType(program, PROG.tPOINTER, program.target.adr, 0, unit);
759
        t := PROG.enterType(program, PROG.tPOINTER, TARGETS.AdrSize, 0, unit);
Line 755... Line 760...
755
        t.align := program.target.adr;
760
        t.align := TARGETS.AdrSize;
756
 
761
 
Line 768... Line 773...
768
            PROG.frwPtr(unit, t, baseIdent, pos)
773
            PROG.frwPtr(unit, t, baseIdent, pos)
769
        END
774
        END
Line 770... Line 775...
770
 
775
 
771
    ELSIF parser.sym = SCAN.lxPROCEDURE THEN
776
    ELSIF parser.sym = SCAN.lxPROCEDURE THEN
772
        NextPos(parser, pos);
777
        NextPos(parser, pos);
773
        t := PROG.enterType(program, PROG.tPROCEDURE, program.target.adr, 0, unit);
778
        t := PROG.enterType(program, PROG.tPROCEDURE, TARGETS.AdrSize, 0, unit);
774
        t.align := program.target.adr;
779
        t.align := TARGETS.AdrSize;
775
        t.call := procflag(parser, import, FALSE);
780
        t.call := procflag(parser, import, FALSE);
776
        FormalParameters(parser, t)
781
        FormalParameters(parser, t)
777
    ELSE
782
    ELSE
778
        check1(FALSE, parser, 49)
783
        check1(FALSE, parser, 49)
Line 895... Line 900...
895
        endmod, b:  BOOLEAN;
900
        endmod, b:  BOOLEAN;
896
        fparams:    SET;
901
        fparams:    SET;
897
        variables:  LISTS.LIST;
902
        variables:  LISTS.LIST;
898
        int, flt:   INTEGER;
903
        int, flt:   INTEGER;
899
        comma:      BOOLEAN;
904
        comma:      BOOLEAN;
900
        code:       ARITH.VALUE;
905
        code, iv:   ARITH.VALUE;
-
 
906
        codeProc,
901
        codeProc:   BOOLEAN;
907
        handler:    BOOLEAN;
Line 902... Line 908...
902
 
908
 
903
    BEGIN
909
    BEGIN
-
 
910
        endmod := FALSE;
Line 904... Line 911...
904
        endmod := FALSE;
911
        handler := FALSE;
Line 905... Line 912...
905
 
912
 
Line 919... Line 926...
919
            proc := IdentDef(parser, PROG.idPROC, name)
926
            proc := IdentDef(parser, PROG.idPROC, name)
920
        END;
927
        END;
Line 921... Line 928...
921
 
928
 
Line 922... Line 929...
922
        check(PROG.openScope(unit, proc.proc), pos, 116);
929
        check(PROG.openScope(unit, proc.proc), pos, 116);
923
 
930
 
924
        proc.type := PROG.enterType(program, PROG.tPROCEDURE, program.target.adr, 0, unit);
931
        proc.type := PROG.enterType(program, PROG.tPROCEDURE, TARGETS.AdrSize, 0, unit);
925
        t := proc.type;
932
        t := proc.type;
Line 926... Line 933...
926
        t.align := program.target.adr;
933
        t.align := TARGETS.AdrSize;
Line -... Line 934...
-
 
934
        t.call  := call;
-
 
935
 
-
 
936
        FormalParameters(parser, t);
-
 
937
 
-
 
938
        IF parser.sym = SCAN.lxLSQUARE THEN
-
 
939
            getpos(parser, pos2);
-
 
940
            check(TARGETS.target = TARGETS.STM32CM3, pos2, 24);
-
 
941
            Next(parser);
-
 
942
            getpos(parser, pos2);
-
 
943
            ConstExpression(parser, iv);
-
 
944
            check(iv.typ = ARITH.tINTEGER, pos2, 43);
-
 
945
            check((0 <= ARITH.Int(iv)) & (ARITH.Int(iv) <= THUMB.maxIVT), pos2, 46);
-
 
946
            check(THUMB.SetIV(ARITH.Int(iv)), pos2, 121);
-
 
947
            checklex(parser, SCAN.lxRSQUARE);
927
        t.call  := call;
948
            Next(parser);
Line 928... Line 949...
928
 
949
            handler := TRUE
929
        FormalParameters(parser, t);
950
        END;
930
 
951
 
Line 946... Line 967...
946
            param := param.next(PROG.PARAM)
967
            param := param.next(PROG.PARAM)
947
        END;
968
        END;
Line 948... Line 969...
948
 
969
 
949
        IF import = NIL THEN
970
        IF import = NIL THEN
950
            label := IL.NewLabel();
971
            label := IL.NewLabel();
-
 
972
            proc.proc.label := label;
-
 
973
            proc.proc.used  := handler;
-
 
974
            IF handler THEN
-
 
975
                IL.AddCmd2(IL.opHANDLER, label, ARITH.Int(iv))
951
            proc.proc.label := label
976
            END
Line 952... Line 977...
952
        END;
977
        END;
953
 
978
 
954
        IF codeProc THEN
979
        IF codeProc THEN
955
            enter := IL.EnterC(label);
980
            enter := IL.EnterC(label);
956
            comma := FALSE;
981
            comma := FALSE;
957
            WHILE (parser.sym # SCAN.lxSEMI) OR comma DO
982
            WHILE (parser.sym # SCAN.lxSEMI) OR comma DO
958
                getpos(parser, pos2);
983
                getpos(parser, pos2);
959
                ConstExpression(parser, code);
984
                ConstExpression(parser, code);
960
                check(code.typ = ARITH.tINTEGER, pos2, 43);
985
                check(code.typ = ARITH.tINTEGER, pos2, 43);
-
 
986
                IF TARGETS.CPU IN {TARGETS.cpuX86, TARGETS.cpuAMD64} THEN
-
 
987
                    check(ARITH.range(code, 0, 255), pos2, 42)
961
                IF program.target.sys # mConst.Target_iMSP430 THEN
988
                ELSIF TARGETS.CPU = TARGETS.cpuTHUMB THEN
962
                    check(ARITH.range(code, 0, 255), pos2, 42)
989
                    check(ARITH.range(code, 0, 65535), pos2, 110)
963
                END;
990
                END;
964
                IL.AddCmd(IL.opCODE, ARITH.getInt(code));
991
                IL.AddCmd(IL.opCODE, ARITH.getInt(code));
965
                comma := parser.sym = SCAN.lxCOMMA;
992
                comma := parser.sym = SCAN.lxCOMMA;
Line 974... Line 1001...
974
        checklex(parser, SCAN.lxSEMI);
1001
        checklex(parser, SCAN.lxSEMI);
975
        Next(parser);
1002
        Next(parser);
Line 976... Line 1003...
976
 
1003
 
Line 977... Line 1004...
977
        IF import = NIL THEN
1004
        IF import = NIL THEN
978
 
1005
 
979
            IF parser.main & proc.export & program.dll THEN
1006
            IF parser.main & proc.export & TARGETS.Dll THEN
980
                IF program.obj THEN
1007
                IF TARGETS.target = TARGETS.KolibriOSDLL THEN
981
                    check((proc.name.s # "lib_init") & (proc.name.s # "version"), pos, 114)
1008
                    check((proc.name.s # "lib_init") & (proc.name.s # "version"), pos, 114)
982
                END;
1009
                END;
983
                IL.AddExp(label, proc.name.s);
1010
                IL.AddExp(label, proc.name.s);
Line 1021... Line 1048...
1021
                checklex(parser, SCAN.lxEND)
1048
                checklex(parser, SCAN.lxEND)
1022
            ELSE
1049
            ELSE
1023
                proc.proc.leave := IL.LeaveC()
1050
                proc.proc.leave := IL.LeaveC()
1024
            END;
1051
            END;
Line 1025... Line 1052...
1025
 
1052
 
1026
            IF program.target.sys = mConst.Target_iMSP430 THEN
1053
            IF TARGETS.CPU = TARGETS.cpuMSP430 THEN
1027
                check((enter.param2 * ORD(~codeProc) + proc.type.parSize) * 2 + 16 < program.target.options.ram, pos1, 63)
1054
                check((enter.param2 * ORD(~codeProc) + proc.type.parSize) * 2 + 16 < program.options.ram, pos1, 63)
1028
            END
1055
            END
Line 1029... Line 1056...
1029
        END;
1056
        END;
1030
 
1057
 
Line 1139... Line 1166...
1139
    Next(parser);
1166
    Next(parser);
1140
    IF parser.sym = SCAN.lxIMPORT THEN
1167
    IF parser.sym = SCAN.lxIMPORT THEN
1141
        ImportList(parser)
1168
        ImportList(parser)
1142
    END;
1169
    END;
Line -... Line 1170...
-
 
1170
 
-
 
1171
    INC(modules);
-
 
1172
 
-
 
1173
    CONSOLE.String("compiling ");
1143
 
1174
    IF TARGETS.CPU IN {TARGETS.cpuTHUMB, TARGETS.cpuMSP430} THEN
-
 
1175
        CONSOLE.String("("); CONSOLE.Int(modules); CONSOLE.String(") ")
-
 
1176
    END;
1144
    CONSOLE.String("compiling "); CONSOLE.String(unit.name.s);
1177
    CONSOLE.String(unit.name.s);
1145
    IF parser.unit.sysimport THEN
1178
    IF parser.unit.sysimport THEN
1146
        CONSOLE.String(" (SYSTEM)")
1179
        CONSOLE.String(" (SYSTEM)")
1147
    END;
1180
    END;
Line 1154... Line 1187...
1154
 
1187
 
1155
    errlabel := IL.NewLabel();
1188
    errlabel := IL.NewLabel();
1156
    IL.SetLabel(errlabel);
1189
    IL.SetLabel(errlabel);
1157
    IL.StrAdr(name);
1190
    IL.StrAdr(name);
-
 
1191
    IL.Param1;
-
 
1192
    IF TARGETS.CPU IN {TARGETS.cpuTHUMB, TARGETS.cpuMSP430} THEN
-
 
1193
        IL.AddCmd(IL.opPUSHC, modules)
1158
    IL.Param1;
1194
    END;
Line 1159... Line 1195...
1159
    IL.AddCmd0(IL.opERR);
1195
    IL.AddCmd0(IL.opERR);
1160
 
1196
 
1161
    FOR errno := 1 TO LEN(IL.codes.errlabels) - 1 DO
1197
    FOR errno := 1 TO LEN(IL.codes.errlabels) - 1 DO
Line 1225... Line 1261...
1225
BEGIN
1261
BEGIN
1226
    parser := NewParser();
1262
    parser := NewParser();
Line 1227... Line 1263...
1227
 
1263
 
1228
    parser.path     := path;
1264
    parser.path     := path;
1229
    parser.lib_path := lib_path;
1265
    parser.lib_path := lib_path;
1230
    parser.ext      := mConst.FILE_EXT;
1266
    parser.ext      := UTILS.FILE_EXT;
1231
    parser.fname    := path;
1267
    parser.fname    := path;
1232
    parser.modname  := "";
1268
    parser.modname  := "";
1233
    parser.scanner  := NIL;
1269
    parser.scanner  := NIL;
1234
    parser.unit     := NIL;
1270
    parser.unit     := NIL;
Line 1245... Line 1281...
1245
 
1281
 
1246
    RETURN parser
1282
    RETURN parser
Line 1247... Line 1283...
1247
END create;
1283
END create;
1248
 
1284
 
1249
 
1285
 
1250
PROCEDURE init* (bit_depth, target: INTEGER; options: PROG.OPTIONS);
1286
PROCEDURE init* (options: PROG.OPTIONS);
1251
BEGIN
1287
BEGIN
-
 
1288
    program := PROG.create(options);
1252
    program := PROG.create(bit_depth, target, options);
1289
    parsers := C.create();
Line 1253... Line 1290...
1253
    parsers := C.create();
1290
    lines   := 0;