openrat-cms

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

haskell.js (8109B)


      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 "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     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 });