Diff of /lexers/LexHaskell.cxx [664f32] .. [0b7306] Maximize Restore

  Switch to unified view

a/lexers/LexHaskell.cxx b/lexers/LexHaskell.cxx
...
...
6
 *    External lexer stuff inspired from the caml external lexer.
6
 *    External lexer stuff inspired from the caml external lexer.
7
 *
7
 *
8
 *    Written by Tobias Engvall - tumm at dtek dot chalmers dot se
8
 *    Written by Tobias Engvall - tumm at dtek dot chalmers dot se
9
 *
9
 *
10
 *    Several bug fixes by Krasimir Angelov - kr.angelov at gmail.com
10
 *    Several bug fixes by Krasimir Angelov - kr.angelov at gmail.com
11
 *
12
 *    Improvements by kudah - kudahkukarek at gmail.com
11
 *
13
 *
12
 *    TODO:
14
 *    TODO:
13
 *    * Implement a folder :)
15
 *    * Implement a folder :)
14
 *    * Nice Character-lexing (stuff inside '\''), LexPython has
16
 *    * Nice Character-lexing (stuff inside '\''), LexPython has
15
 *      this.
17
 *      this.
...
...
55
#define HA_MODE_IMPORT3     3
57
#define HA_MODE_IMPORT3     3
56
#define HA_MODE_MODULE      4
58
#define HA_MODE_MODULE      4
57
#define HA_MODE_FFI         5
59
#define HA_MODE_FFI         5
58
#define HA_MODE_TYPE        6
60
#define HA_MODE_TYPE        6
59
61
60
static inline bool IsNewline(const int ch) {
61
   return (ch == '\n' || ch == '\r');
62
}
63
64
static inline bool IsWhitespace(const int ch) {
65
   return (  ch == ' '
66
          || ch == '\t'
67
          || IsNewline(ch) );
68
}
69
70
static inline bool IsAWordStart(const int ch) {
62
static inline bool IsAWordStart(const int ch) {
71
   return (ch < 0x80) && (isalnum(ch) || ch == '_');
63
   return (IsLowerCase(ch) || IsUpperCase(ch) || ch == '_');
72
}
64
}
73
65
66
static inline bool IsAWordChar(const int ch, const bool magicHash) {
67
   return (  IsAlphaNumeric(ch)
68
          || ch == '_'
69
          || ch == '\''
70
          || (magicHash && ch == '#'));
71
}
72
74
static inline bool IsAWordChar(const int ch) {
73
static inline bool IsAnOperatorChar(const int ch) {
75
   return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '\'');
74
   return
75
      (  ch == '!' || ch == '#' || ch == '$' || ch == '%'
76
      || ch == '&' || ch == '*' || ch == '+' || ch == '-'
77
      || ch == '.' || ch == '/' || ch == ':' || ch == '<'
78
      || ch == '=' || ch == '>' || ch == '?' || ch == '@'
79
      || ch == '\\' || ch == '^' || ch == '|' || ch == '~');
76
}
80
}
77
81
78
static void ColorizeHaskellDoc(unsigned int startPos, int length, int initStyle,
82
static void ColorizeHaskellDoc(unsigned int startPos, int length, int initStyle,
79
                               WordList *keywordlists[], Accessor &styler) {
83
                               WordList *keywordlists[], Accessor &styler) {
80
84
81
   WordList &keywords = *keywordlists[0];
85
   WordList &keywords = *keywordlists[0];
82
   WordList &ffi      = *keywordlists[1];
86
   WordList &ffi      = *keywordlists[1];
87
88
   // property lexer.haskell.allow.hash
89
   //  Set to 1 to allow the # character in identifiers with the haskell lexer.
90
   //  (GHC -XMagicHash extension)
91
   const bool magicHash = styler.GetPropertyInt("lexer.haskell.allow.hash") != 0;
92
   const bool stylingWithinPreprocessor = styler.GetPropertyInt("styling.within.preprocessor") != 0;
83
93
84
   StyleContext sc(startPos, length, initStyle, styler);
94
   StyleContext sc(startPos, length, initStyle, styler);
85
95
86
   int lineCurrent = styler.GetLine(startPos);
96
   int lineCurrent = styler.GetLine(startPos);
87
   int state = lineCurrent ? styler.GetLineState(lineCurrent-1)
97
   int state = lineCurrent ? styler.GetLineState(lineCurrent-1)
88
                           : HA_MODE_DEFAULT;
98
                           : HA_MODE_DEFAULT;
89
   int mode  = state & 0xF;
99
   int mode  = state & 0xF;
90
   int xmode = state >> 4;
100
   int xmode = state >> 4; // obscure parameter. Means different things in different modes.
91
101
92
   while (sc.More()) {
102
   while (sc.More()) {
93
      // Check for state end
103
      // Check for state end
94
104
95
         // Operator
105
         // Operator
96
      if (sc.state == SCE_HA_OPERATOR) {
106
      if (sc.state == SCE_HA_OPERATOR) {
97
         if (isascii(sc.ch) && isoperator(static_cast<char>(sc.ch))) {
107
         int style = SCE_HA_OPERATOR;
108
109
         if (sc.ch == ':' &&
110
            // except "::"
111
            !(sc.chNext == ':' && !IsAnOperatorChar(sc.GetRelative(2)))) {
112
            style = SCE_HA_CAPITAL;
113
         }
114
115
         while(IsAnOperatorChar(sc.ch))
98
            sc.Forward();
116
               sc.Forward();
99
         } else {
117
100
            styler.ColourTo(sc.currentPos - 1, sc.state);
118
         styler.ColourTo(sc.currentPos - 1, style);
101
            sc.ChangeState(SCE_HA_DEFAULT);
119
         sc.ChangeState(SCE_HA_DEFAULT);
102
         }
103
      }
120
      }
104
         // String
121
         // String
105
      else if (sc.state == SCE_HA_STRING) {
122
      else if (sc.state == SCE_HA_STRING) {
106
         if (sc.ch == '\"') {
123
         if (sc.ch == '\"') {
107
          sc.Forward();
124
            sc.Forward();
108
            styler.ColourTo(sc.currentPos-1, sc.state);
109
            sc.ChangeState(SCE_HA_DEFAULT);
125
            sc.SetState(SCE_HA_DEFAULT);
110
         } else if (sc.ch == '\\') {
126
         } else if (sc.ch == '\\') {
111
            sc.Forward(2);
127
            sc.Forward(2);
112
         } else if (sc.atLineEnd) {
128
         } else if (sc.atLineEnd) {
113
          styler.ColourTo(sc.currentPos-1, sc.state);
129
            sc.SetState(SCE_HA_DEFAULT);
114
          sc.ChangeState(SCE_HA_DEFAULT);
130
         } else {
115
       } else {
131
            sc.Forward();
116
          sc.Forward();
132
         }
117
       }
118
      }
133
      }
119
         // Char
134
         // Char
120
      else if (sc.state == SCE_HA_CHARACTER) {
135
      else if (sc.state == SCE_HA_CHARACTER) {
121
         if (sc.ch == '\'') {
136
         if (sc.ch == '\'') {
122
          sc.Forward();
137
            sc.Forward();
123
            styler.ColourTo(sc.currentPos-1, sc.state);
124
            sc.ChangeState(SCE_HA_DEFAULT);
138
            sc.SetState(SCE_HA_DEFAULT);
125
         } else if (sc.ch == '\\') {
139
         } else if (sc.ch == '\\') {
126
            sc.Forward(2);
140
            sc.Forward(2);
127
         } else if (sc.atLineEnd) {
141
         } else if (sc.atLineEnd) {
128
          styler.ColourTo(sc.currentPos-1, sc.state);
142
            sc.SetState(SCE_HA_DEFAULT);
129
          sc.ChangeState(SCE_HA_DEFAULT);
143
         } else {
130
       } else {
144
            sc.Forward();
131
          sc.Forward();
145
         }
132
       }
133
      }
146
      }
134
         // Number
147
         // Number
135
      else if (sc.state == SCE_HA_NUMBER) {
148
      else if (sc.state == SCE_HA_NUMBER) {
136
         if (IsADigit(sc.ch, xmode)) {
149
         if (IsADigit(sc.ch, xmode) ||
150
            (sc.ch=='.' && IsADigit(sc.chNext, xmode))) {
137
            sc.Forward();
151
            sc.Forward();
138
         } else if ((xmode == 10) &&
152
         } else if ((xmode == 10) &&
139
                    (sc.ch == 'e' || sc.ch == 'E') &&
153
                    (sc.ch == 'e' || sc.ch == 'E') &&
140
                    (IsADigit(sc.chNext) || sc.chNext == '+' || sc.chNext == '-')) {
154
                    (IsADigit(sc.chNext) || sc.chNext == '+' || sc.chNext == '-')) {
141
          sc.Forward();
155
            sc.Forward();
142
          if (sc.ch == '+' || sc.ch == '-')
156
            if (sc.ch == '+' || sc.ch == '-')
143
              sc.Forward();
157
                sc.Forward();
144
         } else {
158
         } else {
145
            styler.ColourTo(sc.currentPos - 1, sc.state);
146
            sc.ChangeState(SCE_HA_DEFAULT);
159
            sc.SetState(SCE_HA_DEFAULT);
147
         }
148
      }
160
         }
161
      }
149
         // Identifier
162
         // Keyword or Identifier
150
      else if (sc.state == SCE_HA_IDENTIFIER) {
163
      else if (sc.state == SCE_HA_IDENTIFIER) {
164
         while (sc.More()) {
151
         if (IsAWordChar(sc.ch)) {
165
            if (IsAWordChar(sc.ch, magicHash)) {
152
            sc.Forward();
166
               sc.Forward();
167
            } else if (xmode == SCE_HA_CAPITAL && sc.ch=='.') {
168
               if (isupper(sc.chNext)) {
169
                  xmode = SCE_HA_CAPITAL;
170
                  sc.Forward();
171
               } else if (IsAWordStart(sc.chNext)) {
172
                  xmode = SCE_HA_IDENTIFIER;
173
                  sc.Forward();
174
               } else if (IsAnOperatorChar(sc.chNext)) {
175
                  xmode = SCE_HA_OPERATOR;
176
                  sc.Forward();
177
               } else {
178
                  break;
179
               }
180
            } else if (xmode == SCE_HA_OPERATOR && IsAnOperatorChar(sc.ch)) {
181
               sc.Forward();
153
         } else {
182
            } else {
183
               break;
184
            }
185
         }
186
154
            char s[100];
187
         char s[100];
155
            sc.GetCurrent(s, sizeof(s));
188
         sc.GetCurrent(s, sizeof(s));
189
156
            int style = sc.state;
190
         int style = xmode;
157
            int new_mode = 0;
191
192
         int new_mode = HA_MODE_DEFAULT;
193
158
            if (keywords.InList(s)) {
194
         if (keywords.InList(s)) {
195
            style = SCE_HA_KEYWORD;
196
         } else if (isupper(s[0])) {
197
            if (mode >= HA_MODE_IMPORT1 && mode <= HA_MODE_IMPORT3) {
198
               style    = SCE_HA_MODULE;
199
               new_mode = HA_MODE_IMPORT2;
200
            } else if (mode == HA_MODE_MODULE) {
201
               style = SCE_HA_MODULE;
202
            }
203
         } else if (mode == HA_MODE_IMPORT1 &&
204
                    strcmp(s,"qualified") == 0) {
205
             style    = SCE_HA_KEYWORD;
206
             new_mode = HA_MODE_IMPORT1;
207
         } else if (mode == HA_MODE_IMPORT2) {
208
             if (strcmp(s,"as") == 0) {
209
                style    = SCE_HA_KEYWORD;
210
                new_mode = HA_MODE_IMPORT3;
211
            } else if (strcmp(s,"hiding") == 0) {
212
                style     = SCE_HA_KEYWORD;
213
            }
214
         } else if (mode == HA_MODE_TYPE) {
215
            if (strcmp(s,"family") == 0)
216
               style    = SCE_HA_KEYWORD;
217
         }
218
219
         if (mode == HA_MODE_FFI) {
220
            if (ffi.InList(s)) {
159
               style = SCE_HA_KEYWORD;
221
               style = SCE_HA_KEYWORD;
160
            } else if (isupper(s[0])) {
161
               if (mode >= HA_MODE_IMPORT1 && mode <= HA_MODE_IMPORT3) {
162
                  style    = SCE_HA_MODULE;
163
                  new_mode = HA_MODE_IMPORT2;
164
               } else if (mode == HA_MODE_MODULE)
165
                  style = SCE_HA_MODULE;
166
               else
167
                  style = SCE_HA_CAPITAL;
168
            } else if (mode == HA_MODE_IMPORT1 &&
169
                       strcmp(s,"qualified") == 0) {
170
                style    = SCE_HA_KEYWORD;
171
                new_mode = HA_MODE_IMPORT1;
172
            } else if (mode == HA_MODE_IMPORT2) {
173
                if (strcmp(s,"as") == 0) {
174
                   style    = SCE_HA_KEYWORD;
175
                   new_mode = HA_MODE_IMPORT3;
176
               } else if (strcmp(s,"hiding") == 0) {
177
                   style     = SCE_HA_KEYWORD;
178
               }
179
            } else if (mode == HA_MODE_FFI) {
180
             if (ffi.InList(s)) {
181
                  style = SCE_HA_KEYWORD;
182
                  new_mode = HA_MODE_FFI;
183
               }
184
            }
185
            else if (mode == HA_MODE_TYPE) {
186
               if (strcmp(s,"family") == 0)
187
                  style    = SCE_HA_KEYWORD;
188
          }
189
            styler.ColourTo(sc.currentPos - 1, style);
190
            if (strcmp(s,"import") == 0 && mode != HA_MODE_FFI)
191
               new_mode = HA_MODE_IMPORT1;
192
            else if (strcmp(s,"module") == 0)
193
               new_mode = HA_MODE_MODULE;
194
            else if (strcmp(s,"foreign") == 0)
195
               new_mode = HA_MODE_FFI;
222
               new_mode = HA_MODE_FFI;
223
            }
224
         }
225
226
         styler.ColourTo(sc.currentPos - 1, style);
227
228
         if (strcmp(s,"import") == 0 && mode != HA_MODE_FFI)
229
            new_mode = HA_MODE_IMPORT1;
230
         else if (strcmp(s,"module") == 0)
231
            new_mode = HA_MODE_MODULE;
232
         else if (strcmp(s,"foreign") == 0)
233
            new_mode = HA_MODE_FFI;
196
            else if (strcmp(s,"type") == 0)
234
         else if (strcmp(s,"type") == 0
235
               || strcmp(s,"data") == 0)
197
               new_mode = HA_MODE_TYPE;
236
            new_mode = HA_MODE_TYPE;
237
238
         xmode = 0;
198
            sc.ChangeState(SCE_HA_DEFAULT);
239
         sc.ChangeState(SCE_HA_DEFAULT);
199
            mode = new_mode;
240
         mode = new_mode;
200
         }
201
      }
241
      }
202
242
203
         // Comments
243
         // Comments
204
            // Oneliner
244
            // Oneliner
205
      else if (sc.state == SCE_HA_COMMENTLINE) {
245
      else if (sc.state == SCE_HA_COMMENTLINE) {
246
         if (xmode == 1 && sc.ch != '-') {
247
            xmode = 0;
248
            if (IsAnOperatorChar(sc.ch))
249
               sc.ChangeState(SCE_HA_OPERATOR);
206
         if (sc.atLineEnd) {
250
         } else if (sc.atLineEnd) {
207
            styler.ColourTo(sc.currentPos - 1, sc.state);
208
            sc.ChangeState(SCE_HA_DEFAULT);
251
            sc.SetState(SCE_HA_DEFAULT);
209
         } else {
252
         } else {
210
            sc.Forward();
253
            sc.Forward();
211
         }
254
         }
212
      }
255
      }
213
            // Nested
256
            // Nested
214
      else if (sc.state == SCE_HA_COMMENTBLOCK) {
257
      else if (sc.state == SCE_HA_COMMENTBLOCK) {
215
         if (sc.Match("{-")) {
258
         if (sc.Match('{','-')) {
216
            sc.Forward(2);
259
            sc.Forward(2);
217
            xmode++;
260
            xmode++;
218
         }
261
         }
219
         else if (sc.Match("-}")) {
262
         else if (sc.Match('-','}')) {
220
            sc.Forward(2);
263
            sc.Forward(2);
221
            xmode--;
264
            xmode--;
222
            if (xmode == 0) {
265
            if (xmode == 0) {
223
               styler.ColourTo(sc.currentPos - 1, sc.state);
224
               sc.ChangeState(SCE_HA_DEFAULT);
266
               sc.SetState(SCE_HA_DEFAULT);
225
            }
267
            }
226
         } else {
268
         } else {
227
            if (sc.atLineEnd) {
269
            if (sc.atLineEnd) {
228
              // Remember the line state for future incremental lexing
270
                // Remember the line state for future incremental lexing
229
              styler.SetLineState(lineCurrent, (xmode << 4) | mode);
271
                styler.SetLineState(lineCurrent, (xmode << 4) | mode);
230
              lineCurrent++;
272
                lineCurrent++;
231
          }
273
            }
274
            sc.Forward();
275
         }
276
      }
277
            // Pragma
278
      else if (sc.state == SCE_HA_PRAGMA) {
279
         if (sc.Match("#-}")) {
280
            sc.Forward(3);
281
            sc.SetState(SCE_HA_DEFAULT);
282
         } else {
283
            sc.Forward();
284
         }
285
      }
286
            // Preprocessor
287
      else if (sc.state == SCE_HA_PREPROCESSOR) {
288
         if (stylingWithinPreprocessor && !IsAWordStart(sc.ch)) {
289
            sc.SetState(SCE_HA_DEFAULT);
290
         } else if (sc.ch == '\\' && !stylingWithinPreprocessor) {
291
            sc.Forward(2);
292
         } else if (sc.atLineEnd) {
293
            sc.SetState(SCE_HA_DEFAULT);
294
         } else {
232
            sc.Forward();
295
            sc.Forward();
233
         }
296
         }
234
      }
297
      }
235
      // New state?
298
      // New state?
236
      if (sc.state == SCE_HA_DEFAULT) {
299
      if (sc.state == SCE_HA_DEFAULT) {
237
         // Digit
300
         // Digit
238
         if (IsADigit(sc.ch) ||
301
         if (IsADigit(sc.ch)) {
239
             (sc.ch == '.' && IsADigit(sc.chNext)) ||
240
             (sc.ch == '-' && IsADigit(sc.chNext))) {
241
            styler.ColourTo(sc.currentPos - 1, sc.state);
242
            sc.ChangeState(SCE_HA_NUMBER);
302
            sc.SetState(SCE_HA_NUMBER);
243
            if (sc.ch == '0' && (sc.chNext == 'X' || sc.chNext == 'x')) {
303
            if (sc.ch == '0' && (sc.chNext == 'X' || sc.chNext == 'x')) {
244
              // Match anything starting with "0x" or "0X", too
304
                // Match anything starting with "0x" or "0X", too
245
              sc.Forward(2);
305
                sc.Forward(2);
246
              xmode = 16;
306
                xmode = 16;
247
            } else if (sc.ch == '0' && (sc.chNext == 'O' || sc.chNext == 'o')) {
307
            } else if (sc.ch == '0' && (sc.chNext == 'O' || sc.chNext == 'o')) {
248
              // Match anything starting with "0x" or "0X", too
308
                // Match anything starting with "0x" or "0X", too
249
              sc.Forward(2);
309
                sc.Forward(2);
250
              xmode = 8;
310
                xmode = 8;
251
            } else {
311
            } else {
252
              sc.Forward();
312
                sc.Forward();
253
              xmode = 10;
313
                xmode = 10;
254
          }
314
            }
255
            mode = HA_MODE_DEFAULT;
315
            mode = HA_MODE_DEFAULT;
256
         }
316
         }
317
         // Pragma
318
         else if (sc.Match("{-#")) {
319
            sc.SetState(SCE_HA_PRAGMA);
320
            sc.Forward(3);
321
         }
257
         // Comment line
322
         // Comment line
258
         else if (sc.Match("--")) {
323
         else if (sc.Match('-','-')) {
259
            styler.ColourTo(sc.currentPos - 1, sc.state);
260
            sc.Forward(2);
261
            sc.ChangeState(SCE_HA_COMMENTLINE);
324
            sc.SetState(SCE_HA_COMMENTLINE);
325
            sc.Forward(2);
326
            xmode = 1;
327
         }
262
         // Comment block
328
         // Comment block
263
         }
264
         else if (sc.Match("{-")) {
329
         else if (sc.Match('{','-')) {
265
            styler.ColourTo(sc.currentPos - 1, sc.state);
266
            sc.Forward(2);
267
            sc.ChangeState(SCE_HA_COMMENTBLOCK);
330
            sc.SetState(SCE_HA_COMMENTBLOCK);
331
            sc.Forward(2);
268
            xmode = 1;
332
            xmode = 1;
269
         }
333
         }
270
         // String
334
         // String
271
         else if (sc.Match('\"')) {
335
         else if (sc.Match('\"')) {
272
            styler.ColourTo(sc.currentPos - 1, sc.state);
273
            sc.Forward();
274
            sc.ChangeState(SCE_HA_STRING);
336
            sc.SetState(SCE_HA_STRING);
337
            sc.Forward();
275
         }
338
         }
276
         // Character
339
         // Character
277
         else if (sc.Match('\'')) {
340
         else if (sc.Match('\'')) {
278
            styler.ColourTo(sc.currentPos - 1, sc.state);
279
            sc.Forward();
280
            sc.ChangeState(SCE_HA_CHARACTER);
341
            sc.SetState(SCE_HA_CHARACTER);
342
            sc.Forward();
281
         }
343
         }
282
         else if (sc.ch == '(' || sc.ch == ')' ||
344
         // Preprocessor
283
                  sc.ch == '{' || sc.ch == '}' ||
345
         else if (sc.atLineStart && sc.ch == '#') {
284
                  sc.ch == '[' || sc.ch == ']') {
285
          styler.ColourTo(sc.currentPos - 1, sc.state);
286
          sc.Forward();
287
          styler.ColourTo(sc.currentPos - 1, SCE_HA_OPERATOR);
288
          mode = HA_MODE_DEFAULT;
346
            mode = HA_MODE_DEFAULT;
289
       }
347
            sc.SetState(SCE_HA_PREPROCESSOR);
348
            sc.Forward();
349
         }
290
         // Operator
350
         // Operator
291
         else if (isascii(sc.ch) && isoperator(static_cast<char>(sc.ch))) {
351
         else if (IsAnOperatorChar(sc.ch)) {
292
            styler.ColourTo(sc.currentPos - 1, sc.state);
293
            sc.Forward();
294
            sc.ChangeState(SCE_HA_OPERATOR);
295
            mode = HA_MODE_DEFAULT;
352
            mode = HA_MODE_DEFAULT;
353
            sc.SetState(SCE_HA_OPERATOR);
296
         }
354
         }
297
         // Keyword
355
         // Braces and punctuation
356
         else if (sc.ch == ',' || sc.ch == ';'
357
               || sc.ch == '(' || sc.ch == ')'
358
               || sc.ch == '[' || sc.ch == ']'
359
               || sc.ch == '{' || sc.ch == '}') {
360
            sc.SetState(SCE_HA_OPERATOR);
361
            sc.Forward();
362
            sc.SetState(SCE_HA_DEFAULT);
363
         }
364
         // Keyword or Identifier
298
         else if (IsAWordStart(sc.ch)) {
365
         else if (IsAWordStart(sc.ch)) {
299
            styler.ColourTo(sc.currentPos - 1, sc.state);
366
            xmode = isupper(sc.ch) ? SCE_HA_CAPITAL : SCE_HA_IDENTIFIER;
300
            sc.Forward();
301
            sc.ChangeState(SCE_HA_IDENTIFIER);
367
            sc.SetState(SCE_HA_IDENTIFIER);
368
            sc.Forward();
302
         } else {
369
         } else {
303
            if (sc.atLineEnd) {
370
            if (sc.atLineEnd) {
304
              // Remember the line state for future incremental lexing
371
                // Remember the line state for future incremental lexing
305
              styler.SetLineState(lineCurrent, (xmode << 4) | mode);
372
                styler.SetLineState(lineCurrent, (xmode << 4) | mode);
306
              lineCurrent++;
373
                lineCurrent++;
307
          }
374
            }
308
            sc.Forward();
375
            sc.Forward();
309
         }
376
         }
310
      }
377
      }
311
   }
378
   }
312
   sc.Complete();
379
   sc.Complete();