]>
git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/LexHaskell.cxx
095675ee5b9c605e07c6d534622d57a4b895e064
1 /******************************************************************
4 * A haskell lexer for the scintilla code control.
5 * Some stuff "lended" from LexPython.cxx and LexCPP.cxx.
6 * External lexer stuff inspired from the caml external lexer.
8 * Written by Tobias Engvall - tumm at dtek dot chalmers dot se
12 * * Implement a folder :)
13 * * Nice Character-lexing (stuff inside '\''), LexPython has
17 *****************************************************************/
29 #include "StyleContext.h"
31 #include "Scintilla.h"
35 using namespace Scintilla
;
38 #ifdef BUILD_AS_EXTERNAL_LEXER
40 #include "ExternalLexer.h"
41 #include "WindowAccessor.h"
43 #define BUILD_EXTERNAL_LEXER 0
47 // Max level of nested comments
48 #define SCE_HA_COMMENTMAX SCE_HA_COMMENTBLOCK3
51 enum kwType
{ kwOther
, kwClass
, kwData
, kwInstance
, kwImport
, kwModule
, kwType
};
53 static inline bool IsNewline(const int ch
) {
54 return (ch
== '\n' || ch
== '\r');
57 static inline bool IsWhitespace(const int ch
) {
63 static inline bool IsAWordStart(const int ch
) {
64 return (ch
< 0x80) && (isalnum(ch
) || ch
== '_');
67 static inline bool IsAWordChar(const int ch
) {
68 return (ch
< 0x80) && (isalnum(ch
) || ch
== '.' || ch
== '_' || ch
== '\'');
71 static void ColorizeHaskellDoc(unsigned int startPos
, int length
, int initStyle
,
72 WordList
*keywordlists
[], Accessor
&styler
) {
74 WordList
&keywords
= *keywordlists
[0];
78 StyleContext
sc(startPos
, length
, initStyle
, styler
);
80 for (; sc
.More(); sc
.Forward()) {
82 // Check for state end
84 if (sc
.state
== SCE_HA_OPERATOR
) {
86 sc
.SetState(SCE_HA_DEFAULT
);
89 else if (sc
.state
== SCE_HA_STRING
) {
91 sc
.ForwardSetState(SCE_HA_DEFAULT
);
92 } else if (sc
.ch
== '\\') {
97 else if (sc
.state
== SCE_HA_CHARACTER
) {
99 sc
.ForwardSetState(SCE_HA_DEFAULT
);
100 } else if (sc
.ch
== '\\') {
105 else if (sc
.state
== SCE_HA_NUMBER
) {
106 if (!IsADigit(sc
.ch
)) {
107 sc
.SetState(SCE_HA_DEFAULT
);
110 // Types, constructors, etc.
111 else if (sc
.state
== SCE_HA_CAPITAL
) {
112 if (!IsAWordChar(sc
.ch
) || sc
.ch
== '.') {
113 sc
.SetState(SCE_HA_DEFAULT
);
117 else if (sc
.state
== SCE_HA_IDENTIFIER
) {
118 if (!IsAWordChar(sc
.ch
)) {
120 sc
.GetCurrent(s
, sizeof(s
));
121 int style
= SCE_HA_IDENTIFIER
;
122 if ((kwLast
== kwImport
) || (strcmp(s
,"qualified") == 0) || (strcmp(s
,"as") == 0)) {
123 style
= SCE_HA_IMPORT
;
124 } else if (keywords
.InList(s
)) {
125 style
= SCE_HA_KEYWORD
;
126 } else if (kwLast
== kwData
) {
128 } else if (kwLast
== kwClass
) {
129 style
= SCE_HA_CLASS
;
130 } else if (kwLast
== kwModule
) {
131 style
= SCE_HA_MODULE
;
132 } else if (isupper(s
[0])) {
133 style
= SCE_HA_CAPITAL
;
135 sc
.ChangeState(style
);
136 sc
.SetState(SCE_HA_DEFAULT
);
137 if (style
== SCE_HA_KEYWORD
) {
138 if (0 == strcmp(s
, "class"))
140 else if (0 == strcmp(s
, "data"))
142 else if (0 == strcmp(s
, "instance"))
144 else if (0 == strcmp(s
, "import"))
146 else if (0 == strcmp(s
, "module"))
150 } else if (style
== SCE_HA_CLASS
|| style
== SCE_HA_IMPORT
||
151 style
== SCE_HA_MODULE
|| style
== SCE_HA_CAPITAL
||
152 style
== SCE_HA_DATA
|| style
== SCE_HA_INSTANCE
) {
159 else if (sc
.state
== SCE_HA_COMMENTLINE
) {
160 if (IsNewline(sc
.ch
))
161 sc
.SetState(SCE_HA_DEFAULT
);
164 else if (sc
.state
>= SCE_HA_COMMENTBLOCK
) {
165 if (sc
.Match("{-")) {
166 if (sc
.state
< SCE_HA_COMMENTMAX
)
167 sc
.SetState(sc
.state
+ 1);
169 else if (sc
.Match("-}")) {
171 if (sc
.state
== SCE_HA_COMMENTBLOCK
)
172 sc
.ForwardSetState(SCE_HA_DEFAULT
);
174 sc
.ForwardSetState(sc
.state
- 1);
178 if (sc
.state
== SCE_HA_DEFAULT
) {
180 if (IsADigit(sc
.ch
) || (sc
.ch
== '.' && IsADigit(sc
.chNext
))) {
181 sc
.SetState(SCE_HA_NUMBER
);
184 else if (sc
.Match("--")) {
185 sc
.SetState(SCE_HA_COMMENTLINE
);
188 else if (sc
.Match("{-")) {
189 sc
.SetState(SCE_HA_COMMENTBLOCK
);
192 else if (sc
.Match('\"')) {
193 sc
.SetState(SCE_HA_STRING
);
196 else if (sc
.Match('\'')) {
197 sc
.SetState(SCE_HA_CHARACTER
);
200 else if (sc
.Match('\"')) {
201 sc
.SetState(SCE_HA_STRING
);
204 else if (isascii(sc
.ch
) && isoperator(static_cast<char>(sc
.ch
))) {
205 sc
.SetState(SCE_HA_OPERATOR
);
208 else if (IsAWordStart(sc
.ch
)) {
209 sc
.SetState(SCE_HA_IDENTIFIER
);
217 // External stuff - used for dynamic-loading, not implemented in wxStyledTextCtrl yet.
218 // Inspired by the caml external lexer - Credits to Robert Roessler - http://www.rftp.com
219 #ifdef BUILD_EXTERNAL_LEXER
220 static const char* LexerName
= "haskell";
222 void EXT_LEXER_DECL
Lex(unsigned int lexer
, unsigned int startPos
, int length
, int initStyle
,
223 char *words
[], WindowID window
, char *props
)
226 ps
.SetMultiple(props
);
227 WindowAccessor
wa(window
, ps
);
230 for (; words
[nWL
]; nWL
++) ;
231 WordList
** wl
= new WordList
* [nWL
+ 1];
235 wl
[i
] = new WordList();
236 wl
[i
]->Set(words
[i
]);
240 ColorizeHaskellDoc(startPos
, length
, initStyle
, wl
, wa
);
242 for (i
=nWL
-1;i
>=0;i
--)
247 void EXT_LEXER_DECL
Fold (unsigned int lexer
, unsigned int startPos
, int length
, int initStyle
,
248 char *words
[], WindowID window
, char *props
)
253 int EXT_LEXER_DECL
GetLexerCount()
258 void EXT_LEXER_DECL
GetLexerName(unsigned int Index
, char *name
, int buflength
)
262 int n
= strlen(LexerName
);
265 memcpy(name
, LexerName
, n
), name
[n
] = '\0';
270 LexerModule
lmHaskell(SCLEX_HASKELL
, ColorizeHaskellDoc
, "haskell");