Subversion Repositories Kolibri OS

Rev

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

Rev 8097 Rev 8859
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-2020, Anton Krotov
4
    Copyright (c) 2018-2021, 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 STATEMENTS;
8
MODULE STATEMENTS;
9
 
9
 
Line 10... Line 10...
10
IMPORT
10
IMPORT
Line 24... Line 24...
24
    errASSERT = 1;  errPTR  =  2;  errDIV  =  3;  errPROC =  4;
24
    errASSERT = 1;  errPTR  =  2;  errDIV  =  3;  errPROC =  4;
25
    errGUARD  = 5;  errIDX  =  6;  errCASE =  7;  errCOPY =  8;
25
    errGUARD  = 5;  errIDX  =  6;  errCASE =  7;  errCOPY =  8;
26
    errCHR    = 9;  errWCHR = 10;  errBYTE = 11;
26
    errCHR    = 9;  errWCHR = 10;  errBYTE = 11;
Line 27... Line 27...
27
 
27
 
-
 
28
    chkIDX* = 0; chkGUARD* = 1; chkPTR* = 2; chkCHR* = 3; chkWCHR* = 4; chkBYTE* = 5;
Line 28... Line 29...
28
    chkIDX* = 0; chkGUARD* = 1; chkPTR* = 2; chkCHR* = 3; chkWCHR* = 4; chkBYTE* = 5;
29
    chkSTK* = MSP430.chkSTK; (* 6 *)
Line 29... Line 30...
29
 
30
 
Line 30... Line 31...
30
    chkALL* = {chkIDX, chkGUARD, chkPTR, chkCHR, chkWCHR, chkBYTE};
31
    chkALL* = {chkIDX, chkGUARD, chkPTR, chkCHR, chkWCHR, chkBYTE, chkSTK};
Line 205... Line 206...
205
BEGIN
206
BEGIN
206
    ASSERT(isString(e));
207
    ASSERT(isString(e));
207
    IF e._type = tCHAR THEN
208
    IF e._type = tCHAR THEN
208
        res := 1
209
        res := 1
209
    ELSE
210
    ELSE
210
        res := LENGTH(e.value.string(SCAN.IDENT).s)
211
        res := LENGTH(e.value.string(SCAN.STRING).s)
211
    END
212
    END
212
    RETURN res
213
    RETURN res
213
END strlen;
214
END strlen;
Line 238... Line 239...
238
BEGIN
239
BEGIN
239
    ASSERT(isStringW(e));
240
    ASSERT(isStringW(e));
240
    IF e._type.typ IN {PROG.tCHAR, PROG.tWCHAR} THEN
241
    IF e._type.typ IN {PROG.tCHAR, PROG.tWCHAR} THEN
241
        res := 1
242
        res := 1
242
    ELSE
243
    ELSE
243
        res := _length(e.value.string(SCAN.IDENT).s)
244
        res := _length(e.value.string(SCAN.STRING).s)
244
    END
245
    END
245
    RETURN res
246
    RETURN res
246
END utf8strlen;
247
END utf8strlen;
Line 299... Line 300...
299
 
300
 
300
 
301
 
301
PROCEDURE String (e: PARS.EXPR): INTEGER;
302
PROCEDURE String (e: PARS.EXPR): INTEGER;
302
VAR
303
VAR
Line 303... Line 304...
303
    offset: INTEGER;
304
    offset: INTEGER;
304
    string: SCAN.IDENT;
305
    string: SCAN.STRING;
305
 
306
 
306
BEGIN
307
BEGIN
307
    IF strlen(e) # 1 THEN
308
    IF strlen(e) # 1 THEN
308
        string := e.value.string(SCAN.IDENT);
309
        string := e.value.string(SCAN.STRING);
309
        IF string.offset = -1 THEN
310
        IF string.offset = -1 THEN
310
            string.offset := IL.putstr(string.s);
311
            string.offset := IL.putstr(string.s);
Line 319... Line 320...
319
 
320
 
320
 
321
 
321
PROCEDURE StringW (e: PARS.EXPR): INTEGER;
322
PROCEDURE StringW (e: PARS.EXPR): INTEGER;
322
VAR
323
VAR
Line 323... Line 324...
323
    offset: INTEGER;
324
    offset: INTEGER;
324
    string: SCAN.IDENT;
325
    string: SCAN.STRING;
325
 
326
 
326
BEGIN
327
BEGIN
327
    IF utf8strlen(e) # 1 THEN
328
    IF utf8strlen(e) # 1 THEN
328
        string := e.value.string(SCAN.IDENT);
329
        string := e.value.string(SCAN.STRING);
329
        IF string.offsetW = -1 THEN
330
        IF string.offsetW = -1 THEN
330
            string.offsetW := IL.putstrW(string.s);
331
            string.offsetW := IL.putstrW(string.s);
331
        END;
332
        END;
332
        offset := string.offsetW
333
        offset := string.offsetW
333
    ELSE
334
    ELSE
334
        IF e._type.typ IN {PROG.tWCHAR, PROG.tCHAR} THEN
335
        IF e._type.typ IN {PROG.tWCHAR, PROG.tCHAR} THEN
335
            offset := IL.putstrW1(ARITH.Int(e.value))
336
            offset := IL.putstrW1(ARITH.Int(e.value))
336
        ELSE (* e._type.typ = PROG.tSTRING *)
337
        ELSE (* e._type.typ = PROG.tSTRING *)
337
            string := e.value.string(SCAN.IDENT);
338
            string := e.value.string(SCAN.STRING);
338
            IF string.offsetW = -1 THEN
339
            IF string.offsetW = -1 THEN
339
                string.offsetW := IL.putstrW(string.s);
340
                string.offsetW := IL.putstrW(string.s);
Line 381... Line 382...
381
            IF ~PROG.isOpenArray(VarType) THEN
382
            IF ~PROG.isOpenArray(VarType) THEN
382
                IL.Const(VarType.length)
383
                IL.Const(VarType.length)
383
            END;
384
            END;
384
            IL.AddCmd(IL.opCOPYA, VarType.base.size);
385
            IL.AddCmd(IL.opCOPYA, VarType.base.size);
385
            label := IL.NewLabel();
386
            label := IL.NewLabel();
