1 // Scintilla source code edit control
2 /** @file LexSorcus.cxx
3 ** Lexer for SORCUS installation files
4 ** Written by Eugen Bitter and Christoph Baumann at SORCUS Computer, Heidelberg Germany
5 ** Based on the ASM Lexer by The Black Horus
6 **/
7 
8 // The License.txt file describes the conditions under which this software may be distributed.
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 
17 #include "ILexer.h"
18 #include "Scintilla.h"
19 #include "SciLexer.h"
20 
21 #include "WordList.h"
22 #include "LexAccessor.h"
23 #include "Accessor.h"
24 #include "StyleContext.h"
25 #include "CharacterSet.h"
26 #include "LexerModule.h"
27 
28 #ifdef SCI_NAMESPACE
29 using namespace Scintilla;
30 #endif
31 
32 
33 //each character a..z and A..Z + '_' can be part of a keyword
34 //additionally numbers that follow 'M' can be contained in a keyword
IsSWordStart(const int ch,const int prev_ch)35 static inline bool IsSWordStart(const int ch, const int prev_ch)
36 {
37     if (isalpha(ch) || (ch == '_') || ((isdigit(ch)) && (prev_ch == 'M')))
38         return true;
39 
40     return false;
41 }
42 
43 
44 //only digits that are not preceded by 'M' count as a number
IsSorcusNumber(const int ch,const int prev_ch)45 static inline bool IsSorcusNumber(const int ch, const int prev_ch)
46 {
47     if ((isdigit(ch)) && (prev_ch != 'M'))
48         return true;
49 
50     return false;
51 }
52 
53 
54 //only = is a valid operator
IsSorcusOperator(const int ch)55 static inline bool IsSorcusOperator(const int ch)
56 {
57     if (ch == '=')
58         return true;
59 
60     return false;
61 }
62 
63 
ColouriseSorcusDoc(unsigned int startPos,int length,int initStyle,WordList * keywordlists[],Accessor & styler)64 static void ColouriseSorcusDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
65                                Accessor &styler)
66 {
67 
68     WordList &Command = *keywordlists[0];
69     WordList &Parameter = *keywordlists[1];
70     WordList &Constant = *keywordlists[2];
71 
72     // Do not leak onto next line
73     if (initStyle == SCE_SORCUS_STRINGEOL)
74         initStyle = SCE_SORCUS_DEFAULT;
75 
76     StyleContext sc(startPos, length, initStyle, styler);
77 
78     for (; sc.More(); sc.Forward())
79     {
80 
81         // Prevent SCE_SORCUS_STRINGEOL from leaking back to previous line
82         if (sc.atLineStart && (sc.state == SCE_SORCUS_STRING))
83         {
84             sc.SetState(SCE_SORCUS_STRING);
85         }
86 
87         // Determine if the current state should terminate.
88         if (sc.state == SCE_SORCUS_OPERATOR)
89         {
90             if (!IsSorcusOperator(sc.ch))
91             {
92                 sc.SetState(SCE_SORCUS_DEFAULT);
93             }
94         }
95         else if(sc.state == SCE_SORCUS_NUMBER)
96         {
97             if(!IsSorcusNumber(sc.ch, sc.chPrev))
98             {
99                 sc.SetState(SCE_SORCUS_DEFAULT);
100             }
101         }
102         else if (sc.state == SCE_SORCUS_IDENTIFIER)
103         {
104             if (!IsSWordStart(sc.ch, sc.chPrev))
105             {
106                 char s[100];
107 
108                 sc.GetCurrent(s, sizeof(s));
109 
110                 if (Command.InList(s))
111                 {
112                     sc.ChangeState(SCE_SORCUS_COMMAND);
113                 }
114                 else if (Parameter.InList(s))
115                 {
116                     sc.ChangeState(SCE_SORCUS_PARAMETER);
117                 }
118                 else if (Constant.InList(s))
119                 {
120                     sc.ChangeState(SCE_SORCUS_CONSTANT);
121                 }
122 
123                 sc.SetState(SCE_SORCUS_DEFAULT);
124             }
125         }
126         else if (sc.state == SCE_SORCUS_COMMENTLINE )
127         {
128             if (sc.atLineEnd)
129             {
130                 sc.SetState(SCE_SORCUS_DEFAULT);
131             }
132         }
133         else if (sc.state == SCE_SORCUS_STRING)
134         {
135             if (sc.ch == '\"')
136             {
137                 sc.ForwardSetState(SCE_SORCUS_DEFAULT);
138             }
139             else if (sc.atLineEnd)
140             {
141                 sc.ChangeState(SCE_SORCUS_STRINGEOL);
142                 sc.ForwardSetState(SCE_SORCUS_DEFAULT);
143             }
144         }
145 
146         // Determine if a new state should be entered.
147         if (sc.state == SCE_SORCUS_DEFAULT)
148         {
149             if ((sc.ch == ';') || (sc.ch == '\''))
150             {
151                 sc.SetState(SCE_SORCUS_COMMENTLINE);
152             }
153             else if (IsSWordStart(sc.ch, sc.chPrev))
154             {
155                 sc.SetState(SCE_SORCUS_IDENTIFIER);
156             }
157             else if (sc.ch == '\"')
158             {
159                 sc.SetState(SCE_SORCUS_STRING);
160             }
161             else if (IsSorcusOperator(sc.ch))
162             {
163                 sc.SetState(SCE_SORCUS_OPERATOR);
164             }
165             else if (IsSorcusNumber(sc.ch, sc.chPrev))
166             {
167                 sc.SetState(SCE_SORCUS_NUMBER);
168             }
169         }
170 
171     }
172     sc.Complete();
173 }
174 
175 
176 static const char* const SorcusWordListDesc[] = {"Command","Parameter", "Constant", 0};
177 
178 LexerModule lmSorc(SCLEX_SORCUS, ColouriseSorcusDoc, "sorcins", 0, SorcusWordListDesc);
179 
180 
181 
182 
183 
184 
185 
186 
187 
188 
189 
190 
191 
192 
193 
194 
195 
196 
197 
198 
199 
200 
201 
202 
203 
204 
205 
206 
207 
208 
209