LexPLM.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. // Copyright (c) 1990-2007, Scientific Toolworks, Inc.
  2. // Author: Jason Haslam
  3. // The License.txt file describes the conditions under which this software may be distributed.
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <stdio.h>
  7. #include <stdarg.h>
  8. #include <assert.h>
  9. #include <ctype.h>
  10. #include "ILexer.h"
  11. #include "Scintilla.h"
  12. #include "SciLexer.h"
  13. #include "WordList.h"
  14. #include "LexAccessor.h"
  15. #include "Accessor.h"
  16. #include "StyleContext.h"
  17. #include "CharacterSet.h"
  18. #include "LexerModule.h"
  19. #ifdef SCI_NAMESPACE
  20. using namespace Scintilla;
  21. #endif
  22. static void GetRange(Sci_PositionU start,
  23. Sci_PositionU end,
  24. Accessor &styler,
  25. char *s,
  26. Sci_PositionU len) {
  27. Sci_PositionU i = 0;
  28. while ((i < end - start + 1) && (i < len-1)) {
  29. s[i] = static_cast<char>(tolower(styler[start + i]));
  30. i++;
  31. }
  32. s[i] = '\0';
  33. }
  34. static void ColourisePlmDoc(Sci_PositionU startPos,
  35. Sci_Position length,
  36. int initStyle,
  37. WordList *keywordlists[],
  38. Accessor &styler)
  39. {
  40. Sci_PositionU endPos = startPos + length;
  41. int state = initStyle;
  42. styler.StartAt(startPos);
  43. styler.StartSegment(startPos);
  44. for (Sci_PositionU i = startPos; i < endPos; i++) {
  45. char ch = styler.SafeGetCharAt(i);
  46. char chNext = styler.SafeGetCharAt(i + 1);
  47. if (state == SCE_PLM_DEFAULT) {
  48. if (ch == '/' && chNext == '*') {
  49. styler.ColourTo(i - 1, state);
  50. state = SCE_PLM_COMMENT;
  51. } else if (ch == '\'') {
  52. styler.ColourTo(i - 1, state);
  53. state = SCE_PLM_STRING;
  54. } else if (isdigit(ch)) {
  55. styler.ColourTo(i - 1, state);
  56. state = SCE_PLM_NUMBER;
  57. } else if (isalpha(ch)) {
  58. styler.ColourTo(i - 1, state);
  59. state = SCE_PLM_IDENTIFIER;
  60. } else if (ch == '+' || ch == '-' || ch == '*' || ch == '/' ||
  61. ch == '=' || ch == '<' || ch == '>' || ch == ':') {
  62. styler.ColourTo(i - 1, state);
  63. state = SCE_PLM_OPERATOR;
  64. } else if (ch == '$') {
  65. styler.ColourTo(i - 1, state);
  66. state = SCE_PLM_CONTROL;
  67. }
  68. } else if (state == SCE_PLM_COMMENT) {
  69. if (ch == '*' && chNext == '/') {
  70. i++;
  71. styler.ColourTo(i, state);
  72. state = SCE_PLM_DEFAULT;
  73. }
  74. } else if (state == SCE_PLM_STRING) {
  75. if (ch == '\'') {
  76. if (chNext == '\'') {
  77. i++;
  78. } else {
  79. styler.ColourTo(i, state);
  80. state = SCE_PLM_DEFAULT;
  81. }
  82. }
  83. } else if (state == SCE_PLM_NUMBER) {
  84. if (!isdigit(ch) && !isalpha(ch) && ch != '$') {
  85. i--;
  86. styler.ColourTo(i, state);
  87. state = SCE_PLM_DEFAULT;
  88. }
  89. } else if (state == SCE_PLM_IDENTIFIER) {
  90. if (!isdigit(ch) && !isalpha(ch) && ch != '$') {
  91. // Get the entire identifier.
  92. char word[1024];
  93. Sci_Position segmentStart = styler.GetStartSegment();
  94. GetRange(segmentStart, i - 1, styler, word, sizeof(word));
  95. i--;
  96. if (keywordlists[0]->InList(word))
  97. styler.ColourTo(i, SCE_PLM_KEYWORD);
  98. else
  99. styler.ColourTo(i, state);
  100. state = SCE_PLM_DEFAULT;
  101. }
  102. } else if (state == SCE_PLM_OPERATOR) {
  103. if (ch != '=' && ch != '>') {
  104. i--;
  105. styler.ColourTo(i, state);
  106. state = SCE_PLM_DEFAULT;
  107. }
  108. } else if (state == SCE_PLM_CONTROL) {
  109. if (ch == '\r' || ch == '\n') {
  110. styler.ColourTo(i - 1, state);
  111. state = SCE_PLM_DEFAULT;
  112. }
  113. }
  114. }
  115. styler.ColourTo(endPos - 1, state);
  116. }
  117. static void FoldPlmDoc(Sci_PositionU startPos,
  118. Sci_Position length,
  119. int initStyle,
  120. WordList *[],
  121. Accessor &styler)
  122. {
  123. bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
  124. bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
  125. Sci_PositionU endPos = startPos + length;
  126. int visibleChars = 0;
  127. Sci_Position lineCurrent = styler.GetLine(startPos);
  128. int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
  129. int levelCurrent = levelPrev;
  130. char chNext = styler[startPos];
  131. int styleNext = styler.StyleAt(startPos);
  132. int style = initStyle;
  133. Sci_Position startKeyword = 0;
  134. for (Sci_PositionU i = startPos; i < endPos; i++) {
  135. char ch = chNext;
  136. chNext = styler.SafeGetCharAt(i + 1);
  137. int stylePrev = style;
  138. style = styleNext;
  139. styleNext = styler.StyleAt(i + 1);
  140. bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
  141. if (stylePrev != SCE_PLM_KEYWORD && style == SCE_PLM_KEYWORD)
  142. startKeyword = i;
  143. if (style == SCE_PLM_KEYWORD && styleNext != SCE_PLM_KEYWORD) {
  144. char word[1024];
  145. GetRange(startKeyword, i, styler, word, sizeof(word));
  146. if (strcmp(word, "procedure") == 0 || strcmp(word, "do") == 0)
  147. levelCurrent++;
  148. else if (strcmp(word, "end") == 0)
  149. levelCurrent--;
  150. }
  151. if (foldComment) {
  152. if (stylePrev != SCE_PLM_COMMENT && style == SCE_PLM_COMMENT)
  153. levelCurrent++;
  154. else if (stylePrev == SCE_PLM_COMMENT && style != SCE_PLM_COMMENT)
  155. levelCurrent--;
  156. }
  157. if (atEOL) {
  158. int lev = levelPrev;
  159. if (visibleChars == 0 && foldCompact)
  160. lev |= SC_FOLDLEVELWHITEFLAG;
  161. if ((levelCurrent > levelPrev) && (visibleChars > 0))
  162. lev |= SC_FOLDLEVELHEADERFLAG;
  163. if (lev != styler.LevelAt(lineCurrent)) {
  164. styler.SetLevel(lineCurrent, lev);
  165. }
  166. lineCurrent++;
  167. levelPrev = levelCurrent;
  168. visibleChars = 0;
  169. }
  170. if (!isspacechar(ch))
  171. visibleChars++;
  172. }
  173. int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
  174. styler.SetLevel(lineCurrent, levelPrev | flagsNext);
  175. }
  176. static const char *const plmWordListDesc[] = {
  177. "Keywords",
  178. 0
  179. };
  180. LexerModule lmPLM(SCLEX_PLM, ColourisePlmDoc, "PL/M", FoldPlmDoc, plmWordListDesc);