Subversion Repositories Kolibri OS

Rev

Rev 7693 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 7693 Rev 7696
1
(*
1
(*
2
    BSD 2-Clause License
2
    BSD 2-Clause License
3
 
3
 
4
    Copyright (c) 2018, 2019, Anton Krotov
4
    Copyright (c) 2018-2019, Anton Krotov
5
    All rights reserved.
5
    All rights reserved.
6
*)
6
*)
7
 
7
 
8
MODULE Compiler;
8
MODULE Compiler;
9
 
9
 
10
IMPORT ST := STATEMENTS, PARS, UTILS, PATHS, PROG, C := CONSOLE, ERRORS, STRINGS, mConst := CONSTANTS, WRITER, MSP430;
10
IMPORT ST := STATEMENTS, PARS, UTILS, PATHS, PROG, C := CONSOLE, ERRORS, STRINGS, mConst := CONSTANTS, WRITER, MSP430;
11
 
11
 
12
 
12
 
13
PROCEDURE Target (s: ARRAY OF CHAR): INTEGER;
13
PROCEDURE Target (s: ARRAY OF CHAR): INTEGER;
14
VAR
14
VAR
15
    res: INTEGER;
15
    res: INTEGER;
16
 
16
 
17
BEGIN
17
BEGIN
18
    IF s = mConst.Target_sConsole THEN
18
    IF s = mConst.Target_sConsole THEN
19
        res := mConst.Target_iConsole
19
        res := mConst.Target_iConsole
20
    ELSIF s = mConst.Target_sGUI THEN
20
    ELSIF s = mConst.Target_sGUI THEN
21
        res := mConst.Target_iGUI
21
        res := mConst.Target_iGUI
22
    ELSIF s = mConst.Target_sDLL THEN
22
    ELSIF s = mConst.Target_sDLL THEN
23
        res := mConst.Target_iDLL
23
        res := mConst.Target_iDLL
24
    ELSIF s = mConst.Target_sKolibri THEN
24
    ELSIF s = mConst.Target_sKolibri THEN
25
        res := mConst.Target_iKolibri
25
        res := mConst.Target_iKolibri
26
    ELSIF s = mConst.Target_sObject THEN
26
    ELSIF s = mConst.Target_sObject THEN
27
        res := mConst.Target_iObject
27
        res := mConst.Target_iObject
28
    ELSIF s = mConst.Target_sConsole64 THEN
28
    ELSIF s = mConst.Target_sConsole64 THEN
29
        res := mConst.Target_iConsole64
29
        res := mConst.Target_iConsole64
30
    ELSIF s = mConst.Target_sGUI64 THEN
30
    ELSIF s = mConst.Target_sGUI64 THEN
31
        res := mConst.Target_iGUI64
31
        res := mConst.Target_iGUI64
32
    ELSIF s = mConst.Target_sDLL64 THEN
32
    ELSIF s = mConst.Target_sDLL64 THEN
33
        res := mConst.Target_iDLL64
33
        res := mConst.Target_iDLL64
34
    ELSIF s = mConst.Target_sELF32 THEN
34
    ELSIF s = mConst.Target_sELF32 THEN
35
        res := mConst.Target_iELF32
35
        res := mConst.Target_iELF32
36
    ELSIF s = mConst.Target_sELFSO32 THEN
36
    ELSIF s = mConst.Target_sELFSO32 THEN
37
        res := mConst.Target_iELFSO32
37
        res := mConst.Target_iELFSO32
38
    ELSIF s = mConst.Target_sELF64 THEN
38
    ELSIF s = mConst.Target_sELF64 THEN
39
        res := mConst.Target_iELF64
39
        res := mConst.Target_iELF64
40
    ELSIF s = mConst.Target_sELFSO64 THEN
40
    ELSIF s = mConst.Target_sELFSO64 THEN
41
        res := mConst.Target_iELFSO64
41
        res := mConst.Target_iELFSO64
42
    ELSIF s = mConst.Target_sMSP430 THEN
42
    ELSIF s = mConst.Target_sMSP430 THEN
43
        res := mConst.Target_iMSP430
43
        res := mConst.Target_iMSP430
44
    ELSE
44
    ELSE
45
        res := 0
45
        res := 0
46
    END
46
    END
47
 
47
 
48
    RETURN res
48
    RETURN res
49
END Target;
49
END Target;
50
 
50
 
51
 
51
 
