~ubuntu-branches/ubuntu/raring/geany/raring-proposed

« back to all changes in this revision

Viewing changes to scintilla/LexHaskell.cxx

  • Committer: Bazaar Package Importer
  • Author(s): Damián Viano
  • Date: 2008-05-02 11:37:45 UTC
  • mfrom: (1.2.1 upstream) (9 hardy)
  • mto: (3.2.1 squeeze)
  • mto: This revision was merged to the branch mainline in revision 12.
  • Revision ID: james.westby@ubuntu.com-20080502113745-xzp4g6dmovrpoj17
Tags: 0.14-1
New upstream release (Closes: #478126)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/******************************************************************
 
2
 *    LexHaskell.cxx
 
3
 *
 
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.
 
7
 *
 
8
 *    Written by Tobias Engvall - tumm at dtek dot chalmers dot se
 
9
 *
 
10
 *
 
11
 *    TODO:
 
12
 *    * Implement a folder :)
 
13
 *    * Nice Character-lexing (stuff inside '\''), LexPython has
 
14
 *      this.
 
15
 *
 
16
 *
 
17
 *****************************************************************/
 
18
 
 
19
#include <stdlib.h>
 
20
#include <string.h>
 
21
#include <ctype.h>
 
22
#include <stdio.h>
 
23
#include <stdarg.h>
 
24
 
 
25
#include "Platform.h"
 
26
 
 
27
#include "PropSet.h"
 
28
#include "Accessor.h"
 
29
#include "StyleContext.h"
 
30
#include "KeyWords.h"
 
31
#include "Scintilla.h"
 
32
#include "SciLexer.h"
 
33
 
 
34
#ifdef SCI_NAMESPACE
 
35
using namespace Scintilla;
 
36
#endif
 
37
 
 
38
#ifdef BUILD_AS_EXTERNAL_LEXER
 
39
 
 
40
#include "ExternalLexer.h"
 
41
#include "WindowAccessor.h"
 
42
 
 
43
#define BUILD_EXTERNAL_LEXER 0
 
44
 
 
45
#endif
 
46
 
 
47
// Max level of nested comments
 
48
#define SCE_HA_COMMENTMAX SCE_HA_COMMENTBLOCK3
 
49
 
 
50
 
 
51
enum kwType { kwOther, kwClass, kwData, kwInstance, kwImport, kwModule, kwType};
 
52
 
 
53
static inline bool IsNewline(const int ch) {
 
54
   return (ch == '\n' || ch == '\r');
 
55
}
 
56
 
 
57
static inline bool IsWhitespace(const int ch) {
 
58
   return (  ch == ' '
 
59
          || ch == '\t'
 
60
          || IsNewline(ch) );
 
61
}
 
62
 
 
63
static inline bool IsAWordStart(const int ch) {
 
64
   return (ch < 0x80) && (isalnum(ch) || ch == '_');
 
65
}
 
66
 
 
67
static inline bool IsAWordChar(const int ch) {
 
68
   return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '\'');
 
69
}
 
70
 
 
71
static void ColorizeHaskellDoc(unsigned int startPos, int length, int initStyle,
 
72
                               WordList *keywordlists[], Accessor &styler) {
 
73
 
 
74
   WordList &keywords = *keywordlists[0];
 
75
 
 
76
   int kwLast = kwOther;
 
77
 
 
78
   StyleContext sc(startPos, length, initStyle, styler);
 
79
 
 
80
   for (; sc.More(); sc.Forward()) {
 
81
 
 
82
      // Check for state end
 
83
         // Operator
 
84
      if (sc.state == SCE_HA_OPERATOR) {
 
85
         kwLast = kwOther;
 
86
         sc.SetState(SCE_HA_DEFAULT);
 
87
      }
 
88
         // String
 
89
      else if (sc.state == SCE_HA_STRING) {
 
90
         if (sc.ch == '\"') {
 
91
            sc.ForwardSetState(SCE_HA_DEFAULT);
 
92
         } else if (sc.ch == '\\') {
 
93
            sc.Forward();
 
94
         }
 
95
      }
 
96
         // Char
 
97
      else if (sc.state == SCE_HA_CHARACTER) {
 
98
         if (sc.ch == '\'') {
 
99
            sc.ForwardSetState(SCE_HA_DEFAULT);
 
100
         } else if (sc.ch == '\\') {
 
101
            sc.Forward();
 
102
         }
 
103
      }
 
104
         // Number
 
105
      else if (sc.state == SCE_HA_NUMBER) {
 
106
         if (!IsADigit(sc.ch)) {
 
107
            sc.SetState(SCE_HA_DEFAULT);
 
108
         }
 
109
      }
 
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);
 
114
         }
 
115
      }
 
116
         // Identifier
 
