Subversion Repositories Kolibri OS

Rev

Rev 9073 | Rev 9190 | 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; langJSON* = 7;
  29.  
  30.     csLang = {langC, langOberon, langLua, langIni, langJSON};
  31.  
  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, jsonKW: ARRAY 3 OF tKeyWords;
  46.  
  47.  
  48. PROCEDURE isCS* (lang: INTEGER): BOOLEAN;
  49.     RETURN lang IN csLang
  50. END isCS;
  51.  
  52.  
  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.         DEC(kwSet);
  70.     res := FALSE;
  71.     CASE lang OF
  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])
  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
  320.     |langNone:
  321.     |langFasm:
  322.     |langC,
  323.      langJSON:    C(line, depth, cond, pos, n)
  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.  
  332. PROCEDURE EnterKW (s: ARRAY OF CHAR; VAR KW: tKeyWords; CPrep: BOOLEAN);
  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
  346.         KW.words[k, 0] := "#";
  347.         j := ORD(CPrep);
  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);
  374.         EnterKW(s, KW[i], (lang = "lang_C") & (i = 1))
  375.     END
  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");
  387.     loadKW(jsonKW,   getStr, "lang_JSON");
  388. END init;
  389.  
  390.  
  391. END Languages.