386
            IL.AddJmpCmd(IL.opJNZ, label);
387
            IL.Jmp(IL.opJNZ, label);
387
            IL.OnError(line, errCOPY);
388
            IL.OnError(line, errCOPY);
388
            IL.SetLabel(label)
389
            IL.SetLabel(label)
Line 389... Line 390...
389
 
390
 
390
        ELSIF isInt(e) & (VarType.typ IN {PROG.tBYTE, PROG.tINTEGER}) THEN
391
        ELSIF isInt(e) & (VarType.typ IN {PROG.tBYTE, PROG.tINTEGER}) THEN
Line 434... Line 435...
434
                IL.AddCmd0(IL.opSAVE8)
435
                IL.AddCmd0(IL.opSAVE8)
435
            END
436
            END
436
        ELSIF (e.obj = eCONST) & isChar(e) & (VarType = tWCHAR) THEN
437
        ELSIF (e.obj = eCONST) & isChar(e) & (VarType = tWCHAR) THEN
437
            IL.AddCmd(IL.opSAVE16C, ARITH.Int(e.value))
438
            IL.AddCmd(IL.opSAVE16C, ARITH.Int(e.value))
438
        ELSIF isStringW1(e) & (VarType = tWCHAR) THEN
439
        ELSIF isStringW1(e) & (VarType = tWCHAR) THEN
439
            IL.AddCmd(IL.opSAVE16C, StrToWChar(e.value.string(SCAN.IDENT).s))
440
            IL.AddCmd(IL.opSAVE16C, StrToWChar(e.value.string(SCAN.STRING).s))
440
        ELSIF isCharW(e) & (VarType = tWCHAR) THEN
441
        ELSIF isCharW(e) & (VarType = tWCHAR) THEN
441
            IF e.obj = eCONST THEN
442
            IF e.obj = eCONST THEN
442
                IL.AddCmd(IL.opSAVE16C, ARITH.Int(e.value))
443
                IL.AddCmd(IL.opSAVE16C, ARITH.Int(e.value))
443
            ELSE
444
            ELSE
444
                IL.AddCmd0(IL.opSAVE16)
445
                IL.AddCmd0(IL.opSAVE16)
Line 606... Line 607...
606
                    IL.AddCmd0(IL.opPUSHF)
607
                    IL.AddCmd0(IL.opPUSHF)
607
                ELSIF e._type.typ = PROG.tNIL THEN
608
                ELSIF e._type.typ = PROG.tNIL THEN
608
                    IL.Const(0);
609
                    IL.Const(0);
609
                    IL.Param1
610
                    IL.Param1
610
                ELSIF isStringW1(e) & (p._type = tWCHAR) THEN
611
                ELSIF isStringW1(e) & (p._type = tWCHAR) THEN
611
                    IL.Const(StrToWChar(e.value.string(SCAN.IDENT).s));
612
                    IL.Const(StrToWChar(e.value.string(SCAN.STRING).s));
612
                    IL.Param1
613
                    IL.Param1
613
                ELSIF (e._type.typ = PROG.tSTRING) OR
614
                ELSIF (e._type.typ = PROG.tSTRING) OR
614
                      (e._type.typ IN {PROG.tCHAR, PROG.tWCHAR}) & (p._type.typ = PROG.tARRAY) & (p._type.base.typ IN {PROG.tCHAR, PROG.tWCHAR}) THEN
615
                      (e._type.typ IN {PROG.tCHAR, PROG.tWCHAR}) & (p._type.typ = PROG.tARRAY) & (p._type.base.typ IN {PROG.tCHAR, PROG.tWCHAR}) THEN
615
                    IF p._type.base = tCHAR THEN
616
                    IF p._type.base = tCHAR THEN
616
                        stroffs := String(e);
617
                        stroffs := String(e);
Line 707... Line 708...
707
        PARS.Next(parser);
708
        PARS.Next(parser);
708
(*    END; *)
709
(*    END; *)
Line 709... Line 710...
709
 
710
 
Line 710... Line -...
710
    getpos(parser, pos);
-
 
711
 
-
 
712
    IF e.obj IN {eSYSPROC, eSYSFUNC} THEN
-
 
713
        IF parser.unit.scopeLvl > 0 THEN
-
 
714
            parser.unit.scopes[parser.unit.scopeLvl].enter(IL.COMMAND).allocReg := FALSE
-
 
715
        END
-
 
716
    END;
711
    getpos(parser, pos);
Line 717... Line 712...
717
 
712
 
718
    IF e.obj IN {eSTPROC, eSYSPROC} THEN
713
    IF e.obj IN {eSTPROC, eSYSPROC} THEN
719
 
714
 
Line 1144... Line 1139...
1144
            ELSE
1139
            ELSE
1145
                IL.AddCmd(IL.opMODR, 2)
1140
                IL.AddCmd(IL.opMODR, 2)
1146
            END
1141
            END
Line 1147... Line 1142...
1147
 
1142
 
-
 
1143
        |PROG.stORD:
1148
        |PROG.stORD:
1144
            IL.AddCmd(IL.opPRECALL, 0);
1149
            PExpression(parser, e);
1145
            PExpression(parser, e);
1150
            PARS.check(isChar(e) OR isBoolean(e) OR isSet(e) OR isCharW(e) OR isStringW1(e), pos, 66);
1146
            PARS.check(isChar(e) OR isBoolean(e) OR isSet(e) OR isCharW(e) OR isStringW1(e), pos, 66);
1151
            IF e.obj = eCONST THEN
1147
            IF e.obj = eCONST THEN
1152
                IF isStringW1(e) THEN
1148
                IF isStringW1(e) THEN
1153
                    ASSERT(ARITH.setInt(e.value, StrToWChar(e.value.string(SCAN.IDENT).s)))
1149
                    ASSERT(ARITH.setInt(e.value, StrToWChar(e.value.string(SCAN.STRING).s)))
1154
                ELSE
1150
                ELSE
1155
                    ARITH.ord(e.value)
1151
                    ARITH.ord(e.value)
1156
                END
1152
                END
1157
            ELSE
1153
            ELSE
Line 1380... Line 1376...
1380
        IL.load(e._type.size)
1376
        IL.load(e._type.size)
1381
    END;
1377
    END;
