github.com/jancarloviray/community@v0.41.1-0.20170124221257-33a66c87cf2f/app/public/codemirror/mode/haskell/haskell.js (about)

     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("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 "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 "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      setType("builtin")(
   204        "Bool", "Bounded", "Char", "Double", "EQ", "Either", "Enum", "Eq",
   205        "False", "FilePath", "Float", "Floating", "Fractional", "Functor", "GT",
   206        "IO", "IOError", "Int", "Integer", "Integral", "Just", "LT", "Left",
   207        "Maybe", "Monad", "Nothing", "Num", "Ord", "Ordering", "Rational", "Read",
   208        "ReadS", "Real", "RealFloat", "RealFrac", "Right", "Show", "ShowS",
   209        "String", "True");
   210  
   211      setType("builtin")(
   212        "abs", "acos", "acosh", "all", "and", "any", "appendFile", "asTypeOf",
   213        "asin", "asinh", "atan", "atan2", "atanh", "break", "catch", "ceiling",
   214        "compare", "concat", "concatMap", "const", "cos", "cosh", "curry",
   215        "cycle", "decodeFloat", "div", "divMod", "drop", "dropWhile", "either",
   216        "elem", "encodeFloat", "enumFrom", "enumFromThen", "enumFromThenTo",
   217        "enumFromTo", "error", "even", "exp", "exponent", "fail", "filter",
   218        "flip", "floatDigits", "floatRadix", "floatRange", "floor", "fmap",
   219        "foldl", "foldl1", "foldr", "foldr1", "fromEnum", "fromInteger",
   220        "fromIntegral", "fromRational", "fst", "gcd", "getChar", "getContents",
   221        "getLine", "head", "id", "init", "interact", "ioError", "isDenormalized",
   222        "isIEEE", "isInfinite", "isNaN", "isNegativeZero", "iterate", "last",
   223        "lcm", "length", "lex", "lines", "log", "logBase", "lookup", "map",
   224        "mapM", "mapM_", "max", "maxBound", "maximum", "maybe", "min", "minBound",
   225        "minimum", "mod", "negate", "not", "notElem", "null", "odd", "or",
   226        "otherwise", "pi", "pred", "print", "product", "properFraction",
   227        "putChar", "putStr", "putStrLn", "quot", "quotRem", "read", "readFile",
   228        "readIO", "readList", "readLn", "readParen", "reads", "readsPrec",
   229        "realToFrac", "recip", "rem", "repeat", "replicate", "return", "reverse",
   230        "round", "scaleFloat", "scanl", "scanl1", "scanr", "scanr1", "seq",
   231        "sequence", "sequence_", "show", "showChar", "showList", "showParen",
   232        "showString", "shows", "showsPrec", "significand", "signum", "sin",
   233        "sinh", "snd", "span", "splitAt", "sqrt", "subtract", "succ", "sum",
   234        "tail", "take", "takeWhile", "tan", "tanh", "toEnum", "toInteger",
   235        "toRational", "truncate", "uncurry", "undefined", "unlines", "until",
   236        "unwords", "unzip", "unzip3", "userError", "words", "writeFile", "zip",
   237        "zip3", "zipWith", "zipWith3");
   238  
   239      var override = modeConfig.overrideKeywords;
   240      if (override) for (var word in override) if (override.hasOwnProperty(word))
   241        wkw[word] = override[word];
   242  
   243      return wkw;
   244    })();
   245  
   246  
   247  
   248    return {
   249      startState: function ()  { return { f: normal }; },
   250      copyState:  function (s) { return { f: s.f }; },
   251  
   252      token: function(stream, state) {
   253        var t = state.f(stream, function(s) { state.f = s; });
   254        var w = stream.current();
   255        return wellKnownWords.hasOwnProperty(w) ? wellKnownWords[w] : t;
   256      },
   257  
   258      blockCommentStart: "{-",
   259      blockCommentEnd: "-}",
   260      lineComment: "--"
   261    };
   262  
   263  });
   264  
   265  CodeMirror.defineMIME("text/x-haskell", "haskell");
   266  
   267  });