52
PROCEDURE keys (VAR options: PROG.OPTIONS);
52
PROCEDURE keys (VAR options: PROG.OPTIONS; VAR out: PARS.PATH);
53
VAR
53
VAR
54
    param: PARS.PATH;
54
    param: PARS.PATH;
55
    i, j:  INTEGER;
55
    i, j:  INTEGER;
56
    end:   BOOLEAN;
56
    end:   BOOLEAN;
57
    value: INTEGER;
57
    value: INTEGER;
58
    minor,
58
    minor,
59
    major: INTEGER;
59
    major: INTEGER;
60
    checking: SET;
60
    checking: SET;
61
 
61
 
62
BEGIN
62
BEGIN
-
 
63
    out := "";
63
    checking := options.checking;
64
    checking := options.checking;
64
    end := FALSE;
65
    end := FALSE;
65
    i := 4;
66
    i := 3;
66
    REPEAT
67
    REPEAT
67
        UTILS.GetArg(i, param);
68
        UTILS.GetArg(i, param);
68
 
69
 
69
        IF param = "-stk" THEN
70
        IF param = "-stk" THEN
70
            INC(i);
71
            INC(i);
71
            UTILS.GetArg(i, param);
72
            UTILS.GetArg(i, param);
72
            IF STRINGS.StrToInt(param, value) & (1 <= value) & (value <= 32) THEN
73
            IF STRINGS.StrToInt(param, value) & (1 <= value) & (value <= 32) THEN
73
                options.stack := value
74
                options.stack := value
74
            END;
75
            END;
75
            IF param[0] = "-" THEN
76
            IF param[0] = "-" THEN
76
                DEC(i)
77
                DEC(i)
77
            END
78
            END
78
 
79
 
79
        ELSIF param = "-base" THEN
80
        ELSIF param = "-out" THEN
80
            INC(i);
81
            INC(i);
81
            UTILS.GetArg(i, param);
-
 
82
            IF STRINGS.StrToInt(param, value) THEN
-
 
83
                options.base := ((value DIV 64) * 64) * 1024
-
 
84
            END;
82
            UTILS.GetArg(i, param);
85
            IF param[0] = "-" THEN
83
            IF param[0] = "-" THEN
-
 
84
                DEC(i)
-
 
85
            ELSE
86
                DEC(i)
86
                out := param
87
            END
87
            END
88
 
88
 
89
        ELSIF param = "-ram" THEN
89
        ELSIF param = "-ram" THEN
90
            INC(i);
90
            INC(i);
91
            UTILS.GetArg(i, param);
91
            UTILS.GetArg(i, param);
92
            IF STRINGS.StrToInt(param, value) THEN
92
            IF STRINGS.StrToInt(param, value) THEN
93
                options.ram := value
93
                options.ram := value
94
            END;
94
            END;
95
            IF param[0] = "-" THEN
95
            IF param[0] = "-" THEN
96
                DEC(i)
96
                DEC(i)
97
            END
97
            END
98
 
98
 
99
        ELSIF param = "-rom" THEN
99
        ELSIF param = "-rom" THEN
100
            INC(i);
100
            INC(i);
101
            UTILS.GetArg(i, param);
101
            UTILS.GetArg(i, param);
102
            IF STRINGS.StrToInt(param, value) THEN
102
            IF STRINGS.StrToInt(param, value) THEN
103
                options.rom := value
103
                options.rom := value
104
            END;
104
            END;
105
            IF param[0] = "-" THEN
105
            IF param[0] = "-" THEN
106
                DEC(i)
106
                DEC(i)
107
            END
107
            END
108
 
108
 
109
        ELSIF param = "-nochk" THEN
109
        ELSIF param = "-nochk" THEN
110
            INC(i);
110
            INC(i);
111
            UTILS.GetArg(i, param);
111
            UTILS.GetArg(i, param);
112
 
112
 
113
            IF param[0] = "-" THEN
113
            IF param[0] = "-" THEN
114
                DEC(i)
114
                DEC(i)
115
            ELSE
115
            ELSE
116
                j := 0;
116
                j := 0;
117
                WHILE param[j] # 0X DO
117
                WHILE param[j] # 0X DO
118
 
118
 
119
                    IF    param[j] = "p" THEN
119
                    IF    param[j] = "p" THEN
120
                        EXCL(checking, ST.chkPTR)
120
                        EXCL(checking, ST.chkPTR)
