function mlLike(e) {
  var t = {
    as: "keyword",
    do: "keyword",
    else: "keyword",
    end: "keyword",
    exception: "keyword",
    fun: "keyword",
    functor: "keyword",
    if: "keyword",
    in: "keyword",
    include: "keyword",
    let: "keyword",
    of: "keyword",
    open: "keyword",
    rec: "keyword",
    struct: "keyword",
    then: "keyword",
    type: "keyword",
    val: "keyword",
    while: "keyword",
    with: "keyword"
  }, n = e.extraWords || {};
  for (var r in n) n.hasOwnProperty(r) && (t[r] = e.extraWords[r]);
  var i = [];
  for (var a in t) i.push(a);
  function o(n2, r2) {
    var i2 = n2.next();
    if (i2 === '"') return r2.tokenize = s, r2.tokenize(n2, r2);
    if (i2 === "{" && n2.eat("|")) return r2.longString = true, r2.tokenize = l, r2.tokenize(n2, r2);
    if (i2 === "(" && n2.match(/^\*(?!\))/)) return r2.commentLevel++, r2.tokenize = c, r2.tokenize(n2, r2);
    if (i2 === "~" || i2 === "?") return n2.eatWhile(/\w/), "variableName.special";
    if (i2 === "`") return n2.eatWhile(/\w/), "quote";
    if (i2 === "/" && e.slashComments && n2.eat("/")) return n2.skipToEnd(), "comment";
    if (/\d/.test(i2)) return i2 === "0" && n2.eat(/[bB]/) && n2.eatWhile(/[01]/), i2 === "0" && n2.eat(/[xX]/) && n2.eatWhile(/[0-9a-fA-F]/), i2 === "0" && n2.eat(/[oO]/) ? n2.eatWhile(/[0-7]/) : (n2.eatWhile(/[\d_]/), n2.eat(".") && n2.eatWhile(/[\d]/), n2.eat(/[eE]/) && n2.eatWhile(/[\d\-+]/)), "number";
    if (/[+\-*&%=<>!?|@\.~:]/.test(i2)) return "operator";
    if (/[\w\xa1-\uffff]/.test(i2)) {
      n2.eatWhile(/[\w\xa1-\uffff]/);
      var a2 = n2.current();
      return t.hasOwnProperty(a2) ? t[a2] : "variable";
    }
    return null;
  }
  function s(e2, t2) {
    for (var n2, r2 = false, i2 = false; (n2 = e2.next()) != null; ) {
      if (n2 === '"' && !i2) {
        r2 = true;
        break;
      }
      i2 = !i2 && n2 === "\\";
    }
    return r2 && !i2 && (t2.tokenize = o), "string";
  }
  function c(e2, t2) {
    for (var n2, r2; t2.commentLevel > 0 && (r2 = e2.next()) != null; ) n2 === "(" && r2 === "*" && t2.commentLevel++, n2 === "*" && r2 === ")" && t2.commentLevel--, n2 = r2;
    return t2.commentLevel <= 0 && (t2.tokenize = o), "comment";
  }
  function l(e2, t2) {
    for (var n2, r2; t2.longString && (r2 = e2.next()) != null; ) n2 === "|" && r2 === "}" && (t2.longString = false), n2 = r2;
    return t2.longString || (t2.tokenize = o), "string";
  }
  return {
    startState: function() {
      return {
        tokenize: o,
        commentLevel: 0,
        longString: false
      };
    },
    token: function(e2, t2) {
      return e2.eatSpace() ? null : t2.tokenize(e2, t2);
    },
    languageData: {
      autocomplete: i,
      commentTokens: {
        line: e.slashComments ? "//" : void 0,
        block: {
          open: "(*",
          close: "*)"
        }
      }
    }
  };
}
const oCaml = mlLike({
  name: "ocaml",
  extraWords: {
    and: "keyword",
    assert: "keyword",
    begin: "keyword",
    class: "keyword",
    constraint: "keyword",
    done: "keyword",
    downto: "keyword",
    external: "keyword",
    function: "keyword",
    initializer: "keyword",
    lazy: "keyword",
    match: "keyword",
    method: "keyword",
    module: "keyword",
    mutable: "keyword",
    new: "keyword",
    nonrec: "keyword",
    object: "keyword",
    private: "keyword",
    sig: "keyword",
    to: "keyword",
    try: "keyword",
    value: "keyword",
    virtual: "keyword",
    when: "keyword",
    raise: "builtin",
    failwith: "builtin",
    true: "builtin",
    false: "builtin",
    asr: "builtin",
    land: "builtin",
    lor: "builtin",
    lsl: "builtin",
    lsr: "builtin",
    lxor: "builtin",
    mod: "builtin",
    or: "builtin",
    raise_notrace: "builtin",
    trace: "builtin",
    exit: "builtin",
    print_string: "builtin",
    print_endline: "builtin",
    int: "type",
    float: "type",
    bool: "type",
    char: "type",
    string: "type",
    unit: "type",
    List: "builtin"
  }
}), fSharp = mlLike({
  name: "fsharp",
  extraWords: {
    abstract: "keyword",
    assert: "keyword",
    base: "keyword",
    begin: "keyword",
    class: "keyword",
    default: "keyword",
    delegate: "keyword",
    "do!": "keyword",
    done: "keyword",
    downcast: "keyword",
    downto: "keyword",
    elif: "keyword",
    extern: "keyword",
    finally: "keyword",
    for: "keyword",
    function: "keyword",
    global: "keyword",
    inherit: "keyword",
    inline: "keyword",
    interface: "keyword",
    internal: "keyword",
    lazy: "keyword",
    "let!": "keyword",
    match: "keyword",
    member: "keyword",
    module: "keyword",
    mutable: "keyword",
    namespace: "keyword",
    new: "keyword",
    null: "keyword",
    override: "keyword",
    private: "keyword",
    public: "keyword",
    "return!": "keyword",
    return: "keyword",
    select: "keyword",
    static: "keyword",
    to: "keyword",
    try: "keyword",
    upcast: "keyword",
    "use!": "keyword",
    use: "keyword",
    void: "keyword",
    when: "keyword",
    "yield!": "keyword",
    yield: "keyword",
    atomic: "keyword",
    break: "keyword",
    checked: "keyword",
    component: "keyword",
    const: "keyword",
    constraint: "keyword",
    constructor: "keyword",
    continue: "keyword",
    eager: "keyword",
    event: "keyword",
    external: "keyword",
    fixed: "keyword",
    method: "keyword",
    mixin: "keyword",
    object: "keyword",
    parallel: "keyword",
    process: "keyword",
    protected: "keyword",
    pure: "keyword",
    sealed: "keyword",
    tailcall: "keyword",
    trait: "keyword",
    virtual: "keyword",
    volatile: "keyword",
    List: "builtin",
    Seq: "builtin",
    Map: "builtin",
    Set: "builtin",
    Option: "builtin",
    int: "builtin",
    string: "builtin",
    not: "builtin",
    true: "builtin",
    false: "builtin",
    raise: "builtin",
    failwith: "builtin"
  },
  slashComments: true
}), sml = mlLike({
  name: "sml",
  extraWords: {
    abstype: "keyword",
    and: "keyword",
    andalso: "keyword",
    case: "keyword",
    datatype: "keyword",
    fn: "keyword",
    handle: "keyword",
    infix: "keyword",
    infixr: "keyword",
    local: "keyword",
    nonfix: "keyword",
    op: "keyword",
    orelse: "keyword",
    raise: "keyword",
    withtype: "keyword",
    eqtype: "keyword",
    sharing: "keyword",
    sig: "keyword",
    signature: "keyword",
    structure: "keyword",
    where: "keyword",
    true: "keyword",
    false: "keyword",
    int: "builtin",
    real: "builtin",
    string: "builtin",
    char: "builtin",
    bool: "builtin"
  },
  slashComments: true
});
export {
  oCaml as n,
  sml as r,
  fSharp as t
};