Line 1382... Line 1378...
1382
 
1378
 
1383
    IF chkPTR IN Options.checking THEN
1379
    IF chkPTR IN Options.checking THEN
1384
        label := IL.NewLabel();
1380
        label := IL.NewLabel();
1385
        IL.AddJmpCmd(IL.opJNZ1, label);
1381
        IL.Jmp(IL.opJNZ1, label);
1386
        IL.OnError(pos.line, error);
1382
        IL.OnError(pos.line, error);
1387
        IL.SetLabel(label)
1383
        IL.SetLabel(label)
1388
    END
1384
    END
Line 1549... Line 1545...
1549
 
1545
 
Line 1550... Line 1546...
1550
        UNTIL parser.sym # SCAN.lxCOMMA;
1546
        UNTIL parser.sym # SCAN.lxCOMMA;
1551
 
1547
 
-
 
1548
        PARS.checklex(parser, SCAN.lxRSQUARE);
1552
        PARS.checklex(parser, SCAN.lxRSQUARE);
1549
        PARS.Next(parser);
-
 
1550
        IF ~(isArr(e) & (e._type.length = 0) & (parser.sym = SCAN.lxLSQUARE)) THEN
Line 1553... Line 1551...
1553
        PARS.Next(parser);
1551
            e.ident := NIL
1554
        e.ident := NIL
1552
        END
1555
 
1553
 
1556
    ELSIF parser.sym = SCAN.lxCARET DO
1554
    ELSIF parser.sym = SCAN.lxCARET DO
Line 1626... Line 1624...
1626
        fparSize := 0
1624
        fparSize := 0
1627
    END;
1625
    END;
1628
    IL.setlast(begcall);
1626
    IL.setlast(begcall);
1629
    IL.AddCmd(IL.opPRECALL, ORD(isfloat));
1627
    IL.AddCmd(IL.opPRECALL, ORD(isfloat));
Line 1630... Line 1628...
1630
 
1628
 
1631
    IF cconv IN {PROG._ccall16, PROG.ccall16} THEN
1629
    IF cconv IN {PROG._ccall, PROG.ccall} THEN
1632
        IL.AddCmd(IL.opALIGN16, parSize)
1630
        IL.AddCmd(IL.opALIGN16, parSize)
1633
    ELSIF cconv IN {PROG._win64, PROG.win64} THEN
1631
    ELSIF cconv IN {PROG._win64, PROG.win64} THEN
1634
        IL.AddCmd(IL.opWIN64ALIGN16, parSize)
1632
        IL.AddCmd(IL.opWIN64ALIGN16, parSize)
1635
    ELSIF cconv IN {PROG._systemv, PROG.systemv} THEN
1633
    ELSIF cconv IN {PROG._systemv, PROG.systemv} THEN
Line 1644... Line 1642...
1644
    ELSIF isExpr(e) THEN
1642
    ELSIF isExpr(e) THEN
1645
        deref(pos, e, CallStat, errPROC);
1643
        deref(pos, e, CallStat, errPROC);
1646
        IL.CallP(callconv, fparSize)
1644
        IL.CallP(callconv, fparSize)
1647
    END;
1645
    END;
Line 1648... Line 1646...
1648
 
1646
 
1649
    IF cconv IN {PROG._ccall16, PROG.ccall16} THEN
1647
    IF cconv IN {PROG._ccall, PROG.ccall} THEN
1650
        IL.AddCmd(IL.opCLEANUP, parSize);
1648
        IL.AddCmd(IL.opCLEANUP, parSize);
1651
        IL.AddCmd0(IL.opPOPSP)
1649
        IL.AddCmd0(IL.opPOPSP)
1652
    ELSIF cconv IN {PROG._win64, PROG.win64} THEN
1650
    ELSIF cconv IN {PROG._win64, PROG.win64} THEN
1653
        IL.AddCmd(IL.opCLEANUP, MAX(parSize + parSize MOD 2, 4) + 1);
1651
        IL.AddCmd(IL.opCLEANUP, MAX(parSize + parSize MOD 2, 4) + 1);
1654
        IL.AddCmd0(IL.opPOPSP)
1652
        IL.AddCmd0(IL.opPOPSP)
1655
    ELSIF cconv IN {PROG._systemv, PROG.systemv} THEN
1653
    ELSIF cconv IN {PROG._systemv, PROG.systemv} THEN
1656
        IL.AddCmd(IL.opCLEANUP, parSize + stk_par);
1654
        IL.AddCmd(IL.opCLEANUP, parSize + stk_par);
1657
        IL.AddCmd0(IL.opPOPSP)
1655
        IL.AddCmd0(IL.opPOPSP)
1658
    ELSIF cconv IN {PROG._ccall, PROG.ccall, PROG.default16, PROG.code, PROG._code} THEN
1656
    ELSIF cconv IN {PROG._cdecl, PROG.cdecl, PROG.default16, PROG.code, PROG._code} THEN
1659
        IL.AddCmd(IL.opCLEANUP, parSize)
1657
        IL.AddCmd(IL.opCLEANUP, parSize)
Line 1660... Line 1658...
1660
    END;
1658
    END;
1661
 
1659
 
Line 1910... Line 1908...
1910
 
1908
 
1911
                    IF label = -1 THEN
1909
                    IF label = -1 THEN
1912
                        label := IL.NewLabel()
1910
                        label := IL.NewLabel()
Line 1913... Line 1911...
1913
                    END;
1911
                    END;
1914
 
1912
 
1915
                    IF e.obj = eCONST THEN
1913
                    IF (e.obj = eCONST) & isBoolean(e) THEN
1916
                        IL.Const(ORD(ARITH.getBool(e.value)))
1914
                        IL.Const(ORD(ARITH.getBool(e.value)))
1917
                    END;
1915
                    END;
1918
                    IL.AndOrOpt(label)
1916
                    IL.Jmp(IL.opJZ, label)
Line 1919... Line 1917...
1919
                END
1917
                END
Line 2009... Line 2007...
2009
                    END
2007
                    END
Line 2010... Line 2008...
2010
 
2008
 
2011
                ELSE
2009
                ELSE
2012
                    IF e1.obj # eCONST THEN
2010
                    IF e1.obj # eCONST THEN
2013
                        label1 := IL.NewLabel();
