openrat-cms

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

elm.js (5546B)


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