121
                    ELSIF param[j] = "t" THEN
121
                    ELSIF param[j] = "t" THEN
122
                        EXCL(checking, ST.chkGUARD)
122
                        EXCL(checking, ST.chkGUARD)
123
                    ELSIF param[j] = "i" THEN
123
                    ELSIF param[j] = "i" THEN
124
                        EXCL(checking, ST.chkIDX)
124
                        EXCL(checking, ST.chkIDX)
125
                    ELSIF param[j] = "b" THEN
125
                    ELSIF param[j] = "b" THEN
126
                        EXCL(checking, ST.chkBYTE)
126
                        EXCL(checking, ST.chkBYTE)
127
                    ELSIF param[j] = "c" THEN
127
                    ELSIF param[j] = "c" THEN
128
                        EXCL(checking, ST.chkCHR)
128
                        EXCL(checking, ST.chkCHR)
129
                    ELSIF param[j] = "w" THEN
129
                    ELSIF param[j] = "w" THEN
130
                        EXCL(checking, ST.chkWCHR)
130
                        EXCL(checking, ST.chkWCHR)
131
                    ELSIF param[j] = "r" THEN
131
                    ELSIF param[j] = "r" THEN
132
                        EXCL(checking, ST.chkCHR);
132
                        EXCL(checking, ST.chkCHR);
133
                        EXCL(checking, ST.chkWCHR);
133
                        EXCL(checking, ST.chkWCHR);
134
                        EXCL(checking, ST.chkBYTE)
134
                        EXCL(checking, ST.chkBYTE)
135
                    ELSIF param[j] = "a" THEN
135
                    ELSIF param[j] = "a" THEN
136
                        checking := {}
136
                        checking := {}
137
                    END;
137
                    END;
138
 
138
 
139
                    INC(j)
139
                    INC(j)
140
                END;
140
                END;
141
 
141
 
142
            END
142
            END
143
 
143
 
144
        ELSIF param = "-ver" THEN
144
        ELSIF param = "-ver" THEN
145
            INC(i);
145
            INC(i);
146
            UTILS.GetArg(i, param);
146
            UTILS.GetArg(i, param);
147
            IF STRINGS.StrToVer(param, major, minor) THEN
147
            IF STRINGS.StrToVer(param, major, minor) THEN
148
                options.version := major * 65536 + minor
148
                options.version := major * 65536 + minor
149
            END;
149
            END;
150
            IF param[0] = "-" THEN
150
            IF param[0] = "-" THEN
151
                DEC(i)
151
                DEC(i)
152
            END
152
            END
153
 
153
 
154
        ELSIF param = "-pic" THEN
154
        ELSIF param = "-pic" THEN
155
            options.pic := TRUE
155
            options.pic := TRUE
156
 
156
 
157
        ELSIF param = "" THEN
157
        ELSIF param = "" THEN
158
            end := TRUE
158
            end := TRUE
159
 
159
 
160
        ELSE
160
        ELSE
161
            ERRORS.BadParam(param)
161
            ERRORS.BadParam(param)
162
        END;
162
        END;
163
 
163
 
164
        INC(i)
164
        INC(i)
165
    UNTIL end;
165
    UNTIL end;
166
 
166
 
167
    options.checking := checking
167
    options.checking := checking
168
END keys;
168
END keys;
169
 
169
 
170
 
170
 
171
PROCEDURE main;
171
PROCEDURE main;
172
VAR
172
VAR
173
    path:       PARS.PATH;
173
    path:       PARS.PATH;
174
    inname:     PARS.PATH;
174
    inname:     PARS.PATH;
175
    ext:        PARS.PATH;
175
    ext:        PARS.PATH;
176
    app_path:   PARS.PATH;
176
    app_path:   PARS.PATH;
177
    lib_path:   PARS.PATH;
177
    lib_path:   PARS.PATH;
178
    modname:    PARS.PATH;
178
    modname:    PARS.PATH;
179
    outname:    PARS.PATH;
179
    outname:    PARS.PATH;
180
    param:      PARS.PATH;
180
    param:      PARS.PATH;
181
    temp:       PARS.PATH;
181
    temp:       PARS.PATH;
182
    target:     INTEGER;
182
    target:     INTEGER;
183
    bit_depth:  INTEGER;
183
    bit_depth:  INTEGER;
184
    time:       INTEGER;
184
    time:       INTEGER;
185
    options:    PROG.OPTIONS;
