var J, P, constantly, pairsToObject, removeDoubleBackslashes;

P = require('./pcom');

constantly = function(value) {
  return function() {
    return value;
  };
};

pairsToObject = function(pairs) {
  var object;
  object = {};
  pairs.forEach(function(pair) {
    return object[pair[0]] = pair[1];
  });
  return object;
};

removeDoubleBackslashes = function(string) {
  return string.replace(/\\n/g, '\n').replace(/\\r/g, '\r').replace(/\\t/g, '\t').replace(/\\"/g, '"').replace(/\\'/g, '\'').replace(/\\\\/g, '\\');
};

module.exports = J = {};

J["true"] = P.map(constantly(true), P.string('true'));

J["false"] = P.map(constantly(false), P.string('false'));

J["null"] = P.map(constantly(null), P.string('null'));

J.number = P.integer;

J.string = P.map(removeDoubleBackslashes, P.pick(1, P.string('"'), P.regex(/^(?:[^"\\]|\\.)*/), P.string('"')));

J.pair = P.pick([1, 5], P.whitespace, J.string, P.whitespace, P.string(':'), P.whitespace, P.lazy(function() {
  return J.value;
}), P.whitespace);

J.object = P.map(pairsToObject, P.pick(3, P.whitespace, P.string('{'), P.whitespace, P.separated(J.pair, P.string(',')), P.whitespace, P.string('}')));

J.array = P.pick(3, P.whitespace, P.string('['), P.whitespace, P.separated(P.pick(1, P.whitespace, P.lazy(function() {
  return J.value;
}), P.whitespace), P.string(',')), P.whitespace, P.string(']'));

J.value = P.firstChoice(J.string, J.number, J["true"], J["false"], J["null"], J.object, J.array);
