Subversion Repositories Kolibri OS

Rev

Rev 8762 | Rev 9073 | 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.     csLang = {langNone, langC, langOberon, langLua, langIni};
  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: 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.     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.  
  329. PROCEDURE EnterKW (s: ARRAY OF CHAR; VAR KW: tKeyWords; CPrep: BOOLEAN);
  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
  343.         KW.words[k, 0] := "#";
  344.         j := ORD(CPrep);
  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);
  371.         EnterKW(s, KW[i], (lang = "lang_C") & (i = 1))
  372.     END
  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.