Subversion Repositories Kolibri OS

Rev

Rev 9193 | Rev 9413 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
8728 leency 1
(*
2
    Copyright 2021 Anton Krotov
3
 
4
    This file is part of CEdit.
5
 
6
    CEdit is free software: you can redistribute it and/or modify
7
    it under the terms of the GNU General Public License as published by
8
    the Free Software Foundation, either version 3 of the License, or
9
    (at your option) any later version.
10
 
11
    CEdit is distributed in the hope that it will be useful,
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
    GNU General Public License for more details.
15
 
16
    You should have received a copy of the GNU General Public License
17
    along with CEdit. If not, see .
18
*)
19
 
20
MODULE Languages;
21
 
9210 akron1 22
IMPORT Lines, Utils;
8728 leency 23
 
24
 
25
CONST
26
 
9190 akron1 27
    langText* = 0; langC* = 1; langOberon* = 2; langPascal* = 3;
9174 akron1 28
    langFasm* = 4; langLua* = 5; langIni* = 6; langJSON* = 7;
8728 leency 29
 
9174 akron1 30
    csLang = {langC, langOberon, langLua, langIni, langJSON};
9050 leency 31
 
8728 leency 32
TYPE
33
 
34
    tLine = Lines.tLine;
35
 
36
    tKeyWords = RECORD
37
        words: ARRAY 200, 32 OF WCHAR; cnt: INTEGER
38
    END;
39
 
9193 akron1 40
    tDelimiters = ARRAY 256 OF BOOLEAN;
41
 
8728 leency 42
    procGetStr = PROCEDURE (secName, keyName: ARRAY OF CHAR; VAR s: ARRAY OF CHAR);
43
 
44
 
45
VAR
46
 
9193 akron1 47
	KW: ARRAY 8 OF ARRAY 3 OF tKeyWords;
48
	Delim: ARRAY 8 OF tDelimiters;
8728 leency 49
 
9193 akron1 50
    currentLang: INTEGER;
8728 leency 51
 
9210 akron1 52
    fileExt: ARRAY 11 OF RECORD ext: ARRAY 8 OF CHAR; lang: INTEGER END;
9193 akron1 53
 
9210 akron1 54
 
9050 leency 55
PROCEDURE isCS* (lang: INTEGER): BOOLEAN;
56
    RETURN lang IN csLang
57
END isCS;
58
 
59
 
8728 leency 60
PROCEDURE checkKW (s: ARRAY OF WCHAR; KW: tKeyWords): BOOLEAN;
61
VAR
62
    i: INTEGER;
63
BEGIN
64
    i := KW.cnt - 1;
65
    WHILE (i >= 0) & (s # KW.words[i]) DO
66
        DEC(i)
67
    END
68
    RETURN i >= 0
69
END checkKW;
70
 
71
 
72
PROCEDURE isKey* (s: ARRAY OF WCHAR; lang, kwSet: INTEGER): BOOLEAN;
9193 akron1 73
    RETURN checkKW(s, KW[lang][kwSet - 1])
74
END isKey;
75
 
76
 
77
PROCEDURE isDelim* (c: WCHAR): BOOLEAN;
8728 leency 78
VAR
9193 akron1 79
	res: BOOLEAN;
8728 leency 80
BEGIN
9193 akron1 81
	IF c <= 0FFX THEN
82
		res := Delim[currentLang][ORD(c)]
83
	ELSE
84
		res := FALSE
85
	END
86
	RETURN res
87
END isDelim;
8728 leency 88
 
89
 
90
PROCEDURE SkipString* (line: tLine; VAR pos: INTEGER; n: INTEGER);
91
VAR
92
    quot: WCHAR;
93
BEGIN
94
    quot := Lines.getChar(line, pos);
95
    REPEAT
96
        INC(pos)
97
    UNTIL (pos > n) OR (Lines.getChar(line, pos) = quot)
98
END SkipString;
99
 
100
 
101
PROCEDURE C (line: tLine; VAR depth, cond, pos: INTEGER; n: INTEGER);
102
VAR
103
    c: WCHAR;
104
BEGIN
105
    c := Lines.getChar(line, pos);
106
    IF depth = 0 THEN
107
        IF c = "/" THEN
108
            IF cond = 0 THEN
109
                cond := 1
110
            ELSE
111
                cond := 0;
112
                pos := n
113
            END
114
        ELSIF (c = "*") & (cond = 1) THEN
115
            depth := 1;
116
            cond := 0
117
        ELSIF (c = "'") OR (c = '"') THEN
118
            SkipString(line, pos, n);
119
            cond := 0
120
        ELSE
121
            cond := 0
122
        END
123
    ELSIF depth = 1 THEN
124
        IF c = "*" THEN
125
            cond := 1
126
        ELSIF (c = "/") & (cond = 1) THEN
127
            cond := 0;
128
            depth := 0
129
        ELSE
130
            cond := 0
131
        END
132
    END
133
END C;
134
 
135
 
136
PROCEDURE getChar (line: tLine; i: INTEGER): WCHAR;
137
VAR
138
    res: WCHAR;
139
BEGIN
140
    IF i >= line.length THEN
141
        res := 0X
142
    ELSE
143
        res := Lines.getChar(line, i)
144
    END
145
    RETURN res
146
END getChar;
147
 
148
 
149
PROCEDURE LuaLong* (line: tLine; pos: INTEGER): INTEGER;
150
VAR
151
    res: INTEGER;
152
BEGIN
153
    res := -1;
154
    IF getChar(line, pos) = "[" THEN
155
        INC(pos);
156
        WHILE getChar(line, pos) = "=" DO
157
            INC(res);
158
            INC(pos)
159
        END;
160
        IF getChar(line, pos) = "[" THEN
161
            INC(res)
162
        ELSE
163
            res := -1
164
        END
165
    END
166
    RETURN res
167
END LuaLong;
168
 
169
 
170
PROCEDURE Lua (line: tLine; VAR depth, cond, pos: INTEGER; n: INTEGER);
171
VAR
172
    c: WCHAR;
173
    k: INTEGER;
174
BEGIN
175
    c := Lines.getChar(line, pos);
176
    IF depth = 0 THEN
177
        IF c = "-" THEN
178
            IF cond = 0 THEN
179
                cond := 1
180
            ELSE
181
                cond := 0;
182
                k := LuaLong(line, pos + 1);
183
                IF k >= 0 THEN
184
                    depth := k*2 + 1
185
                ELSE
186
                    pos := n
187
                END
188
            END
189
        ELSIF c = "[" THEN
190
            cond := 0;
191
            k := LuaLong(line, pos);
192
            IF k >= 0 THEN
193
                depth := (k + 1)*2
194
            END
195
        ELSIF (c = "'") OR (c = '"') THEN
196
            SkipString(line, pos, n);
197
            cond := 0
198
        ELSE
199
            cond := 0
200
        END
201
    ELSIF depth > 0 THEN
202
        IF (cond = 0) & (c = "]") THEN
203
            cond := 1
204
        ELSIF (cond >= 1) & (c = "=") THEN
205
            INC(cond)
206
        ELSIF (cond >= 1) & (c = "]") & (cond*2 - depth MOD 2 = depth) THEN
207
            depth := 0;
208
            cond := 0
209
        ELSE
210
            cond := 0
211
        END
212
    END
213
END Lua;
214
 
215
 
216
PROCEDURE Pascal (line: tLine; VAR depth, cond, pos: INTEGER; n: INTEGER);
217
VAR
218
    c: WCHAR;
219
BEGIN
220
    c := Lines.getChar(line, pos);
221
    IF depth = 0 THEN
222
        IF c = "(" THEN
223
            cond := 1
224
        ELSIF c = "/" THEN
225
            IF cond = 2 THEN
226
                cond := 0;
227
                pos := n
228
            ELSE
229
                cond := 2
230
            END
231
        ELSIF (c = "*") & (cond = 1) THEN
232
            depth := 2;
233
            cond := 0
234
        ELSIF c = "'" THEN
235
            SkipString(line, pos, n);
236
            cond := 0
237
        ELSIF c = "{" THEN
238
            IF Lines.getChar(line, pos + 1) = "$" THEN
239
                depth := 3
240
            ELSE
241
                depth := 1
242
            END;
243
            cond := 0
244
        ELSE
245
            cond := 0
246
        END
247
    ELSIF depth IN {1, 3} THEN
248
        IF c = "}" THEN
249
            depth := 0
250
        END
251
    ELSIF depth = 2 THEN
252
        IF c = "*" THEN
253
            cond := 1
254
        ELSIF (c = ")") & (cond = 1) THEN
255
            depth := 0;
256
            cond := 0
257
        ELSE
258
            cond := 0
259
        END
260
    END
261
END Pascal;
262
 
263
 
264
PROCEDURE Oberon (line: tLine; VAR depth, cond, pos: INTEGER; n: INTEGER);
265
VAR
266
    c: WCHAR;
267
BEGIN
268
    c := Lines.getChar(line, pos);
269
    IF (depth = 0) & (c = "/") THEN
270
        IF cond = 3 THEN
271
            cond := 0;
272
            pos := n
273
        ELSE
274
            cond := 3
275
        END
276
    ELSIF (depth = 0) & ((c = "'") OR (c = '"')) THEN
277
        SkipString(line, pos, n);
278
        cond := 0
279
    ELSIF c = "(" THEN
280
        cond := 1
281
    ELSIF c = "*" THEN
282
        IF cond = 1 THEN
283
            INC(depth);
284
            cond := 0
285
        ELSE
286
            cond := 2
287
        END
288
    ELSIF c = ")" THEN
289
        IF cond = 2 THEN
290
            IF depth > 0 THEN
291
                DEC(depth)
292
            END
293
        END;
294
        cond := 0
295
    ELSE
296
        cond := 0
297
    END;
298
END Oberon;
299
 
300
 
301
PROCEDURE Ini (line: tLine; VAR depth, cond, pos: INTEGER; n: INTEGER);
302
VAR
303
    c: WCHAR;
304
BEGIN
305
    cond := 0;
306
    c := Lines.getChar(line, pos);
307
    IF depth = 0 THEN
308
        IF c = ";" THEN
309
            pos := n
310
        ELSIF c = '"' THEN
311
            SkipString(line, pos, n)
312
        ELSIF c = "[" THEN
313
            depth := 1
314
        END
315
    ELSIF depth = 1 THEN
316
        IF c = "]" THEN
317
            depth := 0
318
        END
319
    END
320
END Ini;
321
 
322
 
323
PROCEDURE comments* (line: tLine; VAR depth, cond, pos: INTEGER; n: INTEGER; lang: INTEGER);
324
BEGIN
325
    CASE lang OF
9190 akron1 326
    |langText:
8728 leency 327
    |langFasm:
9174 akron1 328
    |langC,
329
     langJSON:    C(line, depth, cond, pos, n)
8728 leency 330
    |langOberon:  Oberon(line, depth, cond, pos, n)
331
    |langPascal:  Pascal(line, depth, cond, pos, n)
332
    |langLua:     Lua(line, depth, cond, pos, n)
333
    |langIni:     Ini(line, depth, cond, pos, n)
334
    END
335
END comments;
336
 
337
 
8762 leency 338
PROCEDURE EnterKW (s: ARRAY OF CHAR; VAR KW: tKeyWords; CPrep: BOOLEAN);
8728 leency 339
CONST
340
    SPACE = 20X; CR = 0DX; LF = 0AX; TAB = 9X; COMMA = ",";
341
VAR
342
    i, j, k: INTEGER;
343
 
344
    PROCEDURE delim (c: CHAR): BOOLEAN;
345
        RETURN (c = COMMA) OR (c = SPACE) OR (c = CR) OR (c = LF) OR (c = TAB)
346
    END delim;
347
 
348
BEGIN
349
    k := KW.cnt;
350
    i := 0;
351
    REPEAT
8762 leency 352
        KW.words[k, 0] := "#";
353
        j := ORD(CPrep);
8728 leency 354
        WHILE (s[i] # 0X) & ~delim(s[i]) DO
355
            KW.words[k, j] := WCHR(ORD(s[i]));
356
            INC(i);
357
            INC(j)
358
        END;
359
        KW.words[k, j] := 0X;
360
        INC(k);
361
        WHILE delim(s[i]) DO
362
            INC(i)
363
        END
364
    UNTIL s[i] = 0X;
365
    KW.cnt := k
366
END EnterKW;
367
 
368
 
9193 akron1 369
PROCEDURE loadKW (VAR KW: ARRAY OF tKeyWords; VAR delim: tDelimiters; getStr: procGetStr; lang: ARRAY OF CHAR);
8728 leency 370
VAR
371
    s: ARRAY 16*1024 OF CHAR;
372
    key: ARRAY 4 OF CHAR;
373
    i: INTEGER;
374
BEGIN
9193 akron1 375
	FOR i := 0 TO LEN(delim) - 1 DO
376
		delim[i] := FALSE
377
	END;
378
	getStr(lang, "delim", s);
379
	i := 0;
380
	WHILE s[i] # 0X DO
381
		delim[ORD(s[i])] := TRUE;
382
		INC(i)
383
	END;
8728 leency 384
    key := "KW1";
385
    FOR i := 0 TO 2 DO
386
        KW[i].cnt := 0;
387
        key[2] := CHR(ORD("1") + i);
388
        getStr(lang, key, s);
8762 leency 389
        EnterKW(s, KW[i], (lang = "lang_C") & (i = 1))
390
    END
8728 leency 391
END loadKW;
392
 
393
 
9193 akron1 394
PROCEDURE setCurLang* (lang: INTEGER);
395
BEGIN
396
	currentLang := lang
397
END setCurLang;
398
 
399
 
9210 akron1 400
PROCEDURE getLang* (ext: ARRAY OF CHAR): INTEGER;
401
VAR
402
	i: INTEGER;
403
BEGIN
404
	i := 0;
405
	WHILE (i < LEN(fileExt)) & (fileExt[i].ext # ext) DO
406
		INC(i)
407
	END;
408
	IF i < LEN(fileExt) THEN
409
		i := fileExt[i].lang
410
	ELSE
411
		i := langText
412
	END
413
	RETURN i
414
END getLang;
415
 
416
 
417
PROCEDURE getExt* (lang: INTEGER; VAR ext: ARRAY OF CHAR);
418
VAR
419
	i: INTEGER;
420
BEGIN
421
	i := 0;
422
	WHILE fileExt[i].lang # lang DO
423
		INC(i)
424
	END;
425
	COPY(fileExt[i].ext, ext);
426
	Utils.lowcase(ext)
427
END getExt;
428
 
429
 
8728 leency 430
PROCEDURE init* (getStr: procGetStr);
431
BEGIN
9193 akron1 432
	currentLang := langText;
433
	loadKW(KW[langText],   Delim[langText],   getStr, "lang_Text");
434
    loadKW(KW[langOberon], Delim[langOberon], getStr, "lang_Oberon");
435
    loadKW(KW[langC],      Delim[langC],      getStr, "lang_C");
436
    loadKW(KW[langPascal], Delim[langPascal], getStr, "lang_Pascal");
437
    loadKW(KW[langLua],    Delim[langLua],    getStr, "lang_Lua");
438
    loadKW(KW[langIni],    Delim[langIni],    getStr, "lang_Ini");
439
    loadKW(KW[langFasm],   Delim[langFasm],   getStr, "lang_Fasm");
440
    loadKW(KW[langJSON],   Delim[langJSON],   getStr, "lang_JSON");
9210 akron1 441
 
442
    fileExt[ 0].ext := "OB07"; fileExt[ 0].lang := langOberon;
443
    fileExt[ 1].ext := "C";    fileExt[ 1].lang := langC;
444
    fileExt[ 2].ext := "H";    fileExt[ 2].lang := langC;
445
    fileExt[ 3].ext := "CPP";  fileExt[ 3].lang := langC;
446
    fileExt[ 4].ext := "PAS";  fileExt[ 4].lang := langPascal;
447
    fileExt[ 5].ext := "PP";   fileExt[ 5].lang := langPascal;
448
    fileExt[ 6].ext := "ASM";  fileExt[ 6].lang := langFasm;
449
    fileExt[ 7].ext := "LUA";  fileExt[ 7].lang := langLua;
450
    fileExt[ 8].ext := "INI";  fileExt[ 8].lang := langIni;
451
    fileExt[ 9].ext := "JSON"; fileExt[ 9].lang := langJSON;
452
    fileExt[10].ext := "TXT";  fileExt[10].lang := langText;
8728 leency 453
END init;
454
 
455
 
456
END Languages.