Subversion Repositories Kolibri OS

Rev

Rev 8762 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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 <http://www.gnu.org/licenses/>.
  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.  
  322. PROCEDURE EnterKW (s: ARRAY OF CHAR; VAR KW: tKeyWords);
  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
  336.         j := 0;
  337.         WHILE (s[i] # 0X) & ~delim(s[i]) DO
  338.             KW.words[k, j] := WCHR(ORD(s[i]));
  339.             INC(i);
  340.             INC(j)
  341.         END;
  342.         KW.words[k, j] := 0X;
  343.         INC(k);
  344.         WHILE delim(s[i]) DO
  345.             INC(i)
  346.         END
  347.     UNTIL s[i] = 0X;
  348.     KW.cnt := k
  349. END EnterKW;
  350.  
  351.  
  352. PROCEDURE loadKW (VAR KW: ARRAY OF tKeyWords; getStr: procGetStr; lang: ARRAY OF CHAR);
  353. VAR
  354.     s: ARRAY 16*1024 OF CHAR;
  355.     key: ARRAY 4 OF CHAR;
  356.     i: INTEGER;
  357. BEGIN
  358.     key := "KW1";
  359.     FOR i := 0 TO 2 DO
  360.         KW[i].cnt := 0;
  361.         key[2] := CHR(ORD("1") + i);
  362.         getStr(lang, key, s);
  363.         EnterKW(s, KW[i])
  364.     END;
  365. END loadKW;
  366.  
  367.  
  368. PROCEDURE init* (getStr: procGetStr);
  369. BEGIN
  370.     loadKW(oberonKW, getStr, "lang_Oberon");
  371.     loadKW(cKW,      getStr, "lang_C");
  372.     loadKW(pascalKW, getStr, "lang_Pascal");
  373.     loadKW(luaKW,    getStr, "lang_Lua");
  374.     loadKW(iniKW,    getStr, "lang_Ini");
  375.     loadKW(fasmKW,   getStr, "lang_Fasm");
  376. END init;
  377.  
  378.  
  379. END Languages.