Subversion Repositories Kolibri OS

Rev

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