185
    options:    PROG.OPTIONS;
186
 
186
 
187
BEGIN
187
BEGIN
188
    options.stack := 2;
188
    options.stack := 2;
189
    options.version := 65536;
189
    options.version := 65536;
190
    options.pic := FALSE;
190
    options.pic := FALSE;
191
    options.checking := ST.chkALL;
191
    options.checking := ST.chkALL;
192
 
192
 
193
    PATHS.GetCurrentDirectory(app_path);
193
    PATHS.GetCurrentDirectory(app_path);
194
    lib_path := app_path;
194
    lib_path := app_path;
195
 
195
 
196
    UTILS.GetArg(1, inname);
196
    UTILS.GetArg(1, inname);
197
 
197
 
198
    C.Ln;
198
    C.Ln;
199
    C.String("Akron Oberon Compiler v"); C.Int(mConst.vMajor); C.String("."); C.Int2(mConst.vMinor);
199
    C.String("Akron Oberon Compiler v"); C.Int(mConst.vMajor); C.String("."); C.Int2(mConst.vMinor);
200
        C.String(" ("); C.Int(UTILS.bit_depth); C.StringLn("-bit)");
200
        C.String(" ("); C.Int(UTILS.bit_depth); C.StringLn("-bit)");
201
    C.StringLn("Copyright (c) 2018-2019, Anton Krotov");
201
    C.StringLn("Copyright (c) 2018-2019, Anton Krotov");
202
 
202
 
203
    IF inname = "" THEN
203
    IF inname = "" THEN
204
        C.Ln;
204
        C.Ln;
