206 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			206 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
// CodeMirror, copyright (c) by Marijn Haverbeke and others
 | 
						|
// Distributed under an MIT license: http://codemirror.net/LICENSE
 | 
						|
 | 
						|
(function(mod) {
 | 
						|
  if (typeof exports == "object" && typeof module == "object") // CommonJS
 | 
						|
    mod(require("../../lib/codemirror"));
 | 
						|
  else if (typeof define == "function" && define.amd) // AMD
 | 
						|
    define(["../../lib/codemirror"], mod);
 | 
						|
  else // Plain browser env
 | 
						|
    mod(CodeMirror);
 | 
						|
})(function(CodeMirror) {
 | 
						|
  "use strict";
 | 
						|
 | 
						|
  CodeMirror.defineMode("elm", function() {
 | 
						|
 | 
						|
    function switchState(source, setState, f) {
 | 
						|
      setState(f);
 | 
						|
      return f(source, setState);
 | 
						|
    }
 | 
						|
 | 
						|
    // These should all be Unicode extended, as per the Haskell 2010 report
 | 
						|
    var smallRE = /[a-z_]/;
 | 
						|
    var largeRE = /[A-Z]/;
 | 
						|
    var digitRE = /[0-9]/;
 | 
						|
    var hexitRE = /[0-9A-Fa-f]/;
 | 
						|
    var octitRE = /[0-7]/;
 | 
						|
    var idRE = /[a-z_A-Z0-9\']/;
 | 
						|
    var symbolRE = /[-!#$%&*+.\/<=>?@\\^|~:\u03BB\u2192]/;
 | 
						|
    var specialRE = /[(),;[\]`{}]/;
 | 
						|
    var whiteCharRE = /[ \t\v\f]/; // newlines are handled in tokenizer
 | 
						|
 | 
						|
    function normal() {
 | 
						|
      return function (source, setState) {
 | 
						|
        if (source.eatWhile(whiteCharRE)) {
 | 
						|
          return null;
 | 
						|
        }
 | 
						|
 | 
						|
        var ch = source.next();
 | 
						|
        if (specialRE.test(ch)) {
 | 
						|
          if (ch == '{' && source.eat('-')) {
 | 
						|
            var t = "comment";
 | 
						|
            if (source.eat('#')) t = "meta";
 | 
						|
            return switchState(source, setState, ncomment(t, 1));
 | 
						|
          }
 | 
						|
          return null;
 | 
						|
        }
 | 
						|
 | 
						|
        if (ch == '\'') {
 | 
						|
          if (source.eat('\\'))
 | 
						|
            source.next();  // should handle other escapes here
 | 
						|
          else
 | 
						|
            source.next();
 | 
						|
 | 
						|
          if (source.eat('\''))
 | 
						|
            return "string";
 | 
						|
          return "error";
 | 
						|
        }
 | 
						|
 | 
						|
        if (ch == '"') {
 | 
						|
          return switchState(source, setState, stringLiteral);
 | 
						|
        }
 | 
						|
 | 
						|
        if (largeRE.test(ch)) {
 | 
						|
          source.eatWhile(idRE);
 | 
						|
          if (source.eat('.'))
 | 
						|
            return "qualifier";
 | 
						|
          return "variable-2";
 | 
						|
        }
 | 
						|
 | 
						|
        if (smallRE.test(ch)) {
 | 
						|
          var isDef = source.pos === 1;
 | 
						|
          source.eatWhile(idRE);
 | 
						|
          return isDef ? "variable-3" : "variable";
 | 
						|
        }
 | 
						|
 | 
						|
        if (digitRE.test(ch)) {
 | 
						|
          if (ch == '0') {
 | 
						|
            if (source.eat(/[xX]/)) {
 | 
						|
              source.eatWhile(hexitRE); // should require at least 1
 | 
						|
              return "integer";
 | 
						|
            }
 | 
						|
            if (source.eat(/[oO]/)) {
 | 
						|
              source.eatWhile(octitRE); // should require at least 1
 | 
						|
              return "number";
 | 
						|
            }
 | 
						|
          }
 | 
						|
          source.eatWhile(digitRE);
 | 
						|
          var t = "number";
 | 
						|
          if (source.eat('.')) {
 | 
						|
            t = "number";
 | 
						|
            source.eatWhile(digitRE); // should require at least 1
 | 
						|
          }
 | 
						|
          if (source.eat(/[eE]/)) {
 | 
						|
            t = "number";
 | 
						|
            source.eat(/[-+]/);
 | 
						|
            source.eatWhile(digitRE); // should require at least 1
 | 
						|
          }
 | 
						|
          return t;
 | 
						|
        }
 | 
						|
 | 
						|
        if (symbolRE.test(ch)) {
 | 
						|
          if (ch == '-' && source.eat(/-/)) {
 | 
						|
            source.eatWhile(/-/);
 | 
						|
            if (!source.eat(symbolRE)) {
 | 
						|
              source.skipToEnd();
 | 
						|
              return "comment";
 | 
						|
            }
 | 
						|
          }
 | 
						|
          source.eatWhile(symbolRE);
 | 
						|
          return "builtin";
 | 
						|
        }
 | 
						|
 | 
						|
        return "error";
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    function ncomment(type, nest) {
 | 
						|
      if (nest == 0) {
 | 
						|
        return normal();
 | 
						|
      }
 | 
						|
      return function(source, setState) {
 | 
						|
        var currNest = nest;
 | 
						|
        while (!source.eol()) {
 | 
						|
          var ch = source.next();
 | 
						|
          if (ch == '{' && source.eat('-')) {
 | 
						|
            ++currNest;
 | 
						|
          } else if (ch == '-' && source.eat('}')) {
 | 
						|
            --currNest;
 | 
						|
            if (currNest == 0) {
 | 
						|
              setState(normal());
 | 
						|
              return type;
 | 
						|
            }
 | 
						|
          }
 | 
						|
        }
 | 
						|
        setState(ncomment(type, currNest));
 | 
						|
        return type;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    function stringLiteral(source, setState) {
 | 
						|
      while (!source.eol()) {
 | 
						|
        var ch = source.next();
 | 
						|
        if (ch == '"') {
 | 
						|
          setState(normal());
 | 
						|
          return "string";
 | 
						|
        }
 | 
						|
        if (ch == '\\') {
 | 
						|
          if (source.eol() || source.eat(whiteCharRE)) {
 | 
						|
            setState(stringGap);
 | 
						|
            return "string";
 | 
						|
          }
 | 
						|
          if (!source.eat('&')) source.next(); // should handle other escapes here
 | 
						|
        }
 | 
						|
      }
 | 
						|
      setState(normal());
 | 
						|
      return "error";
 | 
						|
    }
 | 
						|
 | 
						|
    function stringGap(source, setState) {
 | 
						|
      if (source.eat('\\')) {
 | 
						|
        return switchState(source, setState, stringLiteral);
 | 
						|
      }
 | 
						|
      source.next();
 | 
						|
      setState(normal());
 | 
						|
      return "error";
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    var wellKnownWords = (function() {
 | 
						|
      var wkw = {};
 | 
						|
 | 
						|
      var keywords = [
 | 
						|
        "case", "of", "as",
 | 
						|
        "if", "then", "else",
 | 
						|
        "let", "in",
 | 
						|
        "infix", "infixl", "infixr",
 | 
						|
        "type", "alias",
 | 
						|
        "input", "output", "foreign", "loopback",
 | 
						|
        "module", "where", "import", "exposing",
 | 
						|
        "_", "..", "|", ":", "=", "\\", "\"", "->", "<-"
 | 
						|
      ];
 | 
						|
 | 
						|
      for (var i = keywords.length; i--;)
 | 
						|
        wkw[keywords[i]] = "keyword";
 | 
						|
 | 
						|
      return wkw;
 | 
						|
    })();
 | 
						|
 | 
						|
 | 
						|
 | 
						|
    return {
 | 
						|
      startState: function ()  { return { f: normal() }; },
 | 
						|
      copyState:  function (s) { return { f: s.f }; },
 | 
						|
 | 
						|
      token: function(stream, state) {
 | 
						|
        var t = state.f(stream, function(s) { state.f = s; });
 | 
						|
        var w = stream.current();
 | 
						|
        return (wellKnownWords.hasOwnProperty(w)) ? wellKnownWords[w] : t;
 | 
						|
      }
 | 
						|
    };
 | 
						|
 | 
						|
  });
 | 
						|
 | 
						|
  CodeMirror.defineMIME("text/x-elm", "elm");
 | 
						|
});
 |