1 | // Scintilla source code edit control |
2 | /** @file LexKix.cxx |
3 | ** Lexer for KIX-Scripts. |
4 | **/ |
5 | // Copyright 2004 by Manfred Becker <manfred@becker-trdf.de> |
6 | // The License.txt file describes the conditions under which this software may be distributed. |
7 | // Edited by Lee Wilmott (24-Jun-2014) added support for block comments |
8 | |
9 | #include <stdlib.h> |
10 | #include <string.h> |
11 | #include <stdio.h> |
12 | #include <stdarg.h> |
13 | #include <assert.h> |
14 | #include <ctype.h> |
15 | |
16 | #include <string> |
17 | #include <string_view> |
18 | |
19 | #include "ILexer.h" |
20 | #include "Scintilla.h" |
21 | #include "SciLexer.h" |
22 | |
23 | #include "WordList.h" |
24 | #include "LexAccessor.h" |
25 | #include "Accessor.h" |
26 | #include "StyleContext.h" |
27 | #include "CharacterSet.h" |
28 | #include "LexerModule.h" |
29 | |
30 | using namespace Lexilla; |
31 | |
32 | // Extended to accept accented characters |
33 | static inline bool IsAWordChar(int ch) { |
34 | return ch >= 0x80 || isalnum(ch) || ch == '_'; |
35 | } |
36 | |
37 | static inline bool IsOperator(const int ch) { |
38 | return (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '&' || ch == '|' || ch == '<' || ch == '>' || ch == '='); |
39 | } |
40 | |
41 | static void ColouriseKixDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, |
42 | WordList *keywordlists[], Accessor &styler) { |
43 | |
44 | WordList &keywords = *keywordlists[0]; |
45 | WordList &keywords2 = *keywordlists[1]; |
46 | WordList &keywords3 = *keywordlists[2]; |
47 | // WordList &keywords4 = *keywordlists[3]; |
48 | |
49 | styler.StartAt(startPos); |
50 | |
51 | StyleContext sc(startPos, length, initStyle, styler); |
52 | |
53 | for (; sc.More(); sc.Forward()) { |
54 | |
55 | if (sc.state == SCE_KIX_COMMENT) { |
56 | if (sc.atLineEnd) { |
57 | sc.SetState(SCE_KIX_DEFAULT); |
58 | } |
59 | } else if (sc.state == SCE_KIX_COMMENTSTREAM) { |
60 | if (sc.ch == '/' && sc.chPrev == '*') { |
61 | sc.ForwardSetState(SCE_KIX_DEFAULT); |
62 | } |
63 | } else if (sc.state == SCE_KIX_STRING1) { |
64 | // This is a doubles quotes string |
65 | if (sc.ch == '\"') { |
66 | sc.ForwardSetState(SCE_KIX_DEFAULT); |
67 | } |
68 | } else if (sc.state == SCE_KIX_STRING2) { |
69 | // This is a single quote string |
70 | if (sc.ch == '\'') { |
71 | sc.ForwardSetState(SCE_KIX_DEFAULT); |
72 | } |
73 | } else if (sc.state == SCE_KIX_NUMBER) { |
74 | if (!IsADigit(sc.ch)) { |
75 | sc.SetState(SCE_KIX_DEFAULT); |
76 | } |
77 | } else if (sc.state == SCE_KIX_VAR) { |
78 | if (!IsAWordChar(sc.ch)) { |
79 | sc.SetState(SCE_KIX_DEFAULT); |
80 | } |
81 | } else if (sc.state == SCE_KIX_MACRO) { |
82 | if (!IsAWordChar(sc.ch) && !IsADigit(sc.ch)) { |
83 | char s[100]; |
84 | sc.GetCurrentLowered(s, sizeof(s)); |
85 | |
86 | if (!keywords3.InList(&s[1])) { |
87 | sc.ChangeState(SCE_KIX_DEFAULT); |
88 | } |
89 | sc.SetState(SCE_KIX_DEFAULT); |
90 | } |
91 | } else if (sc.state == SCE_KIX_OPERATOR) { |
92 | if (!IsOperator(sc.ch)) { |
93 | sc.SetState(SCE_KIX_DEFAULT); |
94 | } |
95 | } else if (sc.state == SCE_KIX_IDENTIFIER) { |
96 | if (!IsAWordChar(sc.ch)) { |
97 | char s[100]; |
98 | sc.GetCurrentLowered(s, sizeof(s)); |
99 | |
100 | if (keywords.InList(s)) { |
101 | sc.ChangeState(SCE_KIX_KEYWORD); |
102 | } else if (keywords2.InList(s)) { |
103 | sc.ChangeState(SCE_KIX_FUNCTIONS); |
104 | } |
105 | sc.SetState(SCE_KIX_DEFAULT); |
106 | } |
107 | } |
108 | |
109 | // Determine if a new state should be entered. |
110 | if (sc.state == SCE_KIX_DEFAULT) { |
111 | if (sc.ch == ';') { |
112 | sc.SetState(SCE_KIX_COMMENT); |
113 | } else if (sc.ch == '/' && sc.chNext == '*') { |
114 | sc.SetState(SCE_KIX_COMMENTSTREAM); |
115 | } else if (sc.ch == '\"') { |
116 | sc.SetState(SCE_KIX_STRING1); |
117 | } else if (sc.ch == '\'') { |
118 | sc.SetState(SCE_KIX_STRING2); |
119 | } else if (sc.ch == '$') { |
120 | sc.SetState(SCE_KIX_VAR); |
121 | } else if (sc.ch == '@') { |
122 | sc.SetState(SCE_KIX_MACRO); |
123 | } else if (IsADigit(sc.ch) || ((sc.ch == '.' || sc.ch == '&') && IsADigit(sc.chNext))) { |
124 | sc.SetState(SCE_KIX_NUMBER); |
125 | } else if (IsOperator(sc.ch)) { |
126 | sc.SetState(SCE_KIX_OPERATOR); |
127 | } else if (IsAWordChar(sc.ch)) { |
128 | sc.SetState(SCE_KIX_IDENTIFIER); |
129 | } |
130 | } |
131 | } |
132 | sc.Complete(); |
133 | } |
134 | |
135 | |
136 | LexerModule lmKix(SCLEX_KIX, ColouriseKixDoc, "kix" ); |
137 | |
138 | |