Subversion Repositories Kolibri OS

Rev

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