2011
                        label1 := IL.NewLabel();
2014
                        IL.AddJmpCmd(IL.opJG, label1)
2012
                        IL.Jmp(IL.opJG, label1)
2015
                    END;
2013
                    END;
2016
                    IF e.obj = eCONST THEN
2014
                    IF e.obj = eCONST THEN
2017
                        IL.OnError(pos.line, errDIV);
2015
                        IL.OnError(pos.line, errDIV);
2018
                        IL.SetLabel(label1);
2016
                        IL.SetLabel(label1);
Line 2028... Line 2026...
2028
                END
2026
                END
Line 2029... Line 2027...
2029
 
2027
 
2030
            |SCAN.lxAND:
2028
            |SCAN.lxAND:
Line 2031... Line 2029...
2031
                PARS.check(isBoolean(e) & isBoolean(e1), pos, 37);
2029
                PARS.check(isBoolean(e) & isBoolean(e1), pos, 37);
2032
 
2030
 
2033
                IF (e.obj = eCONST) & (e1.obj = eCONST) THEN
2031
                IF (e.obj = eCONST) & (e1.obj = eCONST) & parser.constexp THEN
2034
                    ARITH.opBoolean(e.value, e1.value, "&")
2032
                    ARITH.opBoolean(e.value, e1.value, "&")
2035
                ELSE
2033
                ELSE
2036
                    e.obj := eEXPR;
2034
                    e.obj := eEXPR;
Line 2042... Line 2040...
2042
            END
2040
            END
2043
        END;
2041
        END;
Line 2044... Line 2042...
2044
 
2042
 
2045
        IF label # -1 THEN
2043
        IF label # -1 THEN
2046
            label1 := IL.NewLabel();
2044
            label1 := IL.NewLabel();
2047
            IL.AddJmpCmd(IL.opJNZ, label1);
2045
            IL.Jmp(IL.opJNZ, label1);
2048
            IL.SetLabel(label);
2046
            IL.SetLabel(label);
2049
            IL.Const(0);
2047
            IL.Const(0);
2050
            IL.drop;
2048
            IL.drop;
2051
            label := IL.NewLabel();
2049
            label := IL.NewLabel();
2052
            IL.AddJmpCmd(IL.opJMP, label);
2050
            IL.Jmp(IL.opJMP, label);
2053
            IL.SetLabel(label1);
2051
            IL.SetLabel(label1);
2054
            IL.Const(1);
2052
            IL.Const(1);
2055
            IL.SetLabel(label);
2053
            IL.SetLabel(label);
2056
            IL.AddCmd0(IL.opAND)
2054
            IL.AddCmd0(IL.opAND)
Line 2061... Line 2059...
2061
    PROCEDURE SimpleExpression (parser: PARS.PARSER; VAR e: PARS.EXPR);
2059
    PROCEDURE SimpleExpression (parser: PARS.PARSER; VAR e: PARS.EXPR);
2062
    VAR
2060
    VAR
2063
        pos: PARS.POSITION;
2061
        pos: PARS.POSITION;
2064
        op:  INTEGER;
2062
        op:  INTEGER;
2065
        e1:  PARS.EXPR;
2063
        e1:  PARS.EXPR;
2066
        s, s1: SCAN.LEXSTR;
2064
        s, s1: SCAN.TEXTSTR;
Line 2067... Line 2065...
2067
 
2065
 
Line 2068... Line 2066...
2068
        plus, minus: BOOLEAN;
2066
        plus, minus: BOOLEAN;
Line 2115... Line 2113...
2115
 
2113
 
2116
                    IF label = -1 THEN
2114
                    IF label = -1 THEN
2117
                        label := IL.NewLabel()
2115
                        label := IL.NewLabel()
Line 2118... Line 2116...
2118
                    END;
2116
                    END;
2119
 
2117
 
2120
                    IF e.obj = eCONST THEN
2118
                    IF (e.obj = eCONST) & isBoolean(e) THEN
2121
                        IL.Const(ORD(ARITH.getBool(e.value)))
-
 
2122
                    END;
2119
                        IL.Const(ORD(ARITH.getBool(e.value)))
2123
                    IL.not;
2120
                    END;
Line 2124... Line 2121...
2124
                    IL.AndOrOpt(label)
2121
                    IL.Jmp(IL.opJNZ, label)
Line 2125... Line 2122...
2125
                END
2122
                END
Line 2153... Line 2150...
2153
 
2150
 
2154
                    |ARITH.tCHAR, ARITH.tSTRING:
2151
                    |ARITH.tCHAR, ARITH.tSTRING:
2155
                        IF e.value.typ = ARITH.tCHAR THEN
2152
                        IF e.value.typ = ARITH.tCHAR THEN
2156
                            ARITH.charToStr(e.value, s)
2153
                            ARITH.charToStr(e.value, s)
2157
                        ELSE
2154
                        ELSE
2158
                            s := e.value.string(SCAN.IDENT).s
2155
                            s := e.value.string(SCAN.STRING).s
2159
                        END;
2156
                        END;
2160
                        IF e1.value.typ = ARITH.tCHAR THEN
2157
                        IF e1.value.typ = ARITH.tCHAR THEN
2161
                            ARITH.charToStr(e1.value, s1)
2158
                            ARITH.charToStr(e1.value, s1)
2162
                        ELSE
2159
                        ELSE
2163
                            s1 := e1.value.string(SCAN.IDENT).s
2160
                            s1 := e1.value.string(SCAN.STRING).s
2164
                        END;
2161
                        END;
2165
                        PARS.check(ARITH.concat(s, s1), pos, 5);
2162
                        PARS.check(ARITH.concat(s, s1), pos, 5);
2166
                        e.value.string := SCAN.enterid(s);
2163
                        e.value.string := SCAN.enterStr(s);
2167
                        e.value.typ := ARITH.tSTRING;
2164
                        e.value.typ := ARITH.tSTRING;
2168
                        e._type := PROG.program.stTypes.tSTRING
2165
                        e._type := PROG.program.stTypes.tSTRING
Line 2169... Line 2166...
2169
                   END
2166
                   END
Line 2200... Line 2197...
2200
                END
2197
                END
Line 2201... Line 2198...
2201
 
2198
 
