Subversion-Projekte lars-tiefland.ci

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
776 lars 1
// CodeMirror, copyright (c) by Marijn Haverbeke and others
2
// Distributed under an MIT license: http://codemirror.net/LICENSE
3
 
4
(function(mod) {
5
  if (typeof exports == "object" && typeof module == "object") // CommonJS
6
    mod(require("../../lib/codemirror"));
7
  else if (typeof define == "function" && define.amd) // AMD
8
    define(["../../lib/codemirror"], mod);
9
  else // Plain browser env
10
    mod(CodeMirror);
11
})(function(CodeMirror) {
12
  "use strict";
13
 
14
  CodeMirror.defineMode("elm", function() {
15
 
16
    function switchState(source, setState, f) {
17
      setState(f);
18
      return f(source, setState);
19
    }
20
 
21
    // These should all be Unicode extended, as per the Haskell 2010 report
22
    var smallRE = /[a-z_]/;
23
    var largeRE = /[A-Z]/;
24
    var digitRE = /[0-9]/;
25
    var hexitRE = /[0-9A-Fa-f]/;
26
    var octitRE = /[0-7]/;
27
    var idRE = /[a-z_A-Z0-9\']/;
28
    var symbolRE = /[-!#$%&*+.\/<=>?@\\^|~:\u03BB\u2192]/;
29
    var specialRE = /[(),;[\]`{}]/;
30
    var whiteCharRE = /[ \t\v\f]/; // newlines are handled in tokenizer
31
 
32
    function normal() {
33
      return function (source, setState) {
34
        if (source.eatWhile(whiteCharRE)) {
35
          return null;
36
        }
37
 
38
        var ch = source.next();
39
        if (specialRE.test(ch)) {
40
          if (ch == '{' && source.eat('-')) {
41
            var t = "comment";
42
            if (source.eat('#')) t = "meta";
43
            return switchState(source, setState, ncomment(t, 1));
44
          }
45
          return null;
46
        }
47
 
48
        if (ch == '\'') {
49
          if (source.eat('\\'))
50
            source.next();  // should handle other escapes here
51
          else
52
            source.next();
53
 
54
          if (source.eat('\''))
55
            return "string";
56
          return "error";
57
        }
58
 
59
        if (ch == '"') {
60
          return switchState(source, setState, stringLiteral);
61
        }
62
 
63
        if (largeRE.test(ch)) {
64
          source.eatWhile(idRE);
65
          if (source.eat('.'))
66
            return "qualifier";
67
          return "variable-2";
68
        }
69
 
70
        if (smallRE.test(ch)) {
71
          var isDef = source.pos === 1;
72
          source.eatWhile(idRE);
73
          return isDef ? "variable-3" : "variable";
74
        }
75
 
76
        if (digitRE.test(ch)) {
77
          if (ch == '0') {
78
            if (source.eat(/[xX]/)) {
79
              source.eatWhile(hexitRE); // should require at least 1
80
              return "integer";
81
            }
82
            if (source.eat(/[oO]/)) {
83
              source.eatWhile(octitRE); // should require at least 1
84
              return "number";
85
            }
86
          }
87
          source.eatWhile(digitRE);
88
          var t = "number";
89
          if (source.eat('.')) {
90
            t = "number";
91
            source.eatWhile(digitRE); // should require at least 1
92
          }
93
          if (source.eat(/[eE]/)) {
94
            t = "number";
95
            source.eat(/[-+]/);
96
            source.eatWhile(digitRE); // should require at least 1
97
          }
98
          return t;
99
        }
100
 
101
        if (symbolRE.test(ch)) {
102
          if (ch == '-' && source.eat(/-/)) {
103
            source.eatWhile(/-/);
104
            if (!source.eat(symbolRE)) {
105
              source.skipToEnd();
106
              return "comment";
107
            }
108
          }
109
          source.eatWhile(symbolRE);
110
          return "builtin";
111
        }
112
 
113
        return "error";
114
      }
115
    }
116
 
117
    function ncomment(type, nest) {
118
      if (nest == 0) {
119
        return normal();
120
      }
121
      return function(source, setState) {
122
        var currNest = nest;
123
        while (!source.eol()) {
124
          var ch = source.next();
125
          if (ch == '{' && source.eat('-')) {
126
            ++currNest;
127
          } else if (ch == '-' && source.eat('}')) {
128
            --currNest;
129
            if (currNest == 0) {
130
              setState(normal());
131
              return type;
132
            }
133
          }
134
        }
135
        setState(ncomment(type, currNest));
136
        return type;
137
      }
138
    }
139
 
140
    function stringLiteral(source, setState) {
141
      while (!source.eol()) {
142
        var ch = source.next();
143
        if (ch == '"') {
144
          setState(normal());
145
          return "string";
146
        }
147
        if (ch == '\\') {
148
          if (source.eol() || source.eat(whiteCharRE)) {
149
            setState(stringGap);
150
            return "string";
151
          }
152
          if (!source.eat('&')) source.next(); // should handle other escapes here
153
        }
154
      }
155
      setState(normal());
156
      return "error";
157
    }
158
 
159
    function stringGap(source, setState) {
160
      if (source.eat('\\')) {
161
        return switchState(source, setState, stringLiteral);
162
      }
163
      source.next();
164
      setState(normal());
165
      return "error";
166
    }
167
 
168
 
169
    var wellKnownWords = (function() {
170
      var wkw = {};
171
 
172
      var keywords = [
173
        "case", "of", "as",
174
        "if", "then", "else",
175
        "let", "in",
176
        "infix", "infixl", "infixr",
177
        "type", "alias",
178
        "input", "output", "foreign", "loopback",
179
        "module", "where", "import", "exposing",
180
        "_", "..", "|", ":", "=", "\\", "\"", "->", "<-"
181
      ];
182
 
183
      for (var i = keywords.length; i--;)
184
        wkw[keywords[i]] = "keyword";
185
 
186
      return wkw;
187
    })();
188
 
189
 
190
 
191
    return {
192
      startState: function ()  { return { f: normal() }; },
193
      copyState:  function (s) { return { f: s.f }; },
194
 
195
      token: function(stream, state) {
196
        var t = state.f(stream, function(s) { state.f = s; });
197
        var w = stream.current();
198
        return (wellKnownWords.hasOwnProperty(w)) ? wellKnownWords[w] : t;
199
      }
200
    };
201
 
202
  });
203
 
204
  CodeMirror.defineMIME("text/x-elm", "elm");
205
})();