<commit_before>const repl = require('repl')
const path = require('path')
const vm = require('vm')

function addAwaitOutside(replServer) {
  /*
  - allow whitespace before everything else
  - optionally capture `<varname> = `
    - varname only matches if it starts with a-Z or _ or $
      and if contains only those chars or numbers
    - this is overly restrictive but is easier to maintain
  - capture `await <anything that follows it>`
  */
  let re = /^\s*(?:([a-zA-Z_$][0-9a-zA-Z_$]*)\s*=\s*)?(await[\s\S]*)/

  const wrap = (code, binder) => {
    return `(async function() {
      let result = (${code.trim()});
      ${binder ? `global.${binder} = result` : 'return result'}
    }())`
  }

  replServer.eval = function(originalEval) {
    return function (cmd, context, filename, callback) {
      const match = cmd.match(re)

      if (!match) {
        return originalEval.call(this, cmd, context, filename, callback)
      }

      const code = wrap(match[2], match[1])

      vm.runInContext(code, vm.createContext(context))
        .then(r => callback(null, r), callback)
    }
  }(replServer.eval)
}

module.exports = addAwaitOutside<commit_msg>Recover from SyntaxErrors, handle all other errors gracefully'<commit_after>const repl = require('repl')
const vm = require('vm')

function addAwaitOutside(replServer) {
  /*
  - allow whitespace before everything else
  - optionally capture `<varname> = `
    - varname only matches if it starts with a-Z or _ or $
      and if contains only those chars or numbers
    - this is overly restrictive but is easier to maintain
  - capture `await <anything that follows it>`
  */
  let re = /^\s*(?:([a-zA-Z_$][0-9a-zA-Z_$]*)\s*=\s*)?(await[\s\S]*)/

  const wrap = (code, binder) => {
    return `(async function() {
      let result = (${code.trim()});
      ${binder ? `global.${binder} = result` : 'return result'}
    }())`
  }

  const isRecoverableError = (error) => {
    if (error.name === 'SyntaxError') {
      return /^(Unexpected end of input|Unexpected token)/.test(error.message)
    }
    return false
  }

  replServer.eval = function(originalEval) {
    return function (cmd, context, filename, callback) {
      const match = cmd.match(re)

      if (!match) {
        return originalEval.call(this, cmd, context, filename, callback)
      }

      const code = wrap(match[2], match[1])
      try {
        vm.runInContext(code, vm.createContext(context))
          .then(r => callback(null, r), callback)
      } catch (e) {
        callback(isRecoverableError(e) ? new repl.Recoverable(e) : e)
      }
    }
  }(replServer.eval)
}

module.exports = addAwaitOutside
{'fraction_non_alphanumeric': 0.1502649507948524, 'fraction_numerical': 0.003028009084027252, 'mean_word_length': 2.9924471299093653, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 12, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '28400', 'n_tokens_mistral': 876, 'n_tokens_neox': 844, 'n_words': 228}