2202
            |SCAN.lxOR:
2199
            |SCAN.lxOR:
Line 2203... Line 2200...
2203
                PARS.check(isBoolean(e) & isBoolean(e1), pos, 37);
2200
                PARS.check(isBoolean(e) & isBoolean(e1), pos, 37);
2204
 
2201
 
2205
                IF (e.obj = eCONST) & (e1.obj = eCONST) THEN
2202
                IF (e.obj = eCONST) & (e1.obj = eCONST) & parser.constexp THEN
2206
                    ARITH.opBoolean(e.value, e1.value, "|")
2203
                    ARITH.opBoolean(e.value, e1.value, "|")
2207
                ELSE
2204
                ELSE
2208
                    e.obj := eEXPR;
2205
                    e.obj := eEXPR;
Line 2214... Line 2211...
2214
            END
2211
            END
2215
        END;
2212
        END;
Line 2216... Line 2213...
2216
 
2213
 
2217
        IF label # -1 THEN
2214
        IF label # -1 THEN
2218
            label1 := IL.NewLabel();
2215
            label1 := IL.NewLabel();
2219
            IL.AddJmpCmd(IL.opJZ, label1);
2216
            IL.Jmp(IL.opJZ, label1);
2220
            IL.SetLabel(label);
2217
            IL.SetLabel(label);
2221
            IL.Const(1);
2218
            IL.Const(1);
2222
            IL.drop;
2219
            IL.drop;
2223
            label := IL.NewLabel();
2220
            label := IL.NewLabel();
2224
            IL.AddJmpCmd(IL.opJMP, label);
2221
            IL.Jmp(IL.opJMP, label);
2225
            IL.SetLabel(label1);
2222
            IL.SetLabel(label1);
2226
            IL.Const(0);
2223
            IL.Const(0);
2227
            IL.SetLabel(label);
2224
            IL.SetLabel(label);
2228
            IL.AddCmd0(IL.opOR)
2225
            IL.AddCmd0(IL.opOR)
Line 2369... Line 2366...
2369
                        IL.AddCmd0(IL.opEQ + cmp)
2366
                        IL.AddCmd0(IL.opEQ + cmp)
2370
                    END
2367
                    END
2371
                END
2368
                END
Line 2372... Line 2369...
2372
 
2369
 
2373
            ELSIF isStringW1(e) & isCharW(e1) THEN
2370
            ELSIF isStringW1(e) & isCharW(e1) THEN
Line 2374... Line 2371...
2374
                IL.AddCmd(IL.opEQC + cmp, StrToWChar(e.value.string(SCAN.IDENT).s))
2371
                IL.AddCmd(IL.opEQC + cmp, StrToWChar(e.value.string(SCAN.STRING).s))
2375
 
2372
 
Line 2376... Line 2373...
2376
            ELSIF isStringW1(e1) & isCharW(e) THEN
2373
            ELSIF isStringW1(e1) & isCharW(e) THEN
2377
                IL.AddCmd(IL.opEQC + cmp, StrToWChar(e1.value.string(SCAN.IDENT).s))
2374
                IL.AddCmd(IL.opEQC + cmp, StrToWChar(e1.value.string(SCAN.STRING).s))
2378
 
2375
 
2379
            ELSIF isBoolean(e) & isBoolean(e1) THEN
2376
            ELSIF isBoolean(e) & isBoolean(e1) THEN
Line 2486... Line 2483...
2486
                        IL.AddCmd0(IL.opEQ + cmp)
2483
                        IL.AddCmd0(IL.opEQ + cmp)
2487
                    END
2484
                    END
2488
                END
2485
                END
Line 2489... Line 2486...
2489
 
2486
 
2490
            ELSIF isStringW1(e) & isCharW(e1) THEN
2487
            ELSIF isStringW1(e) & isCharW(e1) THEN
Line 2491... Line 2488...
2491
                IL.AddCmd(IL.opEQC + invcmpcode(op), StrToWChar(e.value.string(SCAN.IDENT).s))
2488
                IL.AddCmd(IL.opEQC + invcmpcode(op), StrToWChar(e.value.string(SCAN.STRING).s))
2492
 
2489
 
Line 2493... Line 2490...
2493
            ELSIF isStringW1(e1) & isCharW(e) THEN
2490
            ELSIF isStringW1(e1) & isCharW(e) THEN
2494
                IL.AddCmd(IL.opEQC + cmp, StrToWChar(e1.value.string(SCAN.IDENT).s))
2491
                IL.AddCmd(IL.opEQC + cmp, StrToWChar(e1.value.string(SCAN.STRING).s))
2495
 
2492
 
2496
            ELSIF isReal(e) & isReal(e1) THEN
2493
            ELSIF isReal(e) & isReal(e1) THEN
Line 2639... Line 2636...
2639
 
2636
 
2640
BEGIN
2637
BEGIN
Line 2641... Line 2638...
2641
    L := IL.NewLabel();
2638
    L := IL.NewLabel();
2642
 
2639
 
2643
    IF ~_if THEN
2640
    IF ~_if THEN
2644
        IL.AddCmd0(IL.opLOOP);
2641
        IL.AddCmd(IL.opNOP, IL.begin_loop);
Line 2645... Line 2642...
2645
        IL.SetLabel(L)
2642
        IL.SetLabel(L)
2646
    END;
2643
    END;
Line 2653... Line 2650...
2653
        expression(parser, e);
2650
        expression(parser, e);
2654
        PARS.check(isBoolean(e), pos, 72);
2651
        PARS.check(isBoolean(e), pos, 72);
Line 2655... Line 2652...
2655
 
2652
 
2656
        IF e.obj = eCONST THEN
2653
        IF e.obj = eCONST THEN
2657
            IF ~ARITH.getBool(e.value) THEN
2654
            IF ~ARITH.getBool(e.value) THEN
2658
                IL.AddJmpCmd(IL.opJMP, label)
2655
                IL.Jmp(IL.opJMP, label)
2659
            END
2656
            END
2660
        ELSE
2657
        ELSE
2661
            IL.AndOrOpt(label)
2658
            IL.AndOrOpt(label)
Line 2669... Line 2666...
2669
 
2666
 
2670
        PARS.Next(parser);
2667
        PARS.Next(parser);
