PageRenderTime 41ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/LexLisp.cxx

https://bitbucket.org/CaptainOz/ogre
C++ | 275 lines | 246 code | 21 blank | 8 comment | 160 complexity | 3ee48d090beae10ab85b60f6bee74283 MD5 | raw file
Possible License(s): LGPL-2.1, MIT
  1. // Scintilla source code edit control
  2. /** @file LexLisp.cxx
  3. ** Lexer for Lisp.
  4. ** Written by Alexey Yutkin.
  5. **/
  6. // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
  7. // The License.txt file describes the conditions under which this software may be distributed.
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <ctype.h>
  11. #include <stdio.h>
  12. #include <stdarg.h>
  13. #include "Platform.h"
  14. #include "PropSet.h"
  15. #include "Accessor.h"
  16. #include "KeyWords.h"
  17. #include "Scintilla.h"
  18. #include "SciLexer.h"
  19. #include "StyleContext.h"
  20. #define SCE_LISP_CHARACTER 29
  21. #define SCE_LISP_MACRO 30
  22. #define SCE_LISP_MACRO_DISPATCH 31
  23. static inline bool isLispoperator(char ch) {
  24. if (isascii(ch) && isalnum(ch))
  25. return false;
  26. if (ch == '\'' || ch == '`' || ch == '(' || ch == ')' )
  27. return true;
  28. return false;
  29. }
  30. static inline bool isLispwordstart(char ch) {
  31. return isascii(ch) && ch != ';' && !isspacechar(ch) && !isLispoperator(ch) &&
  32. ch != '\n' && ch != '\r' && ch != '\"';
  33. }
  34. static void classifyWordLisp(unsigned int start, unsigned int end, WordList &keywords, WordList &keywords_kw, Accessor &styler) {
  35. PLATFORM_ASSERT(end >= start);
  36. char s[100];
  37. unsigned int i;
  38. bool digit_flag = true;
  39. for (i = 0; (i < end - start + 1) && (i < 99); i++) {
  40. s[i] = styler[start + i];
  41. s[i + 1] = '\0';
  42. if (!isdigit(s[i]) && (s[i] != '.')) digit_flag = false;
  43. }
  44. char chAttr = SCE_LISP_IDENTIFIER;
  45. if(digit_flag) chAttr = SCE_LISP_NUMBER;
  46. else {
  47. if (keywords.InList(s)) {
  48. chAttr = SCE_LISP_KEYWORD;
  49. } else if (keywords_kw.InList(s)) {
  50. chAttr = SCE_LISP_KEYWORD_KW;
  51. } else if ((s[0] == '*' && s[i-1] == '*') ||
  52. (s[0] == '+' && s[i-1] == '+')) {
  53. chAttr = SCE_LISP_SPECIAL;
  54. }
  55. }
  56. styler.ColourTo(end, chAttr);
  57. return;
  58. }
  59. static void ColouriseLispDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
  60. Accessor &styler) {
  61. WordList &keywords = *keywordlists[0];
  62. WordList &keywords_kw = *keywordlists[1];
  63. styler.StartAt(startPos);
  64. int state = initStyle, radix = -1;
  65. char chNext = styler[startPos];
  66. unsigned int lengthDoc = startPos + length;
  67. styler.StartSegment(startPos);
  68. for (unsigned int i = startPos; i < lengthDoc; i++) {
  69. char ch = chNext;
  70. chNext = styler.SafeGetCharAt(i + 1);
  71. bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
  72. if (styler.IsLeadByte(ch)) {
  73. chNext = styler.SafeGetCharAt(i + 2);
  74. i += 1;
  75. continue;
  76. }
  77. if (state == SCE_LISP_DEFAULT) {
  78. if (ch == '#') {
  79. styler.ColourTo(i - 1, state);
  80. radix = -1;
  81. state = SCE_LISP_MACRO_DISPATCH;
  82. } else if (isLispwordstart(ch)) {
  83. styler.ColourTo(i - 1, state);
  84. state = SCE_LISP_IDENTIFIER;
  85. }
  86. else if (ch == ';') {
  87. styler.ColourTo(i - 1, state);
  88. state = SCE_LISP_COMMENT;
  89. }
  90. else if (isLispoperator(ch) || ch=='\'') {
  91. styler.ColourTo(i - 1, state);
  92. styler.ColourTo(i, SCE_LISP_OPERATOR);
  93. if (ch=='\'' && isLispwordstart(chNext)) {
  94. state = SCE_LISP_SYMBOL;
  95. }
  96. }
  97. else if (ch == '\"') {
  98. styler.ColourTo(i - 1, state);
  99. state = SCE_LISP_STRING;
  100. }
  101. } else if (state == SCE_LISP_IDENTIFIER || state == SCE_LISP_SYMBOL) {
  102. if (!isLispwordstart(ch)) {
  103. if (state == SCE_LISP_IDENTIFIER) {
  104. classifyWordLisp(styler.GetStartSegment(), i - 1, keywords, keywords_kw, styler);
  105. } else {
  106. styler.ColourTo(i - 1, state);
  107. }
  108. state = SCE_LISP_DEFAULT;
  109. } /*else*/
  110. if (isLispoperator(ch) || ch=='\'') {
  111. styler.ColourTo(i - 1, state);
  112. styler.ColourTo(i, SCE_LISP_OPERATOR);
  113. if (ch=='\'' && isLispwordstart(chNext)) {
  114. state = SCE_LISP_SYMBOL;
  115. }
  116. }
  117. } else if (state == SCE_LISP_MACRO_DISPATCH) {
  118. if (!isdigit(ch)) {
  119. if (ch != 'r' && ch != 'R' && (i - styler.GetStartSegment()) > 1) {
  120. state = SCE_LISP_DEFAULT;
  121. } else {
  122. switch (ch) {
  123. case '|': state = SCE_LISP_MULTI_COMMENT; break;
  124. case 'o':
  125. case 'O': radix = 8; state = SCE_LISP_MACRO; break;
  126. case 'x':
  127. case 'X': radix = 16; state = SCE_LISP_MACRO; break;
  128. case 'b':
  129. case 'B': radix = 2; state = SCE_LISP_MACRO; break;
  130. case '\\': state = SCE_LISP_CHARACTER; break;
  131. case ':':
  132. case '-':
  133. case '+': state = SCE_LISP_MACRO; break;
  134. case '\'': if (isLispwordstart(chNext)) {
  135. state = SCE_LISP_SPECIAL;
  136. } else {
  137. styler.ColourTo(i - 1, SCE_LISP_DEFAULT);
  138. styler.ColourTo(i, SCE_LISP_OPERATOR);
  139. state = SCE_LISP_DEFAULT;
  140. }
  141. break;
  142. default: if (isLispoperator(ch)) {
  143. styler.ColourTo(i - 1, SCE_LISP_DEFAULT);
  144. styler.ColourTo(i, SCE_LISP_OPERATOR);
  145. }
  146. state = SCE_LISP_DEFAULT;
  147. break;
  148. }
  149. }
  150. }
  151. } else if (state == SCE_LISP_MACRO) {
  152. if (isLispwordstart(ch) && (radix == -1 || IsADigit(ch, radix))) {
  153. state = SCE_LISP_SPECIAL;
  154. } else {
  155. state = SCE_LISP_DEFAULT;
  156. }
  157. } else if (state == SCE_LISP_CHARACTER) {
  158. if (isLispoperator(ch)) {
  159. styler.ColourTo(i, SCE_LISP_SPECIAL);
  160. state = SCE_LISP_DEFAULT;
  161. } else if (isLispwordstart(ch)) {
  162. styler.ColourTo(i, SCE_LISP_SPECIAL);
  163. state = SCE_LISP_SPECIAL;
  164. } else {
  165. state = SCE_LISP_DEFAULT;
  166. }
  167. } else if (state == SCE_LISP_SPECIAL) {
  168. if (!isLispwordstart(ch) || (radix != -1 && !IsADigit(ch, radix))) {
  169. styler.ColourTo(i - 1, state);
  170. state = SCE_LISP_DEFAULT;
  171. }
  172. if (isLispoperator(ch) || ch=='\'') {
  173. styler.ColourTo(i - 1, state);
  174. styler.ColourTo(i, SCE_LISP_OPERATOR);
  175. if (ch=='\'' && isLispwordstart(chNext)) {
  176. state = SCE_LISP_SYMBOL;
  177. }
  178. }
  179. } else {
  180. if (state == SCE_LISP_COMMENT) {
  181. if (atEOL) {
  182. styler.ColourTo(i - 1, state);
  183. state = SCE_LISP_DEFAULT;
  184. }
  185. } else if (state == SCE_LISP_MULTI_COMMENT) {
  186. if (ch == '|' && chNext == '#') {
  187. i++;
  188. chNext = styler.SafeGetCharAt(i + 1);
  189. styler.ColourTo(i, state);
  190. state = SCE_LISP_DEFAULT;
  191. }
  192. } else if (state == SCE_LISP_STRING) {
  193. if (ch == '\\') {
  194. if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
  195. i++;
  196. chNext = styler.SafeGetCharAt(i + 1);
  197. }
  198. } else if (ch == '\"') {
  199. styler.ColourTo(i, state);
  200. state = SCE_LISP_DEFAULT;
  201. }
  202. }
  203. }
  204. }
  205. styler.ColourTo(lengthDoc - 1, state);
  206. }
  207. static void FoldLispDoc(unsigned int startPos, int length, int /* initStyle */, WordList *[],
  208. Accessor &styler) {
  209. unsigned int lengthDoc = startPos + length;
  210. int visibleChars = 0;
  211. int lineCurrent = styler.GetLine(startPos);
  212. int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
  213. int levelCurrent = levelPrev;
  214. char chNext = styler[startPos];
  215. int styleNext = styler.StyleAt(startPos);
  216. for (unsigned int i = startPos; i < lengthDoc; i++) {
  217. char ch = chNext;
  218. chNext = styler.SafeGetCharAt(i + 1);
  219. int style = styleNext;
  220. styleNext = styler.StyleAt(i + 1);
  221. bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
  222. if (style == SCE_LISP_OPERATOR) {
  223. if (ch == '(') {
  224. levelCurrent++;
  225. } else if (ch == ')') {
  226. levelCurrent--;
  227. }
  228. }
  229. if (atEOL) {
  230. int lev = levelPrev;
  231. if (visibleChars == 0)
  232. lev |= SC_FOLDLEVELWHITEFLAG;
  233. if ((levelCurrent > levelPrev) && (visibleChars > 0))
  234. lev |= SC_FOLDLEVELHEADERFLAG;
  235. if (lev != styler.LevelAt(lineCurrent)) {
  236. styler.SetLevel(lineCurrent, lev);
  237. }
  238. lineCurrent++;
  239. levelPrev = levelCurrent;
  240. visibleChars = 0;
  241. }
  242. if (!isspacechar(ch))
  243. visibleChars++;
  244. }
  245. // Fill in the real level of the next line, keeping the current flags as they will be filled in later
  246. int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
  247. styler.SetLevel(lineCurrent, levelPrev | flagsNext);
  248. }
  249. static const char * const lispWordListDesc[] = {
  250. "Functions and special operators",
  251. "Keywords",
  252. 0
  253. };
  254. LexerModule lmLISP(SCLEX_LISP, ColouriseLispDoc, "lisp", FoldLispDoc, lispWordListDesc);