117
      else if (sc.state == SCE_HA_IDENTIFIER) {
 
118
         if (!IsAWordChar(sc.ch)) {
 
119
            char s[100];
 
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) {
 
127
               style = SCE_HA_DATA;
 
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;
 
134
            }
 
135
            sc.ChangeState(style);
 
136
            sc.SetState(SCE_HA_DEFAULT);
 
137
            if (style == SCE_HA_KEYWORD) {
 
138
               if (0 == strcmp(s, "class"))
 
139
                  kwLast = kwClass;
 
140
               else if (0 == strcmp(s, "data"))
 
141
                  kwLast = kwData;
 
142
               else if (0 == strcmp(s, "instance"))
 
143
                  kwLast = kwInstance;
 
144
               else if (0 == strcmp(s, "import"))
 
145
                  kwLast = kwImport;
 
146
               else if (0 == strcmp(s, "module"))
 
147
                  kwLast = kwModule;
 
148
               else
 
149
                  kwLast = kwOther;
 
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) {
 
153
               kwLast = kwOther;
 
154
            }
 
155
         }
 
156
      }
 
157
         // Comments
 
158
            // Oneliner
 
159
      else if (sc.state == SCE_HA_COMMENTLINE) {
 
160
         if (IsNewline(sc.ch))
 
161
            sc.SetState(SCE_HA_DEFAULT);
 
162
      }
 
163
            // Nested
 
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);
 
168
         }
 
169
         else if (sc.Match("-}")) {
 
170
            sc.Forward();
 
171
            if (sc.state == SCE_HA_COMMENTBLOCK)
 
172
               sc.ForwardSetState(SCE_HA_DEFAULT);
 
173
            else
 
174
               sc.ForwardSetState(sc.state - 1);
 
175
         }
 
176
      }
 
177
      // New state?
 
178
      if (sc.state == SCE_HA_DEFAULT) {
 
179
         // Digit
 
180
         if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
 
181
            sc.SetState(SCE_HA_NUMBER);
 
182
         }
 
183
         // Comment line
 
184
         else if (sc.Match("--")) {
 
185
            sc.SetState(SCE_HA_COMMENTLINE);
 
186
         // Comment block
 
187
         }
 
188
         else if (sc.Match("{-")) {
 
189
            sc.SetState(SCE_HA_COMMENTBLOCK);
 
190
         }
 
191
         // String
 
192
         else if (sc.Match('\"')) {
 
193
            sc.SetState(SCE_HA_STRING);
 
194
         }
 
195
         // Character
 
196
         else if (sc.Match('\'')) {
 
197
            sc.SetState(SCE_HA_CHARACTER);
 
198
         }
 
199
         // Stringstart
 
200
         else if (sc.Match('\"')) {
 
201
            sc.SetState(SCE_HA_STRING);
 
202
         }
 
203
         // Operator
 
204
         else if (isascii(sc.ch) && isoperator(static_cast<char>(sc.ch))) {
 
205
            sc.SetState(SCE_HA_OPERATOR);
 
206
         }
 
207
         // Keyword
 
208
         else if (IsAWordStart(sc.ch)) {
 
209
               sc.SetState(SCE_HA_IDENTIFIER);
 
210
         }
 
211
 
 
212
      }
 
213
   }
 
214
   sc.Complete();
 
215
}
 
216
 
 
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";
 
221
 
 
222
void EXT_LEXER_DECL Lex(unsigned int lexer, unsigned int startPos, int length, int initStyle,
 
223
                        char *words[], WindowID window, char *props)
 
224
{
 
225
   PropSet ps;
 
226
   ps.SetMultiple(props);
 
227
   WindowAccessor wa(window, ps);
 
228
 
 
229
   int nWL = 0;
 
230
   for (; words[nWL]; nWL++) ;
 
231
   WordList** wl = new WordList* [nWL + 1];
 
232
   int i = 0;
 
233
   for (; i<nWL; i++)
 
234
   {
 
235
      wl[i] = new WordList();
 
236
      wl[i]->Set(words[i]);
 
237
   }
 
238
   wl[i] = 0;
 
239
 
 
240
   ColorizeHaskellDoc(startPos, length, initStyle, wl, wa);
 
241
   wa.Flush();
 
242
   for (i=nWL-1;i>=0;i--)
 
243
      delete wl[i];
 
244
   delete [] wl;
 
245
}
 
246
 
 
247
void EXT_LEXER_DECL Fold (unsigned int lexer, unsigned int startPos, int length, int initStyle,
 
248
                        char *words[], WindowID window, char *props)
 
249
{
 
250
 
 
251
}
 
252
 
 
253
int EXT_LEXER_DECL GetLexerCount()
 
254
{
 
255
   return 1;
 
256
}
 
257
 
 
258
void EXT_LEXER_DECL GetLexerName(unsigned int Index, char *name, int buflength)
 
259
{
 
260
   if (buflength > 0) {
 
261
      buflength--;
 
262
      int n = strlen(LexerName);
 
263
      if (n > buflength)
 
264
         n = buflength;
 
265
      memcpy(name, LexerName, n), name[n] = '\0';
 
266
   }
 
267
}
 
268
#endif
 
269
 
 
270
LexerModule lmHaskell(SCLEX_HASKELL, ColorizeHaskellDoc, "haskell");
 
271