PageRenderTime 26ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/ExtLibs/wxWidgets/src/stc/scintilla/lexers/LexTACL.cxx

https://bitbucket.org/cafu/cafu
C++ | 400 lines | 360 code | 27 blank | 13 comment | 144 complexity | ae28cc853d47b028ace05b22e55b33af MD5 | raw file
Possible License(s): GPL-3.0, LGPL-2.0, BSD-3-Clause, LGPL-3.0, LGPL-2.1, AGPL-3.0
  1. // Scintilla source code edit control
  2. /** @file LexTAL.cxx
  3. ** Lexer for TAL
  4. ** Based on LexPascal.cxx
  5. ** Written by Laurent le Tynevez
  6. ** Updated by Simon Steele <s.steele@pnotepad.org> September 2002
  7. ** Updated by Mathias Rauen <scite@madshi.net> May 2003 (Delphi adjustments)
  8. ** Updated by Rod Falck, Aug 2006 Converted to TACL
  9. **/
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <stdio.h>
  13. #include <stdarg.h>
  14. #include <assert.h>
  15. #include <ctype.h>
  16. #include "ILexer.h"
  17. #include "Scintilla.h"
  18. #include "SciLexer.h"
  19. #include "WordList.h"
  20. #include "LexAccessor.h"
  21. #include "Accessor.h"
  22. #include "StyleContext.h"
  23. #include "CharacterSet.h"
  24. #include "LexerModule.h"
  25. #ifdef SCI_NAMESPACE
  26. using namespace Scintilla;
  27. #endif
  28. inline bool isTACLoperator(char ch)
  29. {
  30. return ch == '\'' || isoperator(ch);
  31. }
  32. inline bool isTACLwordchar(char ch)
  33. {
  34. return ch == '#' || ch == '^' || ch == '|' || ch == '_' || iswordchar(ch);
  35. }
  36. inline bool isTACLwordstart(char ch)
  37. {
  38. return ch == '#' || ch == '|' || ch == '_' || iswordstart(ch);
  39. }
  40. static void getRange(unsigned int start,
  41. unsigned int end,
  42. Accessor &styler,
  43. char *s,
  44. unsigned int len) {
  45. unsigned int i = 0;
  46. while ((i < end - start + 1) && (i < len-1)) {
  47. s[i] = static_cast<char>(tolower(styler[start + i]));
  48. i++;
  49. }
  50. s[i] = '\0';
  51. }
  52. static bool IsStreamCommentStyle(int style) {
  53. return style == SCE_C_COMMENT ||
  54. style == SCE_C_COMMENTDOC ||
  55. style == SCE_C_COMMENTDOCKEYWORD ||
  56. style == SCE_C_COMMENTDOCKEYWORDERROR;
  57. }
  58. static void ColourTo(Accessor &styler, unsigned int end, unsigned int attr, bool bInAsm) {
  59. if ((bInAsm) && (attr == SCE_C_OPERATOR || attr == SCE_C_NUMBER || attr == SCE_C_DEFAULT || attr == SCE_C_WORD || attr == SCE_C_IDENTIFIER)) {
  60. styler.ColourTo(end, SCE_C_REGEX);
  61. } else
  62. styler.ColourTo(end, attr);
  63. }
  64. // returns 1 if the item starts a class definition, and -1 if the word is "end", and 2 if the word is "asm"
  65. static int classifyWordTACL(unsigned int start, unsigned int end, /*WordList &keywords*/WordList *keywordlists[], Accessor &styler, bool bInAsm) {
  66. int ret = 0;
  67. WordList& keywords = *keywordlists[0];
  68. WordList& builtins = *keywordlists[1];
  69. WordList& commands = *keywordlists[2];
  70. char s[100];
  71. getRange(start, end, styler, s, sizeof(s));
  72. char chAttr = SCE_C_IDENTIFIER;
  73. if (isdigit(s[0]) || (s[0] == '.')) {
  74. chAttr = SCE_C_NUMBER;
  75. }
  76. else {
  77. if (s[0] == '#' || keywords.InList(s)) {
  78. chAttr = SCE_C_WORD;
  79. if (strcmp(s, "asm") == 0) {
  80. ret = 2;
  81. }
  82. else if (strcmp(s, "end") == 0) {
  83. ret = -1;
  84. }
  85. }
  86. else if (s[0] == '|' || builtins.InList(s)) {
  87. chAttr = SCE_C_WORD2;
  88. }
  89. else if (commands.InList(s)) {
  90. chAttr = SCE_C_UUID;
  91. }
  92. else if (strcmp(s, "comment") == 0) {
  93. chAttr = SCE_C_COMMENTLINE;
  94. ret = 3;
  95. }
  96. }
  97. ColourTo(styler, end, chAttr, (bInAsm && ret != -1));
  98. return ret;
  99. }
  100. static int classifyFoldPointTACL(const char* s) {
  101. int lev = 0;
  102. if (s[0] == '[')
  103. lev=1;
  104. else if (s[0] == ']')
  105. lev=-1;
  106. return lev;
  107. }
  108. static void ColouriseTACLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
  109. Accessor &styler) {
  110. styler.StartAt(startPos);
  111. int state = initStyle;
  112. if (state == SCE_C_CHARACTER) // Does not leak onto next line
  113. state = SCE_C_DEFAULT;
  114. char chPrev = ' ';
  115. char chNext = styler[startPos];
  116. unsigned int lengthDoc = startPos + length;
  117. bool bInClassDefinition;
  118. int currentLine = styler.GetLine(startPos);
  119. if (currentLine > 0) {
  120. styler.SetLineState(currentLine, styler.GetLineState(currentLine-1));
  121. bInClassDefinition = (styler.GetLineState(currentLine) == 1);
  122. } else {
  123. styler.SetLineState(currentLine, 0);
  124. bInClassDefinition = false;
  125. }
  126. bool bInAsm = (state == SCE_C_REGEX);
  127. if (bInAsm)
  128. state = SCE_C_DEFAULT;
  129. styler.StartSegment(startPos);
  130. int visibleChars = 0;
  131. unsigned int i;
  132. for (i = startPos; i < lengthDoc; i++) {
  133. char ch = chNext;
  134. chNext = styler.SafeGetCharAt(i + 1);
  135. if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
  136. // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
  137. // Avoid triggering two times on Dos/Win
  138. // End of line
  139. if (state == SCE_C_CHARACTER) {
  140. ColourTo(styler, i, state, bInAsm);
  141. state = SCE_C_DEFAULT;
  142. }
  143. visibleChars = 0;
  144. currentLine++;
  145. styler.SetLineState(currentLine, (bInClassDefinition ? 1 : 0));
  146. }
  147. if (styler.IsLeadByte(ch)) {
  148. chNext = styler.SafeGetCharAt(i + 2);
  149. chPrev = ' ';
  150. i += 1;
  151. continue;
  152. }
  153. if (state == SCE_C_DEFAULT) {
  154. if (isTACLwordstart(ch)) {
  155. ColourTo(styler, i-1, state, bInAsm);
  156. state = SCE_C_IDENTIFIER;
  157. } else if (ch == '{') {
  158. ColourTo(styler, i-1, state, bInAsm);
  159. state = SCE_C_COMMENT;
  160. } else if (ch == '{' && chNext == '*') {
  161. ColourTo(styler, i-1, state, bInAsm);
  162. state = SCE_C_COMMENTDOC;
  163. } else if (ch == '=' && chNext == '=') {
  164. ColourTo(styler, i-1, state, bInAsm);
  165. state = SCE_C_COMMENTLINE;
  166. } else if (ch == '"') {
  167. ColourTo(styler, i-1, state, bInAsm);
  168. state = SCE_C_STRING;
  169. } else if (ch == '?' && visibleChars == 0) {
  170. ColourTo(styler, i-1, state, bInAsm);
  171. state = SCE_C_PREPROCESSOR;
  172. } else if (isTACLoperator(ch)) {
  173. ColourTo(styler, i-1, state, bInAsm);
  174. ColourTo(styler, i, SCE_C_OPERATOR, bInAsm);
  175. }
  176. } else if (state == SCE_C_IDENTIFIER) {
  177. if (!isTACLwordchar(ch)) {
  178. int lStateChange = classifyWordTACL(styler.GetStartSegment(), i - 1, keywordlists, styler, bInAsm);
  179. if(lStateChange == 1) {
  180. styler.SetLineState(currentLine, 1);
  181. bInClassDefinition = true;
  182. } else if(lStateChange == 2) {
  183. bInAsm = true;
  184. } else if(lStateChange == -1) {
  185. styler.SetLineState(currentLine, 0);
  186. bInClassDefinition = false;
  187. bInAsm = false;
  188. }
  189. if (lStateChange == 3) {
  190. state = SCE_C_COMMENTLINE;
  191. }
  192. else {
  193. state = SCE_C_DEFAULT;
  194. chNext = styler.SafeGetCharAt(i + 1);
  195. if (ch == '{') {
  196. state = SCE_C_COMMENT;
  197. } else if (ch == '{' && chNext == '*') {
  198. ColourTo(styler, i-1, state, bInAsm);
  199. state = SCE_C_COMMENTDOC;
  200. } else if (ch == '=' && chNext == '=') {
  201. state = SCE_C_COMMENTLINE;
  202. } else if (ch == '"') {
  203. state = SCE_C_STRING;
  204. } else if (isTACLoperator(ch)) {
  205. ColourTo(styler, i, SCE_C_OPERATOR, bInAsm);
  206. }
  207. }
  208. }
  209. } else {
  210. if (state == SCE_C_PREPROCESSOR) {
  211. if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) {
  212. ColourTo(styler, i-1, state, bInAsm);
  213. state = SCE_C_DEFAULT;
  214. }
  215. } else if (state == SCE_C_COMMENT) {
  216. if (ch == '}' || (ch == '\r' || ch == '\n') ) {
  217. ColourTo(styler, i, state, bInAsm);
  218. state = SCE_C_DEFAULT;
  219. }
  220. } else if (state == SCE_C_COMMENTDOC) {
  221. if (ch == '}' || (ch == '\r' || ch == '\n')) {
  222. if (((i > styler.GetStartSegment() + 2) || (
  223. (initStyle == SCE_C_COMMENTDOC) &&
  224. (styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) {
  225. ColourTo(styler, i, state, bInAsm);
  226. state = SCE_C_DEFAULT;
  227. }
  228. }
  229. } else if (state == SCE_C_COMMENTLINE) {
  230. if (ch == '\r' || ch == '\n') {
  231. ColourTo(styler, i-1, state, bInAsm);
  232. state = SCE_C_DEFAULT;
  233. }
  234. } else if (state == SCE_C_STRING) {
  235. if (ch == '"' || ch == '\r' || ch == '\n') {
  236. ColourTo(styler, i, state, bInAsm);
  237. state = SCE_C_DEFAULT;
  238. }
  239. }
  240. }
  241. if (!isspacechar(ch))
  242. visibleChars++;
  243. chPrev = ch;
  244. }
  245. // Process to end of document
  246. if (state == SCE_C_IDENTIFIER) {
  247. classifyWordTACL(styler.GetStartSegment(), i - 1, keywordlists, styler, bInAsm);
  248. }
  249. else
  250. ColourTo(styler, lengthDoc - 1, state, bInAsm);
  251. }
  252. static void FoldTACLDoc(unsigned int startPos, int length, int initStyle, WordList *[],
  253. Accessor &styler) {
  254. bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
  255. bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
  256. bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
  257. unsigned int endPos = startPos + length;
  258. int visibleChars = 0;
  259. int lineCurrent = styler.GetLine(startPos);
  260. int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
  261. int levelCurrent = levelPrev;
  262. char chNext = styler[startPos];
  263. int styleNext = styler.StyleAt(startPos);
  264. int style = initStyle;
  265. bool section = false;
  266. int lastStart = 0;
  267. for (unsigned int i = startPos; i < endPos; i++) {
  268. char ch = chNext;
  269. chNext = styler.SafeGetCharAt(i + 1);
  270. int stylePrev = style;
  271. style = styleNext;
  272. styleNext = styler.StyleAt(i + 1);
  273. bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
  274. if (stylePrev == SCE_C_DEFAULT && (style == SCE_C_WORD || style == SCE_C_PREPROCESSOR))
  275. {
  276. // Store last word start point.
  277. lastStart = i;
  278. }
  279. if (stylePrev == SCE_C_WORD || stylePrev == SCE_C_PREPROCESSOR) {
  280. if(isTACLwordchar(ch) && !isTACLwordchar(chNext)) {
  281. char s[100];
  282. getRange(lastStart, i, styler, s, sizeof(s));
  283. if (stylePrev == SCE_C_PREPROCESSOR && strcmp(s, "?section") == 0)
  284. {
  285. section = true;
  286. levelCurrent = 1;
  287. levelPrev = 0;
  288. }
  289. else if (stylePrev == SCE_C_WORD)
  290. levelCurrent += classifyFoldPointTACL(s);
  291. }
  292. }
  293. if (style == SCE_C_OPERATOR) {
  294. if (ch == '[') {
  295. levelCurrent++;
  296. } else if (ch == ']') {
  297. levelCurrent--;
  298. }
  299. }
  300. if (foldComment && (style == SCE_C_COMMENTLINE)) {
  301. if ((ch == '/') && (chNext == '/')) {
  302. char chNext2 = styler.SafeGetCharAt(i + 2);
  303. if (chNext2 == '{') {
  304. levelCurrent++;
  305. } else if (chNext2 == '}') {
  306. levelCurrent--;
  307. }
  308. }
  309. }
  310. if (foldPreprocessor && (style == SCE_C_PREPROCESSOR)) {
  311. if (ch == '{' && chNext == '$') {
  312. unsigned int j=i+2; // skip {$
  313. while ((j<endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
  314. j++;
  315. }
  316. if (styler.Match(j, "region") || styler.Match(j, "if")) {
  317. levelCurrent++;
  318. } else if (styler.Match(j, "end")) {
  319. levelCurrent--;
  320. }
  321. }
  322. }
  323. if (foldComment && IsStreamCommentStyle(style)) {
  324. if (!IsStreamCommentStyle(stylePrev)) {
  325. levelCurrent++;
  326. } else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
  327. // Comments don't end at end of line and the next character may be unstyled.
  328. levelCurrent--;
  329. }
  330. }
  331. if (atEOL) {
  332. int lev = levelPrev | SC_FOLDLEVELBASE;
  333. if (visibleChars == 0 && foldCompact)
  334. lev |= SC_FOLDLEVELWHITEFLAG;
  335. if ((levelCurrent > levelPrev || section) && (visibleChars > 0))
  336. lev |= SC_FOLDLEVELHEADERFLAG;
  337. if (lev != styler.LevelAt(lineCurrent)) {
  338. styler.SetLevel(lineCurrent, lev);
  339. }
  340. lineCurrent++;
  341. levelPrev = levelCurrent;
  342. visibleChars = 0;
  343. section = false;
  344. }
  345. if (!isspacechar(ch))
  346. visibleChars++;
  347. }
  348. // Fill in the real level of the next line, keeping the current flags as they will be filled in later
  349. int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
  350. styler.SetLevel(lineCurrent, levelPrev | flagsNext);
  351. }
  352. static const char * const TACLWordListDesc[] = {
  353. "Builtins",
  354. "Labels",
  355. "Commands",
  356. 0
  357. };
  358. LexerModule lmTACL(SCLEX_TACL, ColouriseTACLDoc, "TACL", FoldTACLDoc, TACLWordListDesc);