205
        C.StringLn("Usage: Compiler 
[optional settings]"); C.Ln;
205
        C.StringLn("Usage: Compiler 
[optional settings]"); C.Ln;
206
        IF UTILS.bit_depth = 64 THEN
206
        IF UTILS.bit_depth = 64 THEN
207
            C.StringLn('target = console | gui | dll | console64 | gui64 | dll64 | kos | obj | elfexe | elfso | elfexe64 | elfso64 | msp430'); C.Ln;
207
            C.StringLn('target = console | gui | dll | console64 | gui64 | dll64 | kos | obj | elfexe | elfso | elfexe64 | elfso64 | msp430'); C.Ln;
208
        ELSIF UTILS.bit_depth = 32 THEN
208
        ELSIF UTILS.bit_depth = 32 THEN
209
            C.StringLn('target = console | gui | dll | kos | obj | elfexe | elfso | msp430'); C.Ln;
209
            C.StringLn('target = console | gui | dll | kos | obj | elfexe | elfso | msp430'); C.Ln;
210
        END;
210
        END;
211
        C.StringLn("optional settings:"); C.Ln;
211
        C.StringLn("optional settings:"); C.Ln;
-
 
212
        C.StringLn("  -out        output"); C.Ln;
212
        C.StringLn("  -stk             set size of stack in megabytes"); C.Ln;
213
        C.StringLn("  -stk             set size of stack in megabytes"); C.Ln;
213
        C.StringLn("  -base 
set base address of image in kilobytes"); C.Ln;
-
 
214
        C.StringLn('  -ver      set version of program'); C.Ln;
-
 
215
        C.StringLn('  -nochk <"ptibcwra">    disable runtime checking (pointers, types, indexes,');
214
        C.StringLn('  -nochk <"ptibcwra">    disable runtime checking (pointers, types, indexes,');
216
        C.StringLn('                         BYTE, CHR, WCHR)'); C.Ln;
215
        C.StringLn('                         BYTE, CHR, WCHR)'); C.Ln;
-
 
216
        C.StringLn("  -ver      set version of program ('obj' target)"); C.Ln;
217
        C.StringLn("  -ram             set size of RAM in bytes (MSP430)"); C.Ln;
217
        C.StringLn("  -ram             set size of RAM in bytes ('msp430' target)"); C.Ln;
218
        C.StringLn("  -rom             set size of ROM in bytes (MSP430)"); C.Ln;
218
        C.StringLn("  -rom             set size of ROM in bytes ('msp430' target)"); C.Ln;
219
        UTILS.Exit(0)
219
        UTILS.Exit(0)
220
    END;
220
    END;
221
 
221
 
222
    PATHS.split(inname, path, modname, ext);
222
    PATHS.split(inname, path, modname, ext);
223
 
223
 
224
    IF ext # mConst.FILE_EXT THEN
224
    IF ext # mConst.FILE_EXT THEN
225
        ERRORS.Error(207)
225
        ERRORS.Error(207)
226
    END;
226
    END;
227
 
227
 
228
    IF PATHS.isRelative(path) THEN
228
    IF PATHS.isRelative(path) THEN
229
        PATHS.RelPath(app_path, path, temp);
229
        PATHS.RelPath(app_path, path, temp);
230
        path := temp
230
        path := temp
231
    END;
231
    END;
232
 
-
 
233
    UTILS.GetArg(2, outname);
-
 
234
    IF outname = "" THEN
-
 
235
        ERRORS.Error(205)
-
 
236
    END;
-
 
237
    IF PATHS.isRelative(outname) THEN
-
 
238
        PATHS.RelPath(app_path, outname, temp);
-
 
239
        outname := temp
-
 
240
    END;
-
 
241
 
232
 
242
    UTILS.GetArg(3, param);
233
    UTILS.GetArg(2, param);
243
    IF param = "" THEN
234
    IF param = "" THEN
244
        ERRORS.Error(205)
235
        ERRORS.Error(205)
245
    END;
236
    END;
246
 
237
 
247
    target := Target(param);
238
    target := Target(param);
248
 
239
 
249
    IF target = 0 THEN
240
    IF target = 0 THEN
250
        ERRORS.Error(206)
241
        ERRORS.Error(206)
251
    END;
242
    END;
252
 
243
 
253
    CASE target OF
244
    CASE target OF
254
    |mConst.Target_iConsole64, mConst.Target_iGUI64, mConst.Target_iDLL64, mConst.Target_iELF64, mConst.Target_iELFSO64:
245
    |mConst.Target_iConsole64, mConst.Target_iGUI64, mConst.Target_iDLL64, mConst.Target_iELF64, mConst.Target_iELFSO64:
255
        bit_depth := 64
246
        bit_depth := 64
256
    |mConst.Target_iConsole, mConst.Target_iGUI, mConst.Target_iDLL,
247
    |mConst.Target_iConsole, mConst.Target_iGUI, mConst.Target_iDLL,
257
     mConst.Target_iKolibri, mConst.Target_iObject, mConst.Target_iELF32, mConst.Target_iELFSO32:
248
     mConst.Target_iKolibri, mConst.Target_iObject, mConst.Target_iELF32, mConst.Target_iELFSO32:
258
        bit_depth := 32
249
        bit_depth := 32
259
    |mConst.Target_iMSP430:
250
    |mConst.Target_iMSP430:
260
        bit_depth := 16;
251
        bit_depth := 16;
261
        options.ram := MSP430.minRAM;
252
        options.ram := MSP430.minRAM;
262
        options.rom := MSP430.minROM
253
        options.rom := MSP430.minROM
263
    END;
254
    END;
264
 
255
 
265
    IF UTILS.bit_depth < bit_depth THEN
256
    IF UTILS.bit_depth < bit_depth THEN
266
        ERRORS.Error(206)
257
        ERRORS.Error(206)
267
    END;
258
    END;
268
 
259
 
269
    STRINGS.append(lib_path, "lib");
260
    STRINGS.append(lib_path, "lib");
270
    STRINGS.append(lib_path, UTILS.slash);
261
    STRINGS.append(lib_path, UTILS.slash);
271
 
262
 
272
    CASE target OF
263
    CASE target OF
273
    |mConst.Target_iConsole, mConst.Target_iGUI, mConst.Target_iDLL:
264
    |mConst.Target_iConsole, mConst.Target_iGUI, mConst.Target_iDLL:
274
        IF target = mConst.Target_iDLL THEN
-
 
275
            options.base := 10000000H
-
 
276
        ELSE
-
 
277
            options.base := 400000H
-
 
278
        END;
-
 
279
        STRINGS.append(lib_path, "Windows32")
265
        STRINGS.append(lib_path, "Windows32")
280
 
266
 
281
    |mConst.Target_iKolibri, mConst.Target_iObject:
267
    |mConst.Target_iKolibri, mConst.Target_iObject:
282
        STRINGS.append(lib_path, "KolibriOS")
268
        STRINGS.append(lib_path, "KolibriOS")
283
 
269
 
284
    |mConst.Target_iELF32, mConst.Target_iELFSO32:
270
    |mConst.Target_iELF32, mConst.Target_iELFSO32:
285
        STRINGS.append(lib_path, "Linux32")
271
        STRINGS.append(lib_path, "Linux32")
286
 
272
 
287
    |mConst.Target_iELF64, mConst.Target_iELFSO64:
273
    |mConst.Target_iELF64, mConst.Target_iELFSO64:
288
        STRINGS.append(lib_path, "Linux64")
274
        STRINGS.append(lib_path, "Linux64")
289
 
275
 
290
    |mConst.Target_iConsole64, mConst.Target_iGUI64, mConst.Target_iDLL64:
276
    |mConst.Target_iConsole64, mConst.Target_iGUI64, mConst.Target_iDLL64:
291
        STRINGS.append(lib_path, "Windows64")
277
        STRINGS.append(lib_path, "Windows64")
292
 
278
 
293
    |mConst.Target_iMSP430:
279
    |mConst.Target_iMSP430:
294
        STRINGS.append(lib_path, "MSP430")
280
        STRINGS.append(lib_path, "MSP430")
295
 
281
 
296
    END;
282
    END;
297
 
283
 
298
    STRINGS.append(lib_path, UTILS.slash);
284
    STRINGS.append(lib_path, UTILS.slash);
299
 
285
 
-
 
286
    keys(options, outname);
-
 
287
    IF outname = "" THEN
-
 
288
        outname := path;
-
 
289
        STRINGS.append(outname, modname);
-
 
290
        CASE target OF
-
 
291
        |mConst.Target_iConsole, mConst.Target_iGUI, mConst.Target_iConsole64, mConst.Target_iGUI64:
-
 
292
            STRINGS.append(outname, ".exe")
-
 
293
 
-
 
294
        |mConst.Target_iObject:
-
 
295
            STRINGS.append(outname, ".obj")
-
 
296
 
-
 
297
        |mConst.Target_iKolibri, mConst.Target_iELF32, mConst.Target_iELF64:
-
 
298
 
-
 
299
        |mConst.Target_iELFSO32, mConst.Target_iELFSO64:
-
 
300
            STRINGS.append(outname, ".so")
-
 
301
 
-
 
302
        |mConst.Target_iDLL, mConst.Target_iDLL64:
-
 
303
            STRINGS.append(outname, ".dll")
-
 
304
 
-
 
305
        |mConst.Target_iMSP430:
-
 
306
            STRINGS.append(outname, ".hex")
-
 
307
        END
-
 
308
    ELSE
-
 
309
        IF PATHS.isRelative(outname) THEN
-
 
310
            PATHS.RelPath(app_path, outname, temp);
-
 
311
            outname := temp
-
 
312
        END
300
    keys(options);
313
    END;
301
 
314
 
302
    PARS.init(bit_depth, target, options);
315
    PARS.init(bit_depth, target, options);
303
 
316
 
304
    PARS.program.dll := target IN {mConst.Target_iELFSO32, mConst.Target_iELFSO64, mConst.Target_iDLL, mConst.Target_iDLL64, mConst.Target_iObject};
317
    PARS.program.dll := target IN {mConst.Target_iELFSO32, mConst.Target_iELFSO64, mConst.Target_iDLL, mConst.Target_iDLL64, mConst.Target_iObject};
305
    PARS.program.obj := target = mConst.Target_iObject;
318
    PARS.program.obj := target = mConst.Target_iObject;
306
 
319
 
307
    ST.compile(path, lib_path, modname, outname, target, options);
320
    ST.compile(path, lib_path, modname, outname, target, options);
308
 
321
 
309
    time := UTILS.GetTickCount() - UTILS.time;
322
    time := UTILS.GetTickCount() - UTILS.time;
-
 
323
 
310
 
324
    C.Int(PARS.lines); C.String(" lines, ");
311
    C.Int(time DIV 100); C.String("."); C.Int2(time MOD 100); C.String(" sec, ");
325
    C.Int(time DIV 100); C.String("."); C.Int2(time MOD 100); C.String(" sec, ");
312
    C.Int(WRITER.counter); C.StringLn(" bytes");
326
    C.Int(WRITER.counter); C.StringLn(" bytes");
313
 
327
 
314
    UTILS.Exit(0)
328
    UTILS.Exit(0)
315
END main;
329
END main;
316
 
330
 
317
 
331
 
318
BEGIN
332
BEGIN
319
    main
333
    main
320
END Compiler.
-
 
321
334
END Compiler.
-
 
335