Line 2671... Line 2668...
2671
        parser.StatSeq(parser);
2668
        parser.StatSeq(parser);
2672
 
2669
 
2673
        IF ~_if OR (parser.sym # SCAN.lxEND) THEN
2670
        IF ~_if OR (parser.sym # SCAN.lxEND) THEN
2674
            IL.AddJmpCmd(IL.opJMP, L)
2671
            IL.Jmp(IL.opJMP, L)
Line 2675... Line 2672...
2675
        END;
2672
        END;
Line 2682... Line 2679...
2682
            PARS.Next(parser);
2679
            PARS.Next(parser);
2683
            parser.StatSeq(parser)
2680
            parser.StatSeq(parser)
2684
        END;
2681
        END;
2685
        IL.SetLabel(L)
2682
        IL.SetLabel(L)
2686
    ELSE
2683
    ELSE
2687
        IL.AddCmd0(IL.opENDLOOP)
2684
        IL.AddCmd(IL.opNOP, IL.end_loop)
2688
    END;
2685
    END;
Line 2689... Line 2686...
2689
 
2686
 
Line 2690... Line 2687...
2690
    PARS.checklex(parser, SCAN.lxEND);
2687
    PARS.checklex(parser, SCAN.lxEND);
Line 2699... Line 2696...
2699
    pos:   PARS.POSITION;
2696
    pos:   PARS.POSITION;
2700
    label: INTEGER;
2697
    label: INTEGER;
2701
    L:     IL.COMMAND;
2698
    L:     IL.COMMAND;
Line 2702... Line 2699...
2702
 
2699
 
2703
BEGIN
2700
BEGIN
Line 2704... Line 2701...
2704
    IL.AddCmd0(IL.opLOOP);
2701
    IL.AddCmd(IL.opNOP, IL.begin_loop);
2705
 
2702
 
2706
    label := IL.NewLabel();
2703
    label := IL.NewLabel();
Line 2714... Line 2711...
2714
    expression(parser, e);
2711
    expression(parser, e);
2715
    PARS.check(isBoolean(e), pos, 72);
2712
    PARS.check(isBoolean(e), pos, 72);
Line 2716... Line 2713...
2716
 
2713
 
2717
    IF e.obj = eCONST THEN
2714
    IF e.obj = eCONST THEN
2718
        IF ~ARITH.getBool(e.value) THEN
2715
        IF ~ARITH.getBool(e.value) THEN
2719
            IL.AddJmpCmd(IL.opJMP, label)
2716
            IL.Jmp(IL.opJMP, label)
2720
        END
2717
        END
2721
    ELSE
2718
    ELSE
2722
        IL.AndOrOpt(label);
2719
        IL.AndOrOpt(label);
2723
        L.param1 := label
2720
        L.param1 := label
Line 2724... Line 2721...
2724
    END;
2721
    END;
2725
 
2722
 
Line 2726... Line 2723...
2726
    IL.AddCmd0(IL.opENDLOOP)
2723
    IL.AddCmd(IL.opNOP, IL.end_loop)
2727
END RepeatStatement;
2724
END RepeatStatement;
Line 2795... Line 2792...
2795
            PARS.ConstExpression(parser, value);
2792
            PARS.ConstExpression(parser, value);
2796
            PARS.check(value.typ = ARITH.tCHAR, pos, 99);
2793
            PARS.check(value.typ = ARITH.tCHAR, pos, 99);
2797
            a := ARITH.getInt(value)
2794
            a := ARITH.getInt(value)
2798
        ELSIF isCharW(caseExpr) THEN
2795
        ELSIF isCharW(caseExpr) THEN
2799
            PARS.ConstExpression(parser, value);
2796
            PARS.ConstExpression(parser, value);
2800
            IF (value.typ = ARITH.tSTRING) & (_length(value.string(SCAN.IDENT).s) = 1) & (LENGTH(value.string(SCAN.IDENT).s) > 1) THEN
2797
            IF (value.typ = ARITH.tSTRING) & (_length(value.string(SCAN.STRING).s) = 1) & (LENGTH(value.string(SCAN.STRING).s) > 1) THEN
2801
                ASSERT(ARITH.setInt(value, StrToWChar(value.string(SCAN.IDENT).s)))
2798
                ASSERT(ARITH.setInt(value, StrToWChar(value.string(SCAN.STRING).s)))
2802
            ELSE
2799
            ELSE
2803
                PARS.check(value.typ IN {ARITH.tWCHAR, ARITH.tCHAR}, pos, 99)
2800
                PARS.check(value.typ IN {ARITH.tWCHAR, ARITH.tCHAR}, pos, 99)
2804
            END;
2801
            END;
2805
            a := ARITH.getInt(value)
2802
            a := ARITH.getInt(value)
2806
        ELSIF isInt(caseExpr) THEN
2803
        ELSIF isInt(caseExpr) THEN
Line 2925... Line 2922...
2925
            IF ~isRecPtr(caseExpr) THEN
2922
            IF ~isRecPtr(caseExpr) THEN
2926
                LISTS.push(CaseVariants, NewVariant(variant, last))
2923
                LISTS.push(CaseVariants, NewVariant(variant, last))
2927
            END;
2924
            END;
Line 2928... Line 2925...
2928
 
2925
 
2929
            parser.StatSeq(parser);
2926
            parser.StatSeq(parser);
Line 2930... Line 2927...
2930
            IL.AddJmpCmd(IL.opJMP, _end);
2927
            IL.Jmp(IL.opJMP, _end);
2931
 
2928
 
2932
            IF isRecPtr(caseExpr) THEN
2929
            IF isRecPtr(caseExpr) THEN
2933
                caseExpr.ident._type := t
2930
                caseExpr.ident._type := t
Line 2974... Line 2971...
2974
            IL.setlast(v.cmd);
2971
            IL.setlast(v.cmd);
Line 2975... Line 2972...
2975
 
2972
 
2976
            IL.SetLabel(node.data(CASE_LABEL).self);
2973
            IL.SetLabel(node.data(CASE_LABEL).self);
2977
            IL._case(range.a, range.b, L, R);
2974
            IL._case(range.a, range.b, L, R);
2978
            IF v.processed THEN
2975
            IF v.processed THEN
2979
                IL.AddJmpCmd(IL.opJMP, node.data(CASE_LABEL).variant)
2976
                IL.Jmp(IL.opJMP, node.data(CASE_LABEL).variant)
2980
            END;
2977
            END;
Line 2981... Line 2978...
2981
            v.processed := TRUE;
2978
            v.processed := TRUE;
Line 3008... Line 3005...
3008
        LISTS.push(CaseVariants, NewVariant(0, NIL));
3005
        LISTS.push(CaseVariants, NewVariant(0, NIL));
3009
        _end  := IL.NewLabel();
3006
        _end  := IL.NewLabel();
3010
        _else := IL.NewLabel();
3007
        _else := IL.NewLabel();
3011
        table := IL.NewLabel();
3008
        table := IL.NewLabel();
3012
        IL.AddCmd(IL.opSWITCH, ORD(isRecPtr(e)));
3009
        IL.AddCmd(IL.opSWITCH, ORD(isRecPtr(e)));
3013
        IL.AddJmpCmd(IL.opJMP, table);
3010
        IL.Jmp(IL.opJMP, table);
Line 3014... Line 3011...
3014
 
3011
 
Line 3015... Line 3012...
3015
        tree := NIL;
3012
        tree := NIL;
3016
 
3013
 
Line 3022... Line 3019...
3022
 
3019
 
3023
        IL.SetLabel(_else);
3020
        IL.SetLabel(_else);
3024
        IF parser.sym = SCAN.lxELSE THEN
3021
        IF parser.sym = SCAN.lxELSE THEN
3025
            PARS.Next(parser);
3022
            PARS.Next(parser);
3026
            parser.StatSeq(parser);
3023
            parser.StatSeq(parser);
3027
            IL.AddJmpCmd(IL.opJMP, _end)
3024
            IL.Jmp(IL.opJMP, _end)
3028
        ELSE
3025
        ELSE
3029
            IL.OnError(pos.line, errCASE)
3026
            IL.OnError(pos.line, errCASE)
Line 3030... Line 3027...
3030
        END;
3027
        END;
3031
 
3028
 
Line 3032... Line 3029...
3032
        PARS.checklex(parser, SCAN.lxEND);
3029
        PARS.checklex(parser, SCAN.lxEND);
3033
        PARS.Next(parser);
3030
        PARS.Next(parser);
3034
 
3031
 
3035
        IF isRecPtr(e) THEN
3032
        IF isRecPtr(e) THEN
3036
            IL.SetLabel(table);
3033
            IL.SetLabel(table);
3037
            TableT(tree);
3034
            TableT(tree);
3038
            IL.AddJmpCmd(IL.opJMP, _else)
3035
            IL.Jmp(IL.opJMP, _else)
3039
        ELSE
3036
        ELSE
Line 3092... Line 3089...
3092
    ident:     PROG.IDENT;
3089
    ident:     PROG.IDENT;
3093
    offset:    INTEGER;
3090
    offset:    INTEGER;
3094
    L1, L2:    INTEGER;
3091
    L1, L2:    INTEGER;
Line 3095... Line 3092...
3095
 
3092
 
3096
BEGIN
3093
BEGIN
Line 3097... Line 3094...
3097
    IL.AddCmd0(IL.opLOOP);
3094
    IL.AddCmd(IL.opNOP, IL.begin_loop);
3098
 
3095
 
Line 3099... Line 3096...
3099
    L1 := IL.NewLabel();
3096
    L1 := IL.NewLabel();
Line 3165... Line 3162...
3165
        ELSE
3162
        ELSE
3166
            IL.AddCmd0(IL.opGE)
3163
            IL.AddCmd0(IL.opGE)
3167
        END
3164
        END
3168
    END;
3165
    END;
Line 3169... Line 3166...
3169
 
3166
 
Line 3170... Line 3167...
3170
    IL.AddJmpCmd(IL.opJZ, L2);
3167
    IL.Jmp(IL.opJZ, L2);
3171
 
3168
 
3172
    PARS.checklex(parser, SCAN.lxDO);
3169
    PARS.checklex(parser, SCAN.lxDO);
Line 3179... Line 3176...
3179
        IL.AddCmd(IL.opLADR, -offset)
3176
        IL.AddCmd(IL.opLADR, -offset)
3180
    END;
3177
    END;
Line 3181... Line 3178...
3181
 
3178
 
Line 3182... Line 3179...
3182
    IL.AddCmd(IL.opINCC, st);
3179
    IL.AddCmd(IL.opINCC, st);
Line 3183... Line 3180...
3183
 
3180
 
3184
    IL.AddJmpCmd(IL.opJMP, L1);
3181
    IL.Jmp(IL.opJMP, L1);
Line 3185... Line 3182...
3185
 
3182
 
Line 3186... Line 3183...
3186
    PARS.checklex(parser, SCAN.lxEND);
3183
    PARS.checklex(parser, SCAN.lxEND);
3187
    PARS.Next(parser);
-
 
3188
 
3184
    PARS.Next(parser);
Line 3189... Line 3185...
3189
    IL.SetLabel(L2);
3185
 
3190
 
3186
    IL.SetLabel(L2);
Line 3258... Line 3254...
3258
PROCEDURE setrtl;
3254
PROCEDURE setrtl;
3259
VAR
3255
VAR
3260
    rtl: PROG.UNIT;
3256
    rtl: PROG.UNIT;
Line 3261... Line 3257...
3261
 
3257
 
3262
 
3258
 
3263
    PROCEDURE getproc (rtl: PROG.UNIT; name: SCAN.LEXSTR; idx: INTEGER);
3259
    PROCEDURE getproc (rtl: PROG.UNIT; name: SCAN.IDSTR; idx: INTEGER);
-
 
3260
    VAR
Line 3264... Line 3261...
3264
    VAR
3261
        id: PROG.IDENT;
-
 
3262
        ident: SCAN.IDENT;
3265
        id: PROG.IDENT;
3263
 
Line 3266... Line 3264...
3266
 
3264
    BEGIN
3267
    BEGIN
3265
        SCAN.setIdent(ident, name);
3268
        id := PROG.getIdent(rtl, SCAN.enterid(name), FALSE);
3266
        id := PROG.getIdent(rtl, ident, FALSE);
3269
 
3267
 
Line 3305... Line 3303...
3305
        getproc(rtl, "_exit",     IL._exit);
3303
        getproc(rtl, "_exit",     IL._exit);
3306
        getproc(rtl, "_dispose",  IL._dispose);
3304
        getproc(rtl, "_dispose",  IL._dispose);
3307
        getproc(rtl, "_isrec",    IL._isrec);
3305
        getproc(rtl, "_isrec",    IL._isrec);
3308
        getproc(rtl, "_dllentry", IL._dllentry);
3306
        getproc(rtl, "_dllentry", IL._dllentry);
3309
        getproc(rtl, "_sofinit",  IL._sofinit)
3307
        getproc(rtl, "_sofinit",  IL._sofinit)
3310
    ELSIF CPU IN {TARGETS.cpuTHUMB, TARGETS.cpuRVM32I} THEN
3308
    ELSIF CPU IN {TARGETS.cpuTHUMB, TARGETS.cpuRVM32I, TARGETS.cpuRVM64I} THEN
3311
        getproc(rtl, "_fmul",  IL._fmul);
3309
        getproc(rtl, "_fmul",  IL._fmul);
3312
        getproc(rtl, "_fdiv",  IL._fdiv);
3310
        getproc(rtl, "_fdiv",  IL._fdiv);
3313
        getproc(rtl, "_fdivi", IL._fdivi);
3311
        getproc(rtl, "_fdivi", IL._fdivi);
3314
        getproc(rtl, "_fadd",  IL._fadd);
3312
        getproc(rtl, "_fadd",  IL._fadd);
3315
        getproc(rtl, "_fsub",  IL._fsub);
3313
        getproc(rtl, "_fsub",  IL._fsub);
Line 3317... Line 3315...
3317
        getproc(rtl, "_fcmp",  IL._fcmp);
3315
        getproc(rtl, "_fcmp",  IL._fcmp);
3318
        getproc(rtl, "_floor", IL._floor);
3316
        getproc(rtl, "_floor", IL._floor);
3319
        getproc(rtl, "_flt",   IL._flt);
3317
        getproc(rtl, "_flt",   IL._flt);
3320
        getproc(rtl, "_pack",  IL._pack);
3318
        getproc(rtl, "_pack",  IL._pack);
3321
        getproc(rtl, "_unpk",  IL._unpk);
3319
        getproc(rtl, "_unpk",  IL._unpk);
3322
        IF CPU = TARGETS.cpuRVM32I THEN
3320
        IF CPU IN {TARGETS.cpuRVM32I, TARGETS.cpuRVM64I} THEN
3323
            getproc(rtl, "_error", IL._error)
3321
            getproc(rtl, "_error", IL._error)
3324
        END
3322
        END
3325
    END
3323
    END
Line 3326... Line 3324...
3326
 
3324
 
Line 3353... Line 3351...
3353
 
3351
 
Line 3354... Line 3352...
3354
    IL.init(CPU);
3352
    IL.init(CPU);
3355
 
3353
 
3356
    IF TARGETS.RTL THEN
3354
    IF TARGETS.RTL THEN
3357
        parser := PARS.create(path, lib_path, StatSeq, expression, designator, chkreturn);
3355
        parser := PARS.create(path, lib_path, StatSeq, expression, designator, chkreturn);
3358
        IF parser.open(parser, UTILS.RTL_NAME) THEN
3356
        IF parser.open(parser, UTILS.RTL_NAME, UTILS.FILE_EXT) THEN
3359
            parser.parse(parser);
3357
            parser.parse(parser);
3360
            PARS.destroy(parser)
3358
            PARS.destroy(parser)
3361
        ELSE
3359
        ELSE
3362
            PARS.destroy(parser);
3360
            PARS.destroy(parser);
3363
            parser := PARS.create(lib_path, lib_path, StatSeq, expression, designator, chkreturn);
3361
            parser := PARS.create(lib_path, lib_path, StatSeq, expression, designator, chkreturn);
3364
            IF parser.open(parser, UTILS.RTL_NAME) THEN
3362
            IF parser.open(parser, UTILS.RTL_NAME, UTILS.FILE_EXT) THEN
3365
                parser.parse(parser);
3363
                parser.parse(parser);
3366
                PARS.destroy(parser)
3364
                PARS.destroy(parser)
3367
            ELSE
3365
            ELSE
Line 3371... Line 3369...
3371
    END;
3369
    END;
Line 3372... Line 3370...
3372
 
3370
 
3373
    parser := PARS.create(path, lib_path, StatSeq, expression, designator, chkreturn);
3371
    parser := PARS.create(path, lib_path, StatSeq, expression, designator, chkreturn);
Line 3374... Line 3372...
3374
    parser.main := TRUE;
3372
    parser.main := TRUE;
3375
 
3373
 
3376
    IF parser.open(parser, modname) THEN
3374
    IF parser.open(parser, modname, UTILS.FILE_EXT) THEN
3377
        parser.parse(parser)
3375
        parser.parse(parser)
3378
    ELSE
3376
    ELSE
Line 3396... Line 3394...
3396
    CASE CPU OF
3394
    CASE CPU OF
3397
    |TARGETS.cpuAMD64:   AMD64.CodeGen(outname, target, options)
3395
    |TARGETS.cpuAMD64:   AMD64.CodeGen(outname, target, options)
3398
    |TARGETS.cpuX86:       X86.CodeGen(outname, target, options)
3396
    |TARGETS.cpuX86:       X86.CodeGen(outname, target, options)
3399
    |TARGETS.cpuMSP430: MSP430.CodeGen(outname, target, options)
3397
    |TARGETS.cpuMSP430: MSP430.CodeGen(outname, target, options)
3400
    |TARGETS.cpuTHUMB:   THUMB.CodeGen(outname, target, options)
3398
    |TARGETS.cpuTHUMB:   THUMB.CodeGen(outname, target, options)
-
 
3399
    |TARGETS.cpuRVM32I,
3401
    |TARGETS.cpuRVM32I: RVM32I.CodeGen(outname, target, options)
3400
     TARGETS.cpuRVM64I:  RVMxI.CodeGen(outname, target, options)
3402
    END
3401
    END
Line 3403... Line 3402...
3403
 
3402