GPQAPP

Форк
0
268 строк · 8.0 Кб
1
// CodeMirror, copyright (c) by Marijn Haverbeke and others
2
// Distributed under an MIT license: https://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("haskell", function(_config, modeConfig) {
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 = /\d/;
25
  var hexitRE = /[0-9A-Fa-f]/;
26
  var octitRE = /[0-7]/;
27
  var idRE = /[a-z_A-Z0-9'\xa1-\uffff]/;
28
  var symbolRE = /[-!#$%&*+.\/<=>?@\\^|~:]/;
29
  var specialRE = /[(),;[\]`{}]/;
30
  var whiteCharRE = /[ \t\v\f]/; // newlines are handled in tokenizer
31

32
  function normal(source, setState) {
33
    if (source.eatWhile(whiteCharRE)) {
34
      return null;
35
    }
36

37
    var ch = source.next();
38
    if (specialRE.test(ch)) {
39
      if (ch == '{' && source.eat('-')) {
40
        var t = "comment";
41
        if (source.eat('#')) {
42
          t = "meta";
43
        }
44
        return switchState(source, setState, ncomment(t, 1));
45
      }
46
      return null;
47
    }
48

49
    if (ch == '\'') {
50
      if (source.eat('\\')) {
51
        source.next();  // should handle other escapes here
52
      }
53
      else {
54
        source.next();
55
      }
56
      if (source.eat('\'')) {
57
        return "string";
58
      }
59
      return "string error";
60
    }
61

62
    if (ch == '"') {
63
      return switchState(source, setState, stringLiteral);
64
    }
65

66
    if (largeRE.test(ch)) {
67
      source.eatWhile(idRE);
68
      if (source.eat('.')) {
69
        return "qualifier";
70
      }
71
      return "variable-2";
72
    }
73

74
    if (smallRE.test(ch)) {
75
      source.eatWhile(idRE);
76
      return "variable";
77
    }
78

79
    if (digitRE.test(ch)) {
80
      if (ch == '0') {
81
        if (source.eat(/[xX]/)) {
82
          source.eatWhile(hexitRE); // should require at least 1
83
          return "integer";
84
        }
85
        if (source.eat(/[oO]/)) {
86
          source.eatWhile(octitRE); // should require at least 1
87
          return "number";
88
        }
89
      }
90
      source.eatWhile(digitRE);
91
      var t = "number";
92
      if (source.match(/^\.\d+/)) {
93
        t = "number";
94
      }
95
      if (source.eat(/[eE]/)) {
96
        t = "number";
97
        source.eat(/[-+]/);
98
        source.eatWhile(digitRE); // should require at least 1
99
      }
100
      return t;
101
    }
102

103
    if (ch == "." && source.eat("."))
104
      return "keyword";
105

106
    if (symbolRE.test(ch)) {
107
      if (ch == '-' && source.eat(/-/)) {
108
        source.eatWhile(/-/);
109
        if (!source.eat(symbolRE)) {
110
          source.skipToEnd();
111
          return "comment";
112
        }
113
      }
114
      var t = "variable";
115
      if (ch == ':') {
116
        t = "variable-2";
117
      }
118
      source.eatWhile(symbolRE);
119
      return t;
120
    }
121

122
    return "error";
123
  }
124

125
  function ncomment(type, nest) {
126
    if (nest == 0) {
127
      return normal;
128
    }
129
    return function(source, setState) {
130
      var currNest = nest;
131
      while (!source.eol()) {
132
        var ch = source.next();
133
        if (ch == '{' && source.eat('-')) {
134
          ++currNest;
135
        }
136
        else if (ch == '-' && source.eat('}')) {
137
          --currNest;
138
          if (currNest == 0) {
139
            setState(normal);
140
            return type;
141
          }
142
        }
143
      }
144
      setState(ncomment(type, currNest));
145
      return type;
146
    };
147
  }
148

149
  function stringLiteral(source, setState) {
150
    while (!source.eol()) {
151
      var ch = source.next();
152
      if (ch == '"') {
153
        setState(normal);
154
        return "string";
155
      }
156
      if (ch == '\\') {
157
        if (source.eol() || source.eat(whiteCharRE)) {
158
          setState(stringGap);
159
          return "string";
160
        }
161
        if (source.eat('&')) {
162
        }
163
        else {
164
          source.next(); // should handle other escapes here
165
        }
166
      }
167
    }
168
    setState(normal);
169
    return "string error";
170
  }
171

172
  function stringGap(source, setState) {
173
    if (source.eat('\\')) {
174
      return switchState(source, setState, stringLiteral);
175
    }
176
    source.next();
177
    setState(normal);
178
    return "error";
179
  }
180

181

182
  var wellKnownWords = (function() {
183
    var wkw = {};
184
    function setType(t) {
185
      return function () {
186
        for (var i = 0; i < arguments.length; i++)
187
          wkw[arguments[i]] = t;
188
      };
189
    }
190

191
    setType("keyword")(
192
      "case", "class", "data", "default", "deriving", "do", "else", "foreign",
193
      "if", "import", "in", "infix", "infixl", "infixr", "instance", "let",
194
      "module", "newtype", "of", "then", "type", "where", "_");
195

196
    setType("keyword")(
197
      "\.\.", ":", "::", "=", "\\", "<-", "->", "@", "~", "=>");
198

199
    setType("builtin")(
200
      "!!", "$!", "$", "&&", "+", "++", "-", ".", "/", "/=", "<", "<*", "<=",
201
      "<$>", "<*>", "=<<", "==", ">", ">=", ">>", ">>=", "^", "^^", "||", "*",
202
      "*>", "**");
203

204
    setType("builtin")(
205
      "Applicative", "Bool", "Bounded", "Char", "Double", "EQ", "Either", "Enum",
206
      "Eq", "False", "FilePath", "Float", "Floating", "Fractional", "Functor",
207
      "GT", "IO", "IOError", "Int", "Integer", "Integral", "Just", "LT", "Left",
208
      "Maybe", "Monad", "Nothing", "Num", "Ord", "Ordering", "Rational", "Read",
209
      "ReadS", "Real", "RealFloat", "RealFrac", "Right", "Show", "ShowS",
210
      "String", "True");
211

212
    setType("builtin")(
213
      "abs", "acos", "acosh", "all", "and", "any", "appendFile", "asTypeOf",
214
      "asin", "asinh", "atan", "atan2", "atanh", "break", "catch", "ceiling",
215
      "compare", "concat", "concatMap", "const", "cos", "cosh", "curry",
216
      "cycle", "decodeFloat", "div", "divMod", "drop", "dropWhile", "either",
217
      "elem", "encodeFloat", "enumFrom", "enumFromThen", "enumFromThenTo",
218
      "enumFromTo", "error", "even", "exp", "exponent", "fail", "filter",
219
      "flip", "floatDigits", "floatRadix", "floatRange", "floor", "fmap",
220
      "foldl", "foldl1", "foldr", "foldr1", "fromEnum", "fromInteger",
221
      "fromIntegral", "fromRational", "fst", "gcd", "getChar", "getContents",
222
      "getLine", "head", "id", "init", "interact", "ioError", "isDenormalized",
223
      "isIEEE", "isInfinite", "isNaN", "isNegativeZero", "iterate", "last",
224
      "lcm", "length", "lex", "lines", "log", "logBase", "lookup", "map",
225
      "mapM", "mapM_", "max", "maxBound", "maximum", "maybe", "min", "minBound",
226
      "minimum", "mod", "negate", "not", "notElem", "null", "odd", "or",
227
      "otherwise", "pi", "pred", "print", "product", "properFraction", "pure",
228
      "putChar", "putStr", "putStrLn", "quot", "quotRem", "read", "readFile",
229
      "readIO", "readList", "readLn", "readParen", "reads", "readsPrec",
230
      "realToFrac", "recip", "rem", "repeat", "replicate", "return", "reverse",
231
      "round", "scaleFloat", "scanl", "scanl1", "scanr", "scanr1", "seq",
232
      "sequence", "sequence_", "show", "showChar", "showList", "showParen",
233
      "showString", "shows", "showsPrec", "significand", "signum", "sin",
234
      "sinh", "snd", "span", "splitAt", "sqrt", "subtract", "succ", "sum",
235
      "tail", "take", "takeWhile", "tan", "tanh", "toEnum", "toInteger",
236
      "toRational", "truncate", "uncurry", "undefined", "unlines", "until",
237
      "unwords", "unzip", "unzip3", "userError", "words", "writeFile", "zip",
238
      "zip3", "zipWith", "zipWith3");
239

240
    var override = modeConfig.overrideKeywords;
241
    if (override) for (var word in override) if (override.hasOwnProperty(word))
242
      wkw[word] = override[word];
243

244
    return wkw;
245
  })();
246

247

248

249
  return {
250
    startState: function ()  { return { f: normal }; },
251
    copyState:  function (s) { return { f: s.f }; },
252

253
    token: function(stream, state) {
254
      var t = state.f(stream, function(s) { state.f = s; });
255
      var w = stream.current();
256
      return wellKnownWords.hasOwnProperty(w) ? wellKnownWords[w] : t;
257
    },
258

259
    blockCommentStart: "{-",
260
    blockCommentEnd: "-}",
261
    lineComment: "--"
262
  };
263

264
});
265

266
CodeMirror.defineMIME("text/x-haskell", "haskell");
267

268
});
269

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.