Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Brian Mock committed Jan 31, 2018
1 parent 13d84f2 commit fb569e0
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 7 deletions.
53 changes: 46 additions & 7 deletions src/parsimmon.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ function isArray(x) {
return {}.toString.call(x) === "[object Array]";
}

var hasBuffer = typeof Buffer !== "undefined";
function isBuffer(x) {
/* global Buffer */
return hasBuffer && Buffer.isBuffer(x);
}

function makeSuccess(index, value) {
return {
status: true,
Expand Down Expand Up @@ -60,6 +66,13 @@ function mergeReplies(result, last) {
}

function makeLineColumnIndex(input, i) {
if (isBuffer(input)) {
return {
offset: i,
line: -1,
column: -1
};
}
var lines = input.slice(0, i).split("\n");
// Note that unlike the character offset, the line and column offsets are
// 1-based.
Expand Down Expand Up @@ -110,6 +123,13 @@ function assertParser(p) {
}
}

function get(input, i) {
if (typeof input === "string") {
return input.charAt(i);
}
return input[i];
}

// TODO[ES5]: Switch to Array.isArray eventually.
function assertArray(x) {
if (!isArray(x)) {
Expand Down Expand Up @@ -164,6 +184,9 @@ function formatGot(input, error) {
if (i === input.length) {
return ", got the end of the input";
}
if (isBuffer(input)) {
return " at byte " + index.offset;
}
var prefix = i > 0 ? "'..." : "'";
var suffix = input.length - i > 12 ? "...'" : "'";
return (
Expand Down Expand Up @@ -336,8 +359,10 @@ function sepBy1(parser, separator) {
// -*- Core Parsing Methods -*-

_.parse = function(input) {
if (typeof input !== "string") {
throw new Error(".parse must be called with a string as its argument");
if (typeof input !== "string" && !isBuffer(input)) {
throw new Error(
".parse must be called with a string or Buffer as its argument"
);
}
var result = this.skip(eof)._(input, 0);
if (result.status) {
Expand Down Expand Up @@ -585,6 +610,19 @@ function string(str) {
});
}

function byte(b) {
assertNumber(b);
var expected = (b > 0xf ? "0x" : "0x0") + b.toString(16);
return Parsimmon(function(input, i) {
var head = get(input, i);
if (head === b) {
return makeSuccess(i + 1, head);
} else {
return makeFailure(i, expected);
}
});
}

function regexp(re, group) {
assertRegexp(re);
if (arguments.length >= 2) {
Expand Down Expand Up @@ -652,11 +690,11 @@ function notFollowedBy(parser) {
function test(predicate) {
assertFunction(predicate);
return Parsimmon(function(input, i) {
var char = input.charAt(i);
var char = get(input, i);
if (i < input.length && predicate(char)) {
return makeSuccess(i + 1, char);
} else {
return makeFailure(i, "a character matching " + predicate);
return makeFailure(i, "a character/byte matching " + predicate);
}
});
}
Expand Down Expand Up @@ -689,7 +727,7 @@ function takeWhile(predicate) {

return Parsimmon(function(input, i) {
var j = i;
while (j < input.length && predicate(input.charAt(j))) {
while (j < input.length && predicate(get(input, j))) {
j++;
}
return makeSuccess(j, input.slice(i, j));
Expand Down Expand Up @@ -738,9 +776,9 @@ var index = Parsimmon(function(input, i) {

var any = Parsimmon(function(input, i) {
if (i >= input.length) {
return makeFailure(i, "any character");
return makeFailure(i, "any character/byte");
}
return makeSuccess(i + 1, input.charAt(i));
return makeSuccess(i + 1, get(input, i));
});

var all = Parsimmon(function(input, i) {
Expand All @@ -764,6 +802,7 @@ var whitespace = regexp(/\s+/).desc("whitespace");
Parsimmon.all = all;
Parsimmon.alt = alt;
Parsimmon.any = any;
Parsimmon.byte = byte;
Parsimmon.createLanguage = createLanguage;
Parsimmon.custom = custom;
Parsimmon.digit = digit;
Expand Down
21 changes: 21 additions & 0 deletions test/core/byte.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"use strict";

suite("byte", function() {
test("it matches a buffer byte", function() {
var b = Buffer.from([0xf]);
var p = Parsimmon.byte(0xf);
assert.ok(p.parse(b).value);
});

test("it formats single digit bytes like 0x0f", function() {
var b = Buffer.from([0xa]);
var p = Parsimmon.byte(0xf);
assert.deepEqual(p.parse(b).expected, ["0x0f"]);
});

test("it formats double digit bytes like 0xff", function() {
var b = Buffer.from([0x12]);
var p = Parsimmon.byte(0xff);
assert.deepEqual(p.parse(b).expected, ["0xff"]);
});
});
6 changes: 6 additions & 0 deletions test/core/test.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,14 @@ test("test", function() {
var parser = Parsimmon.test(function(ch) {
return ch !== ".";
});
var highBit = Parsimmon.test(function(ch) {
return ch | 128;
});
assert.equal(parser.parse("x").value, "x");
assert.equal(parser.parse(".").status, false);
assert.equal(highBit.parse(Buffer.from([255])).status, true);
assert.equal(highBit.parse(Buffer.from([0])).status, true);
assert.equal(highBit.parse(Buffer.from([127])).status, true);
assert.throws(function() {
Parsimmon.test("not a function");
});
Expand Down

0 comments on commit fb569e0

Please sign in to comment.