function words(e) {
  for (var c = {}, l = e.split(","), u = 0; u < l.length; ++u) {
    var d = l[u].toUpperCase(), f = l[u].charAt(0).toUpperCase() + l[u].slice(1);
    c[l[u]] = true, c[d] = true, c[f] = true;
  }
  return c;
}
function metaHook(e) {
  return e.eatWhile(/[\w\$_]/), "meta";
}
var atoms = words("null"), hooks = {
  "`": metaHook,
  $: metaHook
}, multiLineStrings = false, keywords = words("abs,access,after,alias,all,and,architecture,array,assert,attribute,begin,block,body,buffer,bus,case,component,configuration,constant,disconnect,downto,else,elsif,end,end block,end case,end component,end for,end generate,end if,end loop,end process,end record,end units,entity,exit,file,for,function,generate,generic,generic map,group,guarded,if,impure,in,inertial,inout,is,label,library,linkage,literal,loop,map,mod,nand,new,next,nor,null,of,on,open,or,others,out,package,package body,port,port map,postponed,procedure,process,pure,range,record,register,reject,rem,report,return,rol,ror,select,severity,signal,sla,sll,sra,srl,subtype,then,to,transport,type,unaffected,units,until,use,variable,wait,when,while,with,xnor,xor"), blockKeywords = words("architecture,entity,begin,case,port,else,elsif,end,for,function,if"), isOperatorChar = /[&|~><!\)\(*#%@+\/=?\:;}{,\.\^\-\[\]]/, curPunc;
function tokenBase(e, c) {
  var d = e.next();
  if (hooks[d]) {
    var m = hooks[d](e, c);
    if (m !== false) return m;
  }
  if (d == '"') return c.tokenize = tokenString2(d), c.tokenize(e, c);
  if (d == "'") return c.tokenize = tokenString(d), c.tokenize(e, c);
  if (/[\[\]{}\(\),;\:\.]/.test(d)) return curPunc = d, null;
  if (/[\d']/.test(d)) return e.eatWhile(/[\w\.']/), "number";
  if (d == "-" && e.eat("-")) return e.skipToEnd(), "comment";
  if (isOperatorChar.test(d)) return e.eatWhile(isOperatorChar), "operator";
  e.eatWhile(/[\w\$_]/);
  var h = e.current();
  return keywords.propertyIsEnumerable(h.toLowerCase()) ? (blockKeywords.propertyIsEnumerable(h) && (curPunc = "newstatement"), "keyword") : atoms.propertyIsEnumerable(h) ? "atom" : "variable";
}
function tokenString(e) {
  return function(c, l) {
    for (var u = false, f, p = false; (f = c.next()) != null; ) {
      if (f == e && !u) {
        p = true;
        break;
      }
      u = !u && f == "--";
    }
    return (p || !(u || multiLineStrings)) && (l.tokenize = tokenBase), "string";
  };
}
function tokenString2(e) {
  return function(c, l) {
    for (var u = false, f, p = false; (f = c.next()) != null; ) {
      if (f == e && !u) {
        p = true;
        break;
      }
      u = !u && f == "--";
    }
    return (p || !(u || multiLineStrings)) && (l.tokenize = tokenBase), "string.special";
  };
}
function Context(e, c, l, u, d) {
  this.indented = e, this.column = c, this.type = l, this.align = u, this.prev = d;
}
function pushContext(e, c, l) {
  return e.context = new Context(e.indented, c, l, null, e.context);
}
function popContext(e) {
  var c = e.context.type;
  return (c == ")" || c == "]" || c == "}") && (e.indented = e.context.indented), e.context = e.context.prev;
}
const vhdl = {
  name: "vhdl",
  startState: function(e) {
    return {
      tokenize: null,
      context: new Context(-e, 0, "top", false),
      indented: 0,
      startOfLine: true
    };
  },
  token: function(e, c) {
    var l = c.context;
    if (e.sol() && (l.align ?? (l.align = false), c.indented = e.indentation(), c.startOfLine = true), e.eatSpace()) return null;
    curPunc = null;
    var u = (c.tokenize || tokenBase)(e, c);
    if (u == "comment" || u == "meta") return u;
    if (l.align ?? (l.align = true), (curPunc == ";" || curPunc == ":") && l.type == "statement") popContext(c);
    else if (curPunc == "{") pushContext(c, e.column(), "}");
    else if (curPunc == "[") pushContext(c, e.column(), "]");
    else if (curPunc == "(") pushContext(c, e.column(), ")");
    else if (curPunc == "}") {
      for (; l.type == "statement"; ) l = popContext(c);
      for (l.type == "}" && (l = popContext(c)); l.type == "statement"; ) l = popContext(c);
    } else curPunc == l.type ? popContext(c) : (l.type == "}" || l.type == "top" || l.type == "statement" && curPunc == "newstatement") && pushContext(c, e.column(), "statement");
    return c.startOfLine = false, u;
  },
  indent: function(e, c, l) {
    if (e.tokenize != tokenBase && e.tokenize != null) return 0;
    var u = c && c.charAt(0), d = e.context, f = u == d.type;
    return d.type == "statement" ? d.indented + (u == "{" ? 0 : l.unit) : d.align ? d.column + (f ? 0 : 1) : d.indented + (f ? 0 : l.unit);
  },
  languageData: {
    indentOnInput: /^\s*[{}]$/,
    commentTokens: { line: "--" }
  }
};
export {
  vhdl as t
};
