puzzlescript
Version:
Play PuzzleScript games in your terminal!
101 lines • 3.54 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.BaseForLines = exports.getLineAndColumn = void 0;
// Return an object with the line and column information for the given
// offset in `str`.
// From https://github.com/harc/ohm/blob/b88336faf69e7bd89e309931b60445c3dfd495ab/src/util.js#L56
function getLineAndColumn(str, offset) {
let lineNum = 1;
let colNum = 1;
let currOffset = 0;
let lineStartOffset = 0;
let nextLine = null;
let prevLine = null;
let prevLineStartOffset = -1;
while (currOffset < offset) {
const c = str.charAt(currOffset++);
if (c === '\n') {
lineNum++;
colNum = 1;
prevLineStartOffset = lineStartOffset;
lineStartOffset = currOffset;
}
else if (c !== '\r') {
colNum++;
}
}
// Find the end of the target line.
let lineEndOffset = str.indexOf('\n', lineStartOffset);
if (lineEndOffset === -1) {
lineEndOffset = str.length;
}
else {
// Get the next line.
const nextLineEndOffset = str.indexOf('\n', lineEndOffset + 1);
nextLine = nextLineEndOffset === -1 ? str.slice(lineEndOffset)
: str.slice(lineEndOffset, nextLineEndOffset);
// Strip leading and trailing EOL char(s).
nextLine = nextLine.replace(/^\r?\n/, '').replace(/\r$/, '');
}
// Get the previous line.
if (prevLineStartOffset >= 0) {
prevLine = str.slice(prevLineStartOffset, lineStartOffset)
.replace(/\r?\n$/, ''); // Strip trailing EOL char(s).
}
// Get the target line, stripping a trailing carriage return if necessary.
const line = str.slice(lineStartOffset, lineEndOffset).replace(/\r$/, '');
return {
lineNum,
colNum,
line,
prevLine,
nextLine
};
}
exports.getLineAndColumn = getLineAndColumn;
class BaseForLines {
constructor(source) {
if (!source) {
throw new Error(`BUG: failed to provide the source when constructing this object`);
}
this.__source = source;
this.__coverageCount = null;
// This is only used for code coverage
if (process.env.NODE_ENV === 'development') {
this.__coverageCount = 0;
}
}
__getSourceLineAndColumn() {
const s = this.__source;
return getLineAndColumn(s.code, s.sourceOffset);
}
toString() {
const s = this.__source;
const { lineNum, colNum, line } = getLineAndColumn(s.code, s.sourceOffset);
return `${line}\nSource: ${lineNum}:${colNum}`;
}
toSourceString() {
const s = this.__source;
const { lineNum } = getLineAndColumn(s.code, s.sourceOffset);
return s.code.split('\n')[lineNum - 1];
}
// This is mostly used for creating code coverage for the games. So we know which Rules (or objects) are not being matched
__getLineAndColumnRange() {
const s = this.__source;
const { lineNum, colNum } = getLineAndColumn(s.code, s.sourceOffset);
return {
start: { line: lineNum, col: colNum },
end: { line: lineNum, col: colNum + 1 }
};
}
__incrementCoverage() {
if (process.env.NODE_ENV === 'development') {
if (!this.__coverageCount) {
this.__coverageCount = 0;
}
this.__coverageCount++;
}
}
}
exports.BaseForLines = BaseForLines;
//# sourceMappingURL=BaseForLines.js.map