Subversion Repositories Kolibri OS

Rev

Rev 9190 | Rev 9210 | 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
 
22
IMPORT Lines;
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
 
9193 akron1 52
 
9050 leency 53
PROCEDURE isCS* (lang: INTEGER): BOOLEAN;
54
    RETURN lang IN csLang
55
END isCS;
56
 
57
 
8728 leency 58
PROCEDURE checkKW (s: ARRAY OF WCHAR; KW: tKeyWords): BOOLEAN;
59
VAR
60
    i: INTEGER;
61
BEGIN
62
    i := KW.cnt - 1;
63
    WHILE (i >= 0) & (s # KW.words[i]) DO
64
        DEC(i)
65
    END
66
    RETURN i >= 0
67
END checkKW;
68
 
69
 
70
PROCEDURE isKey* (s: ARRAY OF WCHAR; lang, kwSet: INTEGER): BOOLEAN;
9193 akron1 71
    RETURN checkKW(s, KW[lang][kwSet - 1])
72
END isKey;
73
 
74
 
75
PROCEDURE isDelim* (c: WCHAR): BOOLEAN;
8728 leency 76
VAR
9193 akron1 77
	res: BOOLEAN;
8728 leency 78
BEGIN
9193 akron1 79
	IF c <= 0FFX THEN
80
		res := Delim[currentLang][ORD(c)]
81
	ELSE
82
		res := FALSE
83
	END
84
	RETURN res
85
END isDelim;
8728 leency 86
 
87
 
88
PROCEDURE SkipString* (line: tLine; VAR pos: INTEGER; n: INTEGER);
89
VAR
90
    quot: WCHAR;
91
BEGIN
92
    quot := Lines.getChar(line, pos);
93
    REPEAT
94
        INC(pos)
95
    UNTIL (pos > n) OR (Lines.getChar(line, pos) = quot)
96
END SkipString;
97
 
98
 
99
PROCEDURE C (line: tLine; VAR depth, cond, pos: INTEGER; n: INTEGER);
100
VAR
101
    c: WCHAR;
102
BEGIN
103
    c := Lines.getChar(line, pos);
104
    IF depth = 0 THEN
105
        IF c = "/" THEN
106
            IF cond = 0 THEN
107
                cond := 1
108
            ELSE
109
                cond := 0;
110
                pos := n
111
            END
112
        ELSIF (c = "*") & (cond = 1) THEN
113
            depth := 1;
114
            cond := 0
115
        ELSIF (c = "'") OR (c = '"') THEN
116
            SkipString(line, pos, n);
117
            cond := 0
118
        ELSE
119
            cond := 0
120
        END
121
    ELSIF depth = 1 THEN
122
        IF c = "*" THEN
123
            cond := 1
124
        ELSIF (c = "/") & (cond = 1) THEN
125
            cond := 0;
126
            depth := 0
127
        ELSE
128
            cond := 0
129
        END
130
    END
131
END C;
132
 
133
 
134
PROCEDURE getChar (line: tLine; i: INTEGER): WCHAR;
135
VAR
136
    res: WCHAR;
137
BEGIN
138
    IF i >= line.length THEN
139
        res := 0X
140
    ELSE
141
        res := Lines.getChar(line, i)
142
    END
143
    RETURN res
144
END getChar;
145
 
146
 
147
PROCEDURE LuaLong* (line: tLine; pos: INTEGER): INTEGER;
148
VAR
149
    res: INTEGER;
150
BEGIN
151
    res := -1;
152
    IF getChar(line, pos) = "[" THEN
153
        INC(pos);
154
        WHILE getChar(line, pos) = "=" DO
155
            INC(res);
156
            INC(pos)
157
        END;
158
        IF getChar(line, pos) = "[" THEN
159
            INC(res)
160
        ELSE
161
            res := -1
162
        END
163
    END
164
    RETURN res
165
END LuaLong;
166
 
167
 
168
PROCEDURE Lua (line: tLine; VAR depth, cond, pos: INTEGER; n: INTEGER);
169
VAR
170
    c: WCHAR;
171
    k: INTEGER;
172
BEGIN
173
    c := Lines.getChar(line, pos);
174
    IF depth = 0 THEN
175
        IF c = "-" THEN
176
            IF cond = 0 THEN
177
                cond := 1
178
            ELSE
179
                cond := 0;
180
                k := LuaLong(line, pos + 1);
181
                IF k >= 0 THEN
182
                    depth := k*2 + 1
183
                ELSE
184
                    pos := n
185
                END
186
            END
187
        ELSIF c = "[" THEN
188
            cond := 0;
189
            k := LuaLong(line, pos);
190
            IF k >= 0 THEN
191
                depth := (k + 1)*2
192
            END
193
        ELSIF (c = "'") OR (c = '"') THEN
194
            SkipString(line, pos, n);
195
            cond := 0
196
        ELSE
197
            cond := 0
198
        END
199
    ELSIF depth > 0 THEN
200
        IF (cond = 0) & (c = "]") THEN
201
            cond := 1
202
        ELSIF (cond >= 1) & (c = "=") THEN
203
            INC(cond)
204
        ELSIF (cond >= 1) & (c = "]") & (cond*2 - depth MOD 2 = depth) THEN
205
            depth := 0;
206
            cond := 0
207
        ELSE
208
            cond := 0
209
        END
210
    END
211
END Lua;
212
 
213
 
214
PROCEDURE Pascal (line: tLine; VAR depth, cond, pos: INTEGER; n: INTEGER);
215
VAR
216
    c: WCHAR;
217
BEGIN
218
    c := Lines.getChar(line, pos);
219
    IF depth = 0 THEN
220
        IF c = "(" THEN
221
            cond := 1
222
        ELSIF c = "/" THEN
223
            IF cond = 2 THEN
224
                cond := 0;
225
                pos := n
226
            ELSE
227
                cond := 2
228
            END
229
        ELSIF (c = "*") & (cond = 1) THEN
230
            depth := 2;
231
            cond := 0
232
        ELSIF c = "'" THEN
233
            SkipString(line, pos, n);
234
            cond := 0
235
        ELSIF c = "{" THEN
236
            IF Lines.getChar(line, pos + 1) = "$" THEN
237
                depth := 3
238
            ELSE
239
                depth := 1
240
            END;
241
            cond := 0
242
        ELSE
243
            cond := 0
244
        END
245
    ELSIF depth IN {1, 3} THEN
246
        IF c = "}" THEN
247
            depth := 0
248
        END
249
    ELSIF depth = 2 THEN
250
        IF c = "*" THEN
251
            cond := 1
252
        ELSIF (c = ")") & (cond = 1) THEN
253
            depth := 0;
254
            cond := 0
255
        ELSE
256
            cond := 0
257
        END
258
    END
259
END Pascal;
260
 
261
 
262
PROCEDURE Oberon (line: tLine; VAR depth, cond, pos: INTEGER; n: INTEGER);
263
VAR
264
    c: WCHAR;
265
BEGIN
266
    c := Lines.getChar(line, pos);
267
    IF (depth = 0) & (c = "/") THEN
268
        IF cond = 3 THEN
269
            cond := 0;
270
            pos := n
271
        ELSE
272
            cond := 3
273
        END
274
    ELSIF (depth = 0) & ((c = "'") OR (c = '"')) THEN
275
        SkipString(line, pos, n);
276
        cond := 0
277
    ELSIF c = "(" THEN
278
        cond := 1
279
    ELSIF c = "*" THEN
280
        IF cond = 1 THEN
281
            INC(depth);
282
            cond := 0
283
        ELSE
284
            cond := 2
285
        END
286
    ELSIF c = ")" THEN
287
        IF cond = 2 THEN
288
            IF depth > 0 THEN
289
                DEC(depth)
290
            END
291
        END;
292
        cond := 0
293
    ELSE
294
        cond := 0
295
    END;
296
END Oberon;
297
 
298
 
299
PROCEDURE Ini (line: tLine; VAR depth, cond, pos: INTEGER; n: INTEGER);
300
VAR
301
    c: WCHAR;
302
BEGIN
303
    cond := 0;
304
    c := Lines.getChar(line, pos);
305
    IF depth = 0 THEN
306
        IF c = ";" THEN
307
            pos := n
308
        ELSIF c = '"' THEN
309
            SkipString(line, pos, n)
310
        ELSIF c = "[" THEN
311
            depth := 1
312
        END
313
    ELSIF depth = 1 THEN
314
        IF c = "]" THEN
315
            depth := 0
316
        END
317
    END
318
END Ini;
319
 
320
 
321
PROCEDURE comments* (line: tLine; VAR depth, cond, pos: INTEGER; n: INTEGER; lang: INTEGER);
322
BEGIN
323
    CASE lang OF
9190 akron1 324
    |langText:
8728 leency 325
    |langFasm:
9174 akron1 326
    |langC,
327
     langJSON:    C(line, depth, cond, pos, n)
8728 leency 328
    |langOberon:  Oberon(line, depth, cond, pos, n)
329
    |langPascal:  Pascal(line, depth, cond, pos, n)
330
    |langLua:     Lua(line, depth, cond, pos, n)
331
    |langIni:     Ini(line, depth, cond, pos, n)
332
    END
333
END comments;
334
 
335
 
8762 leency 336
PROCEDURE EnterKW (s: ARRAY OF CHAR; VAR KW: tKeyWords; CPrep: BOOLEAN);
8728 leency 337
CONST
338
    SPACE = 20X; CR = 0DX; LF = 0AX; TAB = 9X; COMMA = ",";
339
VAR
340
    i, j, k: INTEGER;
341
 
342
    PROCEDURE delim (c: CHAR): BOOLEAN;
343
        RETURN (c = COMMA) OR (c = SPACE) OR (c = CR) OR (c = LF) OR (c = TAB)
344
    END delim;
345
 
346
BEGIN
347
    k := KW.cnt;
348
    i := 0;
349
    REPEAT
8762 leency 350
        KW.words[k, 0] := "#";
351
        j := ORD(CPrep);
8728 leency 352
        WHILE (s[i] # 0X) & ~delim(s[i]) DO
353
            KW.words[k, j] := WCHR(ORD(s[i]));
354
            INC(i);
355
            INC(j)
356
        END;
357
        KW.words[k, j] := 0X;
358
        INC(k);
359
        WHILE delim(s[i]) DO
360
            INC(i)
361
        END
362
    UNTIL s[i] = 0X;
363
    KW.cnt := k
364
END EnterKW;
365
 
366
 
9193 akron1 367
PROCEDURE loadKW (VAR KW: ARRAY OF tKeyWords; VAR delim: tDelimiters; getStr: procGetStr; lang: ARRAY OF CHAR);
8728 leency 368
VAR
369
    s: ARRAY 16*1024 OF CHAR;
370
    key: ARRAY 4 OF CHAR;
371
    i: INTEGER;
372
BEGIN
9193 akron1 373
	FOR i := 0 TO LEN(delim) - 1 DO
374
		delim[i] := FALSE
375
	END;
376
	getStr(lang, "delim", s);
377
	i := 0;
378
	WHILE s[i] # 0X DO
379
		delim[ORD(s[i])] := TRUE;
380
		INC(i)
381
	END;
8728 leency 382
    key := "KW1";
383
    FOR i := 0 TO 2 DO
384
        KW[i].cnt := 0;
385
        key[2] := CHR(ORD("1") + i);
386
        getStr(lang, key, s);
8762 leency 387
        EnterKW(s, KW[i], (lang = "lang_C") & (i = 1))
388
    END
8728 leency 389
END loadKW;
390
 
391
 
9193 akron1 392
PROCEDURE setCurLang* (lang: INTEGER);
393
BEGIN
394
	currentLang := lang
395
END setCurLang;
396
 
397
 
8728 leency 398
PROCEDURE init* (getStr: procGetStr);
399
BEGIN
9193 akron1 400
	currentLang := langText;
401
	loadKW(KW[langText],   Delim[langText],   getStr, "lang_Text");
402
    loadKW(KW[langOberon], Delim[langOberon], getStr, "lang_Oberon");
403
    loadKW(KW[langC],      Delim[langC],      getStr, "lang_C");
404
    loadKW(KW[langPascal], Delim[langPascal], getStr, "lang_Pascal");
405
    loadKW(KW[langLua],    Delim[langLua],    getStr, "lang_Lua");
406
    loadKW(KW[langIni],    Delim[langIni],    getStr, "lang_Ini");
407
    loadKW(KW[langFasm],   Delim[langFasm],   getStr, "lang_Fasm");
408
    loadKW(KW[langJSON],   Delim[langJSON],   getStr, "lang_JSON");
8728 leency 409
END init;
410
 
411
 
412
END Languages.