{"version":3,"file":"reghex-core.mjs","sources":["../src/codegen.js","../src/parser.js","../src/core.js"],"sourcesContent":["const _state = 'state';\nconst _node = 'node';\nconst _match = 'x';\n\nfunction js(/* arguments */) {\n  let body = arguments[0][0];\n  for (let i = 1; i < arguments.length; i++)\n    body = body + arguments[i] + arguments[0][i];\n  return body.trim();\n}\n\nconst copy = (prev) => {\n  const next = {};\n  for (const key in prev) next[key] = prev[key];\n  return next;\n};\n\nconst assignIndex = (depth) => js`\n  var y${depth} = ${_state}.y,\n      x${depth} = ${_state}.x;\n`;\n\nconst restoreIndex = (depth) => js`\n  ${_state}.y = y${depth};\n  ${_state}.x = x${depth};\n`;\n\nconst astExpression = (ast, depth, opts) => {\n  const capture = !!opts.capture && !ast.capture;\n  const restoreLength =\n    (opts.length && opts.abort && js`${_node}.length = ln${opts.length};`) ||\n    '';\n  const condition = `(${_match} = ${ast.expression.id}(${_state})) ${\n    capture ? '!=' : '=='\n  } null`;\n  return js`\n    if (${condition}) ${\n    capture\n      ? js`{\n      ${_node}.push(${_match});\n    } else `\n      : ''\n  }{\n      ${restoreIndex(opts.index)}\n      ${restoreLength}\n      ${opts.abort}\n    }\n  `;\n};\n\nconst astGroup = (ast, depth, opts) => {\n  const capture = !!opts.capture && !ast.capture;\n\n  opts = copy(opts);\n  opts.capture = capture;\n\n  if (!opts.length && capture) {\n    opts.length = depth;\n    return js`\n      ${js`var ln${depth} = ${_node}.length;`}\n      ${astSequence(ast.sequence, depth + 1, opts)}\n    `;\n  }\n\n  return astSequence(ast.sequence, depth + 1, opts);\n};\n\nconst astChild = (ast, depth, opts) =>\n  ast.expression ? astExpression(ast, depth, opts) : astGroup(ast, depth, opts);\n\nconst astQuantifier = (ast, depth, opts) => {\n  const { index, abort } = opts;\n  const invert = `inv_${depth}`;\n  const group = `group_${depth}`;\n\n  opts = copy(opts);\n  if (ast.capture === '!') {\n    opts.index = depth;\n    opts.abort = js`break ${invert}`;\n  }\n\n  let child;\n  if (ast.quantifier === '+') {\n    const starAst = copy(ast);\n    starAst.quantifier = '*';\n    child = js`\n      ${astChild(ast, depth, opts)}\n      ${astQuantifier(starAst, depth, opts)}\n    `;\n  } else if (ast.quantifier === '*') {\n    opts.length = 0;\n    opts.index = depth;\n    opts.abort = js`break ${group};`;\n\n    child = js`\n      ${group}: for (;;) {\n        ${assignIndex(depth)}\n        ${astChild(ast, depth, opts)}\n      }\n    `;\n  } else if (ast.quantifier === '?' && ast.expression) {\n    opts.index = depth;\n    opts.abort = '';\n\n    child = js`\n      ${assignIndex(depth)}\n      ${astChild(ast, depth, opts)}\n    `;\n  } else if (ast.quantifier === '?') {\n    opts.index = depth;\n    opts.abort = js`break ${group}`;\n\n    child = js`\n      ${group}: {\n        ${assignIndex(depth)}\n        ${astChild(ast, depth, opts)}\n      }\n    `;\n  } else {\n    child = astChild(ast, depth, opts);\n  }\n\n  if (ast.capture === '!') {\n    return js`\n      ${invert}: {\n        ${assignIndex(depth)}\n        ${child}\n        ${restoreIndex(index)}\n        ${abort}\n      }\n    `;\n  } else if (ast.capture === '=') {\n    return js`\n      ${assignIndex(depth)}\n      ${child}\n      ${restoreIndex(depth)}\n    `;\n  } else {\n    return child;\n  }\n};\n\nconst astSequence = (ast, depth, opts) => {\n  const alternation = ast.alternation ? `alt_${depth}` : '';\n\n  let body = '';\n  for (; ast; ast = ast.alternation) {\n    const block = `block_${depth}`;\n\n    let childOpts = opts;\n    if (ast.alternation) {\n      childOpts = copy(opts);\n      childOpts.index = depth;\n      childOpts.abort = js`break ${block};`;\n    }\n\n    let sequence = '';\n    for (let i = 0; i < ast.length; i++)\n      sequence += astQuantifier(ast[i], depth, childOpts);\n\n    if (!ast.alternation) {\n      body += sequence;\n    } else {\n      body += js`\n        ${block}: {\n          ${assignIndex(depth)}\n          ${sequence}\n          break ${alternation};\n        }\n      `;\n    }\n  }\n\n  if (!alternation) return body;\n\n  return js`\n    ${alternation}: {\n      ${body}\n    }\n  `;\n};\n\nconst astRoot = (ast, name, transform) => {\n  return js`\n    (function (${_state}) {\n      ${assignIndex(1)}\n      var ${_node} = [];\n      var ${_match};\n\n      ${astSequence(ast, 2, {\n        index: 1,\n        length: 0,\n        abort: js`return;`,\n        capture: true,\n      })}\n\n      if (${name}) ${_node}.tag = ${name};\n      return ${transform ? js`(${transform})(${_node})` : _node};\n    })\n  `;\n};\n\nexport { astRoot };\n","const syntaxError = (char) => {\n  throw new SyntaxError('Unexpected token \"' + char + '\"');\n};\n\nexport const parse = (quasis, expressions) => {\n  let quasiIndex = 0;\n  let stackIndex = 0;\n\n  const sequenceStack = [];\n  const rootSequence = [];\n\n  let currentGroup = null;\n  let lastMatch;\n  let currentSequence = rootSequence;\n  let capture;\n\n  for (\n    let quasiIndex = 0, stackIndex = 0;\n    stackIndex < quasis.length + expressions.length;\n    stackIndex++\n  ) {\n    if (stackIndex % 2 !== 0) {\n      const expression = expressions[stackIndex++ >> 1];\n      currentSequence.push({ expression, capture });\n      capture = undefined;\n    }\n\n    const quasi = quasis[stackIndex >> 1];\n    for (quasiIndex = 0; quasiIndex < quasi.length; ) {\n      const char = quasi[quasiIndex++];\n      if (char === ' ' || char === '\\t' || char === '\\r' || char === '\\n') {\n      } else if (char === '|' && currentSequence.length) {\n        currentSequence = currentSequence.alternation = [];\n      } else if (char === ')' && currentSequence.length) {\n        currentGroup = null;\n        currentSequence = sequenceStack.pop();\n        if (!currentSequence) syntaxError(char);\n      } else if (char === '(') {\n        sequenceStack.push(currentSequence);\n        currentSequence.push((currentGroup = { sequence: [], capture }));\n        currentSequence = currentGroup.sequence;\n        capture = undefined;\n      } else if (char === ':' || char === '=' || char === '!') {\n        capture = char;\n        const nextChar = quasi[quasiIndex];\n        if (quasi[quasiIndex] && quasi[quasiIndex] !== '(') syntaxError(char);\n      } else if (char === '?' && !currentSequence.length && currentGroup) {\n        capture = quasi[quasiIndex++];\n        if (capture === ':' || capture === '=' || capture === '!') {\n          currentGroup.capture = capture;\n          capture = undefined;\n        } else {\n          syntaxError(char);\n        }\n      } else if (\n        (char === '?' || char === '+' || char === '*') &&\n        (lastMatch = currentSequence[currentSequence.length - 1])\n      ) {\n        lastMatch.quantifier = char;\n      } else {\n        syntaxError(char);\n      }\n    }\n  }\n\n  return rootSequence;\n};\n","import { astRoot } from './codegen';\nimport { parse as parseDSL } from './parser';\n\nconst isStickySupported = typeof /./g.sticky === 'boolean';\n\nconst execLambda = (pattern) => {\n  if (pattern.length) return pattern;\n  return (state) => pattern()(state);\n};\n\nconst execString = (pattern) => {\n  return (state) => {\n    if (state.x < state.quasis.length) {\n      const input = state.quasis[state.x];\n      for (let i = 0, l = pattern.length; i < l; i++)\n        if (input.charCodeAt(state.y + i) !== pattern.charCodeAt(i))\n          return null;\n      state.y += pattern.length;\n      return pattern;\n    }\n  };\n};\n\nconst execRegex = (pattern) => {\n  pattern = isStickySupported\n    ? new RegExp(pattern.source, 'y')\n    : new RegExp(pattern.source + '|()', 'g');\n  return (state) => {\n    if (state.x < state.quasis.length) {\n      const input = state.quasis[state.x];\n      pattern.lastIndex = state.y;\n      let match;\n      if (isStickySupported) {\n        if (pattern.test(input))\n          match = input.slice(state.y, pattern.lastIndex);\n      } else {\n        const x = pattern.exec(input);\n        if (x[1] == null) match = x[0];\n      }\n\n      state.y = pattern.lastIndex;\n      return match;\n    }\n  };\n};\n\nexport const __pattern = (input) => {\n  if (typeof input === 'function') {\n    return execLambda(input);\n  } else if (typeof input === 'string') {\n    return execString(input);\n  } else {\n    return execRegex(input);\n  }\n};\n\nexport const interpolation = (predicate) => (state) => {\n  let match;\n\n  if (\n    state.x < state.expressions.length &&\n    state.y >= state.quasis[state.x].length\n  ) {\n    state.y = 0;\n    match = state.expressions[state.x++];\n    if (predicate && match) match = predicate(match);\n  }\n\n  return match;\n};\n\nexport const parse = (matcher) => (quasis, ...expressions) => {\n  if (typeof quasis === 'string') quasis = [quasis];\n  const state = { quasis, expressions, x: 0, y: 0 };\n  return matcher(state);\n};\n\nexport const match = (name, transform) => (quasis, ...expressions) => {\n  const ast = parseDSL(\n    quasis,\n    expressions.map((_, i) => ({ id: `_${i}` }))\n  );\n  return new Function(\n    '_n,_t,' + expressions.map((_expression, i) => `_${i}`).join(','),\n    'return ' + astRoot(ast, '_n', transform ? '_t' : null)\n  )(name, transform, ...expressions.map(__pattern));\n};\n"],"names":["copy","next","const","_state","depth","capture","_node","index","group","abort","ast","child","quantifier","opts","invert","childOpts","block","sequence","i","body","char","let","pattern","length","state","stackIndex","y","quasiIndex","isStickySupported","match","input","x","_ref","_ref2","window","predicate","expressions","transform","currentSequence","expression","quasi","syntaxError","len","quasis"],"mappings":";AAaaA,QAAA;AACX,UAAW,EAAX,GAAA;;AAGIC,KAAA,EAAA,CAAA,OAAA;;;;;AAOJ,iBAAA,KAAA,gBAAA,KAAA,cAAA;;;AAIAC,SA5BaC,WA4BbD,IAAmCE,CAAnCF,gBAAAA,KAAAA,MAAAA;;cAuB8BE;;AAnBxBC,KAAAA,cAAAA,IAA4B,UAA5BA;mCA/BMC;AAkCZ,KAAA,GAAO,WAAP,mBAAA,cAAA,mBAAA,YAAA,oCAAA,QAAA,cAAA,KAAA,WAAA,MAAA;;AAIID,4DAIA,yGAKJ;;;;;AAQA,MAAIE,WAAJ,aAAA,gBAAA,EAGIC,YAAAA,GAAmBJ,CAHvB;;sCAQOK,CAAAA;mDAOuB,WACHC,gEAKzB,IAAA,GAFKH,CAAAA,KAEL,IAAA,GADKE,CAAAA,KACL,GADa,QACb,KAAA,MAAA,GAAAE,CAAA,IAAA,eAAA,QAAA,cAAA,MAAA,UACK,MAAQC,CAAAA,UAAR,gBAAA,2DAAA,OAIA,iBAAA,IACLV,OAEA,IAAA,EADAW,OACA,WAAA,IADyBL,CACzB,KAAA,GAAAG,CAAA,IAAA,QAAA,QAAA,cAAA,MAAA,GAHK,KAAA,KAKYD;6BAIJI,oDACR,MAAQT,CAAAA,OAAR,OAAA,KAAA,QAAA,KAAA;;;4CAQ8C;AAInD,wBAAA,EACIU,IAAYF,CADhB;iBAGA,kDAGgCG,QAHhC;aAMIC,mBAEgBP,UAAYQ,CAAA;;;AAO9BC,KAAA,GAHGT,aAAL,GAGES,CAHF,KAAA,QAAA,QAAA,KAAA,aAAA,KAAA,OAAA,UAAA,IAGE;;;;WAoBeC;AACnBlB,wBAAwB,+BAAxBA;;ACpIF,uCAAA;aAEoC;AAClCmB,SAAIC,CAAQC,CAAAA,MAAZF,IAAAA,YAIeG,EAAO;AACpBC,iBAAAA;AADoB,GAJtBJ;AADkC;UAUV,CAACC,CAAD;oBACA;;uDAIYJ;0BACHQ,CAAAA,IAAIR;AAC7B,qBAAA;;;;aAMGI;;AAZa;;;;iBAmBR,EAAA;QAEVE,MAAUG,QAAWJ,CAAAA;;;;AAKnBK,wBAEAC,mCAKF,UAFqBC,EAErB,MAAA,QAAA,MAAA,GACUC,CAAA,EAAA,CADV;;;;;;;uDCnDK,MAAOD;;AA6CpBE,QAASA;;;AAMTC;;;AAc+DC,MAAA,CAAA,SAAA,IAAA;AAC/DA,MAAA,CAAA,aAAA,YA3DgCC;kBACbX,EAAO;eAGFY,CAAAA;AAClBZ,SAAA,IAAA;;;;;AAJoB;CA0D1B;AACAU,MAAA,CAAA,KAAA,WAZqB,EAAA,EAAOG,CAAP;;;;;;;0BF0FfC,OACAjC;uBASA,cAAA,SAJqB,CACrBkC,WAAYA,CADS,WAAA,EAIrB,EAAAlC,CAAA;UAGEmC,KAAQ,EAAA,KAAA;;;wFAKRF,wFAQK,MAAA,+EAAA,+CASKlB,2CAKDA,uBACTf,CAEA,GAFUmC,CAAA,IAAA,CAEV,KAAA,MAAA,OAAA,MAAA,OAAA,MAAA,aAEE,IAAA,EAAAnC,CAAA,SAFF;iCCjMAoC,CAAA,EAAA;;;;;;;kFDuIJlB,2BAEAlB,6EAzIUC;;;CEwEd;AACA4B,MAAA,CAAA,KAAA,cA5C+B;;qBAGvBQ,aAAgBnB,CAAAA,MAAhBmB;;;iBAIA,MAAOC;;;AAPgB,CA4C/B;;"}