Subversion Repositories Kolibri OS

Rev

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