PageRenderTime 54ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/ext/scintilla/lexers/LexOpal.cxx

https://gitlab.com/life436/tortoisegit
C++ | 525 lines | 493 code | 19 blank | 13 comment | 24 complexity | dca835c061e371f6f77034e5c8d6775d MD5 | raw file
  1. // Scintilla source code edit control
  2. /** @file LexOpal.cxx
  3. ** Lexer for OPAL (functional language similar to Haskell)
  4. ** Written by Sebastian Pipping <webmaster@hartwork.org>
  5. **/
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <stdio.h>
  9. #include <stdarg.h>
  10. #include <assert.h>
  11. #include <ctype.h>
  12. #include "ILexer.h"
  13. #include "Scintilla.h"
  14. #include "SciLexer.h"
  15. #include "WordList.h"
  16. #include "LexAccessor.h"
  17. #include "Accessor.h"
  18. #include "StyleContext.h"
  19. #include "CharacterSet.h"
  20. #include "LexerModule.h"
  21. #ifdef SCI_NAMESPACE
  22. using namespace Scintilla;
  23. #endif
  24. inline static void getRange( Sci_PositionU start, Sci_PositionU end, Accessor & styler, char * s, Sci_PositionU len )
  25. {
  26. Sci_PositionU i = 0;
  27. while( ( i < end - start + 1 ) && ( i < len - 1 ) )
  28. {
  29. s[i] = static_cast<char>( styler[ start + i ] );
  30. i++;
  31. }
  32. s[ i ] = '\0';
  33. }
  34. inline bool HandleString( Sci_PositionU & cur, Sci_PositionU one_too_much, Accessor & styler )
  35. {
  36. char ch;
  37. // Wait for string to close
  38. bool even_backslash_count = true; // Without gaps in between
  39. cur++; // Skip initial quote
  40. for( ; ; )
  41. {
  42. if( cur >= one_too_much )
  43. {
  44. styler.ColourTo( cur - 1, SCE_OPAL_STRING );
  45. return false; // STOP
  46. }
  47. ch = styler.SafeGetCharAt( cur );
  48. if( ( ch == '\015' ) || ( ch == '\012' ) ) // Deny multi-line strings
  49. {
  50. styler.ColourTo( cur - 1, SCE_OPAL_STRING );
  51. styler.StartSegment( cur );
  52. return true;
  53. }
  54. else
  55. {
  56. if( even_backslash_count )
  57. {
  58. if( ch == '"' )
  59. {
  60. styler.ColourTo( cur, SCE_OPAL_STRING );
  61. cur++;
  62. if( cur >= one_too_much )
  63. {
  64. return false; // STOP
  65. }
  66. else
  67. {
  68. styler.StartSegment( cur );
  69. return true;
  70. }
  71. }
  72. else if( ch == '\\' )
  73. {
  74. even_backslash_count = false;
  75. }
  76. }
  77. else
  78. {
  79. even_backslash_count = true;
  80. }
  81. }
  82. cur++;
  83. }
  84. }
  85. inline bool HandleCommentBlock( Sci_PositionU & cur, Sci_PositionU one_too_much, Accessor & styler, bool could_fail )
  86. {
  87. char ch;
  88. if( could_fail )
  89. {
  90. cur++;
  91. if( cur >= one_too_much )
  92. {
  93. styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
  94. return false; // STOP
  95. }
  96. ch = styler.SafeGetCharAt( cur );
  97. if( ch != '*' )
  98. {
  99. styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
  100. styler.StartSegment( cur );
  101. return true;
  102. }
  103. }
  104. // Wait for comment close
  105. cur++;
  106. bool star_found = false;
  107. for( ; ; )
  108. {
  109. if( cur >= one_too_much )
  110. {
  111. styler.ColourTo( cur - 1, SCE_OPAL_COMMENT_BLOCK );
  112. return false; // STOP
  113. }
  114. ch = styler.SafeGetCharAt( cur );
  115. if( star_found )
  116. {
  117. if( ch == '/' )
  118. {
  119. styler.ColourTo( cur, SCE_OPAL_COMMENT_BLOCK );
  120. cur++;
  121. if( cur >= one_too_much )
  122. {
  123. return false; // STOP
  124. }
  125. else
  126. {
  127. styler.StartSegment( cur );
  128. return true;
  129. }
  130. }
  131. else if( ch != '*' )
  132. {
  133. star_found = false;
  134. }
  135. }
  136. else if( ch == '*' )
  137. {
  138. star_found = true;
  139. }
  140. cur++;
  141. }
  142. }
  143. inline bool HandleCommentLine( Sci_PositionU & cur, Sci_PositionU one_too_much, Accessor & styler, bool could_fail )
  144. {
  145. char ch;
  146. if( could_fail )
  147. {
  148. cur++;
  149. if( cur >= one_too_much )
  150. {
  151. styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
  152. return false; // STOP
  153. }
  154. ch = styler.SafeGetCharAt( cur );
  155. if( ch != '-' )
  156. {
  157. styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
  158. styler.StartSegment( cur );
  159. return true;
  160. }
  161. cur++;
  162. if( cur >= one_too_much )
  163. {
  164. styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
  165. return false; // STOP
  166. }
  167. ch = styler.SafeGetCharAt( cur );
  168. if( ( ch != ' ' ) && ( ch != '\t' ) )
  169. {
  170. styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
  171. styler.StartSegment( cur );
  172. return true;
  173. }
  174. }
  175. // Wait for end of line
  176. bool fifteen_found = false;
  177. for( ; ; )
  178. {
  179. cur++;
  180. if( cur >= one_too_much )
  181. {
  182. styler.ColourTo( cur - 1, SCE_OPAL_COMMENT_LINE );
  183. return false; // STOP
  184. }
  185. ch = styler.SafeGetCharAt( cur );
  186. if( fifteen_found )
  187. {
  188. /*
  189. if( ch == '\012' )
  190. {
  191. // One newline on Windows (015, 012)
  192. }
  193. else
  194. {
  195. // One newline on MAC (015) and another char
  196. }
  197. */
  198. cur--;
  199. styler.ColourTo( cur - 1, SCE_OPAL_COMMENT_LINE );
  200. styler.StartSegment( cur );
  201. return true;
  202. }
  203. else
  204. {
  205. if( ch == '\015' )
  206. {
  207. fifteen_found = true;
  208. }
  209. else if( ch == '\012' )
  210. {
  211. // One newline on Linux (012)
  212. styler.ColourTo( cur - 1, SCE_OPAL_COMMENT_LINE );
  213. styler.StartSegment( cur );
  214. return true;
  215. }
  216. }
  217. }
  218. }
  219. inline bool HandlePar( Sci_PositionU & cur, Accessor & styler )
  220. {
  221. styler.ColourTo( cur, SCE_OPAL_PAR );
  222. cur++;
  223. styler.StartSegment( cur );
  224. return true;
  225. }
  226. inline bool HandleSpace( Sci_PositionU & cur, Sci_PositionU one_too_much, Accessor & styler )
  227. {
  228. char ch;
  229. cur++;
  230. for( ; ; )
  231. {
  232. if( cur >= one_too_much )
  233. {
  234. styler.ColourTo( cur - 1, SCE_OPAL_SPACE );
  235. return false;
  236. }
  237. ch = styler.SafeGetCharAt( cur );
  238. switch( ch )
  239. {
  240. case ' ':
  241. case '\t':
  242. case '\015':
  243. case '\012':
  244. cur++;
  245. break;
  246. default:
  247. styler.ColourTo( cur - 1, SCE_OPAL_SPACE );
  248. styler.StartSegment( cur );
  249. return true;
  250. }
  251. }
  252. }
  253. inline bool HandleInteger( Sci_PositionU & cur, Sci_PositionU one_too_much, Accessor & styler )
  254. {
  255. char ch;
  256. for( ; ; )
  257. {
  258. cur++;
  259. if( cur >= one_too_much )
  260. {
  261. styler.ColourTo( cur - 1, SCE_OPAL_INTEGER );
  262. return false; // STOP
  263. }
  264. ch = styler.SafeGetCharAt( cur );
  265. if( !( IsASCII( ch ) && isdigit( ch ) ) )
  266. {
  267. styler.ColourTo( cur - 1, SCE_OPAL_INTEGER );
  268. styler.StartSegment( cur );
  269. return true;
  270. }
  271. }
  272. }
  273. inline bool HandleWord( Sci_PositionU & cur, Sci_PositionU one_too_much, Accessor & styler, WordList * keywordlists[] )
  274. {
  275. char ch;
  276. const Sci_PositionU beg = cur;
  277. cur++;
  278. for( ; ; )
  279. {
  280. ch = styler.SafeGetCharAt( cur );
  281. if( ( ch != '_' ) && ( ch != '-' ) &&
  282. !( IsASCII( ch ) && ( islower( ch ) || isupper( ch ) || isdigit( ch ) ) ) ) break;
  283. cur++;
  284. if( cur >= one_too_much )
  285. {
  286. break;
  287. }
  288. }
  289. const Sci_Position ide_len = cur - beg + 1;
  290. char * ide = new char[ ide_len ];
  291. getRange( beg, cur, styler, ide, ide_len );
  292. WordList & keywords = *keywordlists[ 0 ];
  293. WordList & classwords = *keywordlists[ 1 ];
  294. if( keywords.InList( ide ) ) // Keyword
  295. {
  296. delete [] ide;
  297. styler.ColourTo( cur - 1, SCE_OPAL_KEYWORD );
  298. if( cur >= one_too_much )
  299. {
  300. return false; // STOP
  301. }
  302. else
  303. {
  304. styler.StartSegment( cur );
  305. return true;
  306. }
  307. }
  308. else if( classwords.InList( ide ) ) // Sort
  309. {
  310. delete [] ide;
  311. styler.ColourTo( cur - 1, SCE_OPAL_SORT );
  312. if( cur >= one_too_much )
  313. {
  314. return false; // STOP
  315. }
  316. else
  317. {
  318. styler.StartSegment( cur );
  319. return true;
  320. }
  321. }
  322. else if( !strcmp( ide, "true" ) || !strcmp( ide, "false" ) ) // Bool const
  323. {
  324. delete [] ide;
  325. styler.ColourTo( cur - 1, SCE_OPAL_BOOL_CONST );
  326. if( cur >= one_too_much )
  327. {
  328. return false; // STOP
  329. }
  330. else
  331. {
  332. styler.StartSegment( cur );
  333. return true;
  334. }
  335. }
  336. else // Unknown keyword
  337. {
  338. delete [] ide;
  339. styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
  340. if( cur >= one_too_much )
  341. {
  342. return false; // STOP
  343. }
  344. else
  345. {
  346. styler.StartSegment( cur );
  347. return true;
  348. }
  349. }
  350. }
  351. inline bool HandleSkip( Sci_PositionU & cur, Sci_PositionU one_too_much, Accessor & styler )
  352. {
  353. cur++;
  354. styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
  355. if( cur >= one_too_much )
  356. {
  357. return false; // STOP
  358. }
  359. else
  360. {
  361. styler.StartSegment( cur );
  362. return true;
  363. }
  364. }
  365. static void ColouriseOpalDoc( Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[], Accessor & styler )
  366. {
  367. styler.StartAt( startPos );
  368. styler.StartSegment( startPos );
  369. Sci_PositionU & cur = startPos;
  370. const Sci_PositionU one_too_much = startPos + length;
  371. int state = initStyle;
  372. for( ; ; )
  373. {
  374. switch( state )
  375. {
  376. case SCE_OPAL_KEYWORD:
  377. case SCE_OPAL_SORT:
  378. if( !HandleWord( cur, one_too_much, styler, keywordlists ) ) return;
  379. state = SCE_OPAL_DEFAULT;
  380. break;
  381. case SCE_OPAL_INTEGER:
  382. if( !HandleInteger( cur, one_too_much, styler ) ) return;
  383. state = SCE_OPAL_DEFAULT;
  384. break;
  385. case SCE_OPAL_COMMENT_BLOCK:
  386. if( !HandleCommentBlock( cur, one_too_much, styler, false ) ) return;
  387. state = SCE_OPAL_DEFAULT;
  388. break;
  389. case SCE_OPAL_COMMENT_LINE:
  390. if( !HandleCommentLine( cur, one_too_much, styler, false ) ) return;
  391. state = SCE_OPAL_DEFAULT;
  392. break;
  393. case SCE_OPAL_STRING:
  394. if( !HandleString( cur, one_too_much, styler ) ) return;
  395. state = SCE_OPAL_DEFAULT;
  396. break;
  397. default: // SCE_OPAL_DEFAULT:
  398. {
  399. char ch = styler.SafeGetCharAt( cur );
  400. switch( ch )
  401. {
  402. // String
  403. case '"':
  404. if( !HandleString( cur, one_too_much, styler ) ) return;
  405. break;
  406. // Comment block
  407. case '/':
  408. if( !HandleCommentBlock( cur, one_too_much, styler, true ) ) return;
  409. break;
  410. // Comment line
  411. case '-':
  412. if( !HandleCommentLine( cur, one_too_much, styler, true ) ) return;
  413. break;
  414. // Par
  415. case '(':
  416. case ')':
  417. case '[':
  418. case ']':
  419. case '{':
  420. case '}':
  421. if( !HandlePar( cur, styler ) ) return;
  422. break;
  423. // Whitespace
  424. case ' ':
  425. case '\t':
  426. case '\015':
  427. case '\012':
  428. if( !HandleSpace( cur, one_too_much, styler ) ) return;
  429. break;
  430. default:
  431. {
  432. // Integer
  433. if( IsASCII( ch ) && isdigit( ch ) )
  434. {
  435. if( !HandleInteger( cur, one_too_much, styler ) ) return;
  436. }
  437. // Keyword
  438. else if( IsASCII( ch ) && ( islower( ch ) || isupper( ch ) ) )
  439. {
  440. if( !HandleWord( cur, one_too_much, styler, keywordlists ) ) return;
  441. }
  442. // Skip
  443. else
  444. {
  445. if( !HandleSkip( cur, one_too_much, styler ) ) return;
  446. }
  447. }
  448. }
  449. break;
  450. }
  451. }
  452. }
  453. }
  454. static const char * const opalWordListDesc[] = {
  455. "Keywords",
  456. "Sorts",
  457. 0
  458. };
  459. LexerModule lmOpal(SCLEX_OPAL, ColouriseOpalDoc, "opal", NULL, opalWordListDesc);