text: // 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('mllike', function(_config, parserConfig) {
    var words = {
      'let': 'keyword',
      'rec': 'keyword',
      'in': 'keyword',
      'of': 'keyword',
      'and': 'keyword',
      'if': 'keyword',
      'then': 'keyword',
      'else': 'keyword',
      'for': 'keyword',
      'to': 'keyword',
      'while': 'keyword',
      'do': 'keyword',
      'done': 'keyword',
      'fun': 'keyword',
      'function': 'keyword',
      'val': 'keyword',
      'type': 'keyword',
      'mutable': 'keyword',
      'match': 'keyword',
      'with': 'keyword',
      'try': 'keyword',
      'open': 'builtin',
      'ignore': 'builtin',
      'begin': 'keyword',
      'end': 'keyword'
    };
  
    var extraWords = parserConfig.extraWords || {};
    for (var prop in extraWords) {
      if (extraWords.hasOwnProperty(prop)) {
        words[prop] = parserConfig.extraWords[prop];
      }
    }
  
    function tokenBase(stream, state) {
      var ch = stream.next();
  
      if (ch === '"') {
        state.tokenize = tokenString;
        return state.tokenize(stream, state);
      }
      if (ch === '(') {
        if (stream.eat('*')) {
          state.commentLevel++;
          state.tokenize = tokenComment;
          return state.tokenize(stream, state);
        }
      }
      if (ch === '~') {
        stream.eatWhile(/\w/);
        return 'variable-2';
      }
      if (ch === '`') {
        stream.eatWhile(/\w/);
        return 'quote';
      }
      if (ch === '/' && parserConfig.slashComments && stream.eat('/')) {
        stream.skipToEnd();
        return 'comment';
      }
      if (/\d/.test(ch)) {
        stream.eatWhile(/[\d]/);
        if (stream.eat('.')) {
          stream.eatWhile(/[\d]/);
        }
        return 'number';
      }
      if ( /[+\-*&%=<>!?|]/.test(ch)) {
        return 'operator';
      }
      stream.eatWhile(/\w/);
      var cur = stream.current();
      return words.hasOwnProperty(cur) ? words[cur] : 'variable';
    }
  
    function tokenString(stream, state) {
      var next, end = false, escaped = false;
      while ((next = stream.next()) != null) {
        if (next === '"' && !escaped) {
          end = true;
          break;
        }
        escaped = !escaped && next === '\\';
      }
      if (end && !escaped) {
        state.tokenize = tokenBase;
      }
      return 'string';
    };
  
    function tokenComment(stream, state) {
      var prev, next;
      while(state.commentLevel > 0 && (next = stream.next()) != null) {
        if (prev === '(' && next === '*') state.commentLevel++;
        if (prev === '*' && next === ')') state.commentLevel--;
        prev = next;
      }
      if (state.commentLevel <= 0) {
        state.tokenize = tokenBase;
      }
      return 'comment';
    }
  
    return {
      startState: function() {return {tokenize: tokenBase, commentLevel: 0};},
      token: function(stream, state) {
        if (stream.eatSpace()) return null;
        return state.tokenize(stream, state);
      },
  
      blockCommentStart: "(*",
      blockCommentEnd: "*)",
      lineComment: parserConfig.slashComments ? "//" : null
    };
  });
  
  CodeMirror.defineMIME('text/x-ocaml', {
    name: 'mllike',
    extraWords: {
      'succ': 'keyword',
      'trace': 'builtin',
      'exit': 'builtin',
      'print_string': 'builtin',
      'print_endline': 'builtin',
      'true': 'atom',
      'false': 'atom',
      'raise': 'keyword'
    }
  });
  
  CodeMirror.defineMIME('text/x-fsharp', {
    name: 'mllike',
    extraWords: {
      'abstract': 'keyword',
      'as': 'keyword',
      'assert': 'keyword',
      'base': 'keyword',
      'class': 'keyword',
      'default': 'keyword',
      'delegate': 'keyword',
      'downcast': 'keyword',
      'downto': 'keyword',
      'elif': 'keyword',
      'exception': 'keyword',
      'extern': 'keyword',
      'finally': 'keyword',
      'global': 'keyword',
      'inherit': 'keyword',
      'inline': 'keyword',
      'interface': 'keyword',
      'internal': 'keyword',
      'lazy': 'keyword',
      'let!': 'keyword',
      'member' : 'keyword',
      'module': 'keyword',
      'namespace': 'keyword',
      'new': 'keyword',
      'null': 'keyword',
      'override': 'keyword',
      'private': 'keyword',
      'public': 'keyword',
      'return': 'keyword',
      'return!': 'keyword',
      'select': 'keyword',
      'static': 'keyword',
      'struct': 'keyword',
      'upcast': 'keyword',
      'use': 'keyword',
      'use!': 'keyword',
      'val': 'keyword',
      'when': 'keyword',
      'yield': 'keyword',
      'yield!': 'keyword',
  
      'List': 'builtin',
      'Seq': 'builtin',
      'Map': 'builtin',
      'Set': 'builtin',
      'int': 'builtin',
      'string': 'builtin',
      'raise': 'builtin',
      'failwith': 'builtin',
      'not': 'builtin',
      'true': 'builtin',
      'false': 'builtin'
    },
    slashComments: true
  });
  
  });
  