~ubuntu-branches/ubuntu/utopic/geany/utopic

« back to all changes in this revision

Viewing changes to scintilla/LexHaskell.cxx

  • Committer: Package Import Robot
  • Author(s): Chow Loong Jin
  • Date: 2011-12-10 07:43:26 UTC
  • mfrom: (3.3.7 sid)
  • Revision ID: package-import@ubuntu.com-20111210074326-s8yqbew5i20h33tf
Tags: 0.21-1ubuntu1
* Merge from Debian Unstable, remaining changes:
  - debian/patches/20_use_evince_viewer.patch:
     + use evince as viewer for pdf and dvi files
  - debian/patches/20_use_x_terminal_emulator.patch:
     + use x-terminal-emulator as terminal
  - debian/control
     + Add breaks on geany-plugins-common << 0.20
* Also fixes bugs:
  - Filter for MATLAB/Octave files filters everythign (LP: 885505)

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 "PropSetSimple.h"
29
 
#include "Accessor.h"
30
 
#include "StyleContext.h"
31
 
#include "KeyWords.h"
32
 
#include "Scintilla.h"
33
 
#include "SciLexer.h"
34
 
 
35
 
#ifdef SCI_NAMESPACE
36
 
using namespace Scintilla;
37
 
#endif
38
 
 
39
 
#ifdef BUILD_AS_EXTERNAL_LEXER
40
 
 
41
 
#include "ExternalLexer.h"
42
 
#include "WindowAccessor.h"
43
 
 
44
 
#define BUILD_EXTERNAL_LEXER 0
45
 
 
46
 
#endif
47
 
 
48
 
// Max level of nested comments
49
 
#define SCE_HA_COMMENTMAX SCE_HA_COMMENTBLOCK3
50
 
 
51
 
 
52
 
enum kwType { kwOther, kwClass, kwData, kwInstance, kwImport, kwModule, kwType};
53
 
 
54
 
static inline bool IsNewline(const int ch) {
55
 
   return (ch == '\n' || ch == '\r');
56
 
}
57
 
 
58
 
static inline bool IsWhitespace(const int ch) {
59
 
   return (  ch == ' '
60
 
          || ch == '\t'
61
 
          || IsNewline(ch) );
62
 
}
63
 
 
64
 
static inline bool IsAWordStart(const int ch) {
65
 
   return (ch < 0x80) && (isalnum(ch) || ch == '_');
66
 
}
67
 
 
68
 
static inline bool IsAWordChar(const int ch) {
69
 
   return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '\'');
70
 
}
71
 
 
72
 
static void ColorizeHaskellDoc(unsigned int startPos, int length, int initStyle,
73
 
                               WordList *keywordlists[], Accessor &styler) {
74
 
 
75
 
   WordList &keywords = *keywordlists[0];
76
 
 
77
 
   int kwLast = kwOther;
78
 
 
79
 
   StyleContext sc(startPos, length, initStyle, styler);
80
 
 
81
 
   for (; sc.More(); sc.Forward()) {
82
 
 
83
 
      // Check for state end
84
 
         // Operator
85
 
      if (sc.state == SCE_HA_OPERATOR) {
86
 
         kwLast = kwOther;
87
 
         sc.SetState(SCE_HA_DEFAULT);
88
 
      }
89
 
         // String
90
 
      else if (sc.state == SCE_HA_STRING) {
91
 
         if (sc.ch == '\"') {
92
 
            sc.ForwardSetState(SCE_HA_DEFAULT);
93
 
         } else if (sc.ch == '\\') {
94
 
            sc.Forward();
95
 
         }
96
 
      }
97
 
         // Char
98
 
      else if (sc.state == SCE_HA_CHARACTER) {
99
 
         if (sc.ch == '\'') {
100
 
            sc.ForwardSetState(SCE_HA_DEFAULT);
101
 
         } else if (sc.ch == '\\') {
102
 
            sc.Forward();
103
 
         }
104
 
      }
105
 
         // Number
106
 
      else if (sc.state == SCE_HA_NUMBER) {
107
 
         if (!IsADigit(sc.ch)) {
108
 
            sc.SetState(SCE_HA_DEFAULT);
109
 
         }
110
 
      }
111
 
         // Types, constructors, etc.
112
 
      else if (sc.state == SCE_HA_CAPITAL) {
113
 
         if (!IsAWordChar(sc.ch) || sc.ch == '.') {
114
 
            sc.SetState(SCE_HA_DEFAULT);
115
 
         }
116
 
      }
117
 
         // Identifier
118
 
      else if (sc.state == SCE_HA_IDENTIFIER) {
119
 
         if (!IsAWordChar(sc.ch)) {
120
 
            char s[100];
121
 
            sc.GetCurrent(s, sizeof(s));
122
 
            int style = SCE_HA_IDENTIFIER;
123
 
            if ((kwLast == kwImport) || (strcmp(s,"qualified") == 0) || (strcmp(s,"as") == 0)) {
124
 
               style = SCE_HA_IMPORT;
125
 
            } else if (keywords.InList(s)) {
126
 
               style = SCE_HA_KEYWORD;
127
 
            } else if (kwLast == kwData) {
128
 
               style = SCE_HA_DATA;
129
 
            } else if (kwLast == kwClass) {
130
 
               style = SCE_HA_CLASS;
131
 
            } else if (kwLast == kwModule) {
132
 
               style = SCE_HA_MODULE;
133
 
            } else if (isupper(s[0])) {
134
 
               style = SCE_HA_CAPITAL;
135
 
            }
136
 
            sc.ChangeState(style);
137
 
            sc.SetState(SCE_HA_DEFAULT);
138
 
            if (style == SCE_HA_KEYWORD) {
139
 
               if (0 == strcmp(s, "class"))
140
 
                  kwLast = kwClass;
141
 
               else if (0 == strcmp(s, "data"))
142
 
                  kwLast = kwData;
143
 
               else if (0 == strcmp(s, "instance"))
144
 
                  kwLast = kwInstance;
145
 
               else if (0 == strcmp(s, "import"))
146
 
                  kwLast = kwImport;
147
 
               else if (0 == strcmp(s, "module"))
148
 
                  kwLast = kwModule;
149
 
               else
150
 
                  kwLast = kwOther;
151
 
            } else if (style == SCE_HA_CLASS || style == SCE_HA_IMPORT ||
152
 
                       style == SCE_HA_MODULE || style == SCE_HA_CAPITAL ||
153
 
                       style == SCE_HA_DATA || style == SCE_HA_INSTANCE) {
154
 
               kwLast = kwOther;
155
 
            }
156
 
         }
157
 
      }
158
 
         // Comments
159
 
            // Oneliner
160
 
      else if (sc.state == SCE_HA_COMMENTLINE) {
161
 
         if (IsNewline(sc.ch))
162
 
            sc.SetState(SCE_HA_DEFAULT);
163
 
      }
164
 
            // Nested
165
 
      else if (sc.state >= SCE_HA_COMMENTBLOCK) {
166
 
         if (sc.Match("{-")) {
167
 
            if (sc.state < SCE_HA_COMMENTMAX)
168
 
               sc.SetState(sc.state + 1);
169
 
         }
170
 
         else if (sc.Match("-}")) {
171
 
            sc.Forward();
172
 
            if (sc.state == SCE_HA_COMMENTBLOCK)
173
 
               sc.ForwardSetState(SCE_HA_DEFAULT);
174
 
            else
175
 
               sc.ForwardSetState(sc.state - 1);
176
 
         }
177
 
      }
178
 
      // New state?
179
 
      if (sc.state == SCE_HA_DEFAULT) {
180
 
         // Digit
181
 
         if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
182
 
            sc.SetState(SCE_HA_NUMBER);
183
 
            if (sc.ch == '0' && (sc.chNext == 'X' || sc.chNext == 'x')) { // Match anything starting with "0x" or "0X", too
184
 
               sc.Forward(1);
185
 
            }
186
 
         }
187
 
         // Comment line
188
 
         else if (sc.Match("--")) {
189
 
            sc.SetState(SCE_HA_COMMENTLINE);
190
 
         // Comment block
191
 
         }
192
 
         else if (sc.Match("{-")) {
193
 
            sc.SetState(SCE_HA_COMMENTBLOCK);
194
 
         }
195
 
         // String
196
 
         else if (sc.Match('\"')) {
197
 
            sc.SetState(SCE_HA_STRING);
198
 
         }
199
 
         // Character
200
 
         else if (sc.Match('\'')) {
201
 
            sc.SetState(SCE_HA_CHARACTER);
202
 
         }
203
 
         // Stringstart
204
 
         else if (sc.Match('\"')) {
205
 
            sc.SetState(SCE_HA_STRING);
206
 
         }
207
 
         // Operator
208
 
         else if (isascii(sc.ch) && isoperator(static_cast<char>(sc.ch))) {
209
 
            sc.SetState(SCE_HA_OPERATOR);
210
 
         }
211
 
         // Keyword
212
 
         else if (IsAWordStart(sc.ch)) {
213
 
               sc.SetState(SCE_HA_IDENTIFIER);
214
 
         }
215
 
 
216
 
      }
217
 
   }
218
 
   sc.Complete();
219
 
}
220
 
 
221
 
// External stuff - used for dynamic-loading, not implemented in wxStyledTextCtrl yet.
222
 
// Inspired by the caml external lexer - Credits to Robert Roessler - http://www.rftp.com
223
 
#ifdef BUILD_EXTERNAL_LEXER
224
 
static const char* LexerName = "haskell";
225
 
 
226
 
void EXT_LEXER_DECL Lex(unsigned int lexer, unsigned int startPos, int length, int initStyle,
227
 
                        char *words[], WindowID window, char *props)
228
 
{
229
 
   PropSetSimple ps;
230
 
   ps.SetMultiple(props);
231
 
   WindowAccessor wa(window, ps);
232
 
 
233
 
   int nWL = 0;
234
 
   for (; words[nWL]; nWL++) ;
235
 
   WordList** wl = new WordList* [nWL + 1];
236
 
   int i = 0;
237
 
   for (; i<nWL; i++)
238
 
   {
239
 
      wl[i] = new WordList();
240
 
      wl[i]->Set(words[i]);
241
 
   }
242
 
   wl[i] = 0;
243
 
 
244
 
   ColorizeHaskellDoc(startPos, length, initStyle, wl, wa);
245
 
   wa.Flush();
246
 
   for (i=nWL-1;i>=0;i--)
247
 
      delete wl[i];
248
 
   delete [] wl;
249
 
}
250
 
 
251
 
void EXT_LEXER_DECL Fold (unsigned int lexer, unsigned int startPos, int length, int initStyle,
252
 
                        char *words[], WindowID window, char *props)
253
 
{
254
 
 
255
 
}
256
 
 
257
 
int EXT_LEXER_DECL GetLexerCount()
258
 
{
259
 
   return 1;
260
 
}
261
 
 
262
 
void EXT_LEXER_DECL GetLexerName(unsigned int Index, char *name, int buflength)
263
 
{
264
 
   if (buflength > 0) {
265
 
      buflength--;
266
 
      int n = strlen(LexerName);
267
 
      if (n > buflength)
268
 
         n = buflength;
269
 
      memcpy(name, LexerName, n), name[n] = '\0';
270
 
   }
271
 
}
272
 
#endif
273
 
 
274
 
LexerModule lmHaskell(SCLEX_HASKELL, ColorizeHaskellDoc, "haskell");
275