mirror of
https://github.com/seigler/rockstar-playground
synced 2025-07-26 01:06:10 +00:00
Tidy project
This commit is contained in:
parent
20b8d44de1
commit
abca4965a3
26 changed files with 2315 additions and 465 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
node_modules/
|
14
README.md
Normal file
14
README.md
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
# Rockstar Playground
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
To make it easy to develop Rockstar solutions to Advent of Code style problems (with an input file and no interactivity).
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
`npm install`
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
`node start <trackname>`
|
||||||
|
Rock source code named `<trackname>.rock` will be used first from the `lyrics` folder, or else from the `contracts` folder (intended for un-poetic works in progress). File input is expected as `<trackname>.txt` in the `music` folder.
|
||||||
|
|
||||||
|
### Development
|
||||||
|
`npx nodemon start <trackname>` will re-run the program whenever it is altered.
|
6
contracts/2020-02.rock
Normal file
6
contracts/2020-02.rock
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
Rock Input
|
||||||
|
Listen to Line
|
||||||
|
Until Line is gone
|
||||||
|
Rock Input with Line
|
||||||
|
Listen to Line
|
||||||
|
(end until)
|
3
music/2020-02.txt
Normal file
3
music/2020-02.txt
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
1-3 a: abcde
|
||||||
|
1-3 b: cdefg
|
||||||
|
2-9 c: ccccccccc
|
16
node_modules/.package-lock.json
generated
vendored
16
node_modules/.package-lock.json
generated
vendored
|
@ -1,16 +0,0 @@
|
||||||
{
|
|
||||||
"name": "advent-of-code-2020-rockstar",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"lockfileVersion": 2,
|
|
||||||
"requires": true,
|
|
||||||
"packages": {
|
|
||||||
"node_modules/n-readlines": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/n-readlines/-/n-readlines-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-z4SyAIVgMy7CkgsoNw7YVz40v0g4+WWvvqy8+ZdHrCtgevcEO758WQyrYcw3XPxcLxF+//RszTz/rO48nzD0wQ==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6.x.x"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
6
node_modules/n-readlines/.travis.yml
generated
vendored
6
node_modules/n-readlines/.travis.yml
generated
vendored
|
@ -1,6 +0,0 @@
|
||||||
language: node_js
|
|
||||||
os:
|
|
||||||
- linux
|
|
||||||
- osx
|
|
||||||
node_js:
|
|
||||||
- "6"
|
|
20
node_modules/n-readlines/LICENSE
generated
vendored
20
node_modules/n-readlines/LICENSE
generated
vendored
|
@ -1,20 +0,0 @@
|
||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) 2013 Liucw
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
||||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
||||||
subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
||||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
||||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
||||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
||||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
53
node_modules/n-readlines/README.md
generated
vendored
53
node_modules/n-readlines/README.md
generated
vendored
|
@ -1,53 +0,0 @@
|
||||||
[](https://travis-ci.org/nacholibre/node-readlines)
|
|
||||||
# node-readlines
|
|
||||||
Reading file line by line may seem like a trivial problem, but in node, there is no straightforward way to do it. There are a lot of libraries using Transform Streams to achieve it, but it seems like a overkill, so I've wrote simple version using only the `filesystem` module of node. Note that this is *synchronous* library.
|
|
||||||
|
|
||||||
Install with
|
|
||||||
`npm install n-readlines`
|
|
||||||
|
|
||||||
---------------------------------------
|
|
||||||
|
|
||||||
## Documentation
|
|
||||||
### new readlines(filename, [options]);
|
|
||||||
### new readlines(fd, [options]);
|
|
||||||
|
|
||||||
**Arguments**
|
|
||||||
|
|
||||||
* `filename` - String path to the file you want to read from
|
|
||||||
* `fd` - File descriptor
|
|
||||||
* `options` - Object
|
|
||||||
* `readChunk` - Integer number of bytes to read at once. Default: 1024
|
|
||||||
* `newLineCharacter` - String new line character, only works with one byte characters for now. Default: `\n` which is `0x0a` hex encoded
|
|
||||||
|
|
||||||
`node-readlines` can handle files without newLineCharacter after the last line
|
|
||||||
|
|
||||||
---------------------------------------
|
|
||||||
|
|
||||||
### readlines.next()
|
|
||||||
Returns `buffer` with the line data without the `newLineCharacter` or `false` if end of file is reached.
|
|
||||||
|
|
||||||
---------------------------------------
|
|
||||||
### readlines.reset()
|
|
||||||
Resets the pointer and starts from the beginning of the file. This works only if the end is not reached.
|
|
||||||
|
|
||||||
---------------------------------------
|
|
||||||
### readlines.close()
|
|
||||||
Manually close the open file, subsequent `next()` calls will return false. This works only if the end is not reached.
|
|
||||||
|
|
||||||
---------------------------------------
|
|
||||||
|
|
||||||
## Example
|
|
||||||
```javascript
|
|
||||||
const lineByLine = require('n-readlines');
|
|
||||||
const liner = new lineByLine('./test/fixtures/normalFile.txt');
|
|
||||||
|
|
||||||
let line;
|
|
||||||
let lineNumber = 0;
|
|
||||||
|
|
||||||
while (line = liner.next()) {
|
|
||||||
console.log('Line ' + lineNumber + ': ' + line.toString('ascii'));
|
|
||||||
lineNumber++;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('end of line reached');
|
|
||||||
```
|
|
14
node_modules/n-readlines/example.js
generated
vendored
14
node_modules/n-readlines/example.js
generated
vendored
|
@ -1,14 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
const lineByLine = require('./readlines.js');
|
|
||||||
const liner = new lineByLine('./test/fixtures/normalFile.txt');
|
|
||||||
|
|
||||||
let line;
|
|
||||||
let lineNumber = 0;
|
|
||||||
|
|
||||||
while (line = liner.next()) {
|
|
||||||
console.log('Line ' + lineNumber + ': ' + line.toString('ascii'));
|
|
||||||
lineNumber++;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('end of line reached');
|
|
34
node_modules/n-readlines/package.json
generated
vendored
34
node_modules/n-readlines/package.json
generated
vendored
|
@ -1,34 +0,0 @@
|
||||||
{
|
|
||||||
"name": "n-readlines",
|
|
||||||
"version": "1.0.1",
|
|
||||||
"description": "Read file line by line without buffering the whole file in memory.",
|
|
||||||
"main": "./readlines.js",
|
|
||||||
"dependencies": {},
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "http://github.com/nacholibre/node-readlines.git"
|
|
||||||
},
|
|
||||||
"keywords": [
|
|
||||||
"read",
|
|
||||||
"line",
|
|
||||||
"reader",
|
|
||||||
"linereader",
|
|
||||||
"readfile",
|
|
||||||
"linebyline",
|
|
||||||
"synchronous",
|
|
||||||
"sync",
|
|
||||||
"readline",
|
|
||||||
"readlines"
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6.x.x"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"tape": "^4.9.0"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"test": "tape test/*.test.js"
|
|
||||||
},
|
|
||||||
"author": "Yoan Arnaudov <jonidev@gmail.com>",
|
|
||||||
"license": "MIT"
|
|
||||||
}
|
|
159
node_modules/n-readlines/readlines.js
generated
vendored
159
node_modules/n-readlines/readlines.js
generated
vendored
|
@ -1,159 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
const fs = require('fs');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @class
|
|
||||||
*/
|
|
||||||
class LineByLine {
|
|
||||||
constructor(file, options) {
|
|
||||||
options = options || {};
|
|
||||||
|
|
||||||
if (!options.readChunk) options.readChunk = 1024;
|
|
||||||
|
|
||||||
if (!options.newLineCharacter) {
|
|
||||||
options.newLineCharacter = 0x0a; //linux line ending
|
|
||||||
} else {
|
|
||||||
options.newLineCharacter = options.newLineCharacter.charCodeAt(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof file === 'number') {
|
|
||||||
this.fd = file;
|
|
||||||
} else {
|
|
||||||
this.fd = fs.openSync(file, 'r');
|
|
||||||
}
|
|
||||||
|
|
||||||
this.options = options;
|
|
||||||
|
|
||||||
this.newLineCharacter = options.newLineCharacter;
|
|
||||||
|
|
||||||
this.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
_searchInBuffer(buffer, hexNeedle) {
|
|
||||||
let found = -1;
|
|
||||||
|
|
||||||
for (let i = 0; i <= buffer.length; i++) {
|
|
||||||
let b_byte = buffer[i];
|
|
||||||
if (b_byte === hexNeedle) {
|
|
||||||
found = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
|
|
||||||
reset() {
|
|
||||||
this.eofReached = false;
|
|
||||||
this.linesCache = [];
|
|
||||||
this.fdPosition = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
close() {
|
|
||||||
fs.closeSync(this.fd);
|
|
||||||
this.fd = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
_extractLines(buffer) {
|
|
||||||
let line;
|
|
||||||
const lines = [];
|
|
||||||
let bufferPosition = 0;
|
|
||||||
|
|
||||||
let lastNewLineBufferPosition = 0;
|
|
||||||
while (true) {
|
|
||||||
let bufferPositionValue = buffer[bufferPosition++];
|
|
||||||
|
|
||||||
if (bufferPositionValue === this.newLineCharacter) {
|
|
||||||
line = buffer.slice(lastNewLineBufferPosition, bufferPosition);
|
|
||||||
lines.push(line);
|
|
||||||
lastNewLineBufferPosition = bufferPosition;
|
|
||||||
} else if (bufferPositionValue === undefined) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let leftovers = buffer.slice(lastNewLineBufferPosition, bufferPosition);
|
|
||||||
if (leftovers.length) {
|
|
||||||
lines.push(leftovers);
|
|
||||||
}
|
|
||||||
|
|
||||||
return lines;
|
|
||||||
};
|
|
||||||
|
|
||||||
_readChunk(lineLeftovers) {
|
|
||||||
let totalBytesRead = 0;
|
|
||||||
|
|
||||||
let bytesRead;
|
|
||||||
const buffers = [];
|
|
||||||
do {
|
|
||||||
const readBuffer = new Buffer(this.options.readChunk);
|
|
||||||
|
|
||||||
bytesRead = fs.readSync(this.fd, readBuffer, 0, this.options.readChunk, this.fdPosition);
|
|
||||||
totalBytesRead = totalBytesRead + bytesRead;
|
|
||||||
|
|
||||||
this.fdPosition = this.fdPosition + bytesRead;
|
|
||||||
|
|
||||||
buffers.push(readBuffer);
|
|
||||||
} while (bytesRead && this._searchInBuffer(buffers[buffers.length-1], this.options.newLineCharacter) === -1);
|
|
||||||
|
|
||||||
let bufferData = Buffer.concat(buffers);
|
|
||||||
|
|
||||||
if (bytesRead < this.options.readChunk) {
|
|
||||||
this.eofReached = true;
|
|
||||||
bufferData = bufferData.slice(0, totalBytesRead);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (totalBytesRead) {
|
|
||||||
this.linesCache = this._extractLines(bufferData);
|
|
||||||
|
|
||||||
if (lineLeftovers) {
|
|
||||||
this.linesCache[0] = Buffer.concat([lineLeftovers, this.linesCache[0]]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return totalBytesRead;
|
|
||||||
}
|
|
||||||
|
|
||||||
next() {
|
|
||||||
if (!this.fd) return false;
|
|
||||||
|
|
||||||
let line = false;
|
|
||||||
|
|
||||||
if (this.eofReached && this.linesCache.length === 0) {
|
|
||||||
return line;
|
|
||||||
}
|
|
||||||
|
|
||||||
let bytesRead;
|
|
||||||
|
|
||||||
if (!this.linesCache.length) {
|
|
||||||
bytesRead = this._readChunk();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.linesCache.length) {
|
|
||||||
line = this.linesCache.shift();
|
|
||||||
|
|
||||||
const lastLineCharacter = line[line.length-1];
|
|
||||||
|
|
||||||
if (lastLineCharacter !== this.newLineCharacter) {
|
|
||||||
bytesRead = this._readChunk(line);
|
|
||||||
|
|
||||||
if (bytesRead) {
|
|
||||||
line = this.linesCache.shift();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.eofReached && this.linesCache.length === 0) {
|
|
||||||
this.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (line && line[line.length-1] === this.newLineCharacter) {
|
|
||||||
line = line.slice(0, line.length-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return line;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = LineByLine;
|
|
2
node_modules/n-readlines/test/fixtures/badEndFile.txt
generated
vendored
2
node_modules/n-readlines/test/fixtures/badEndFile.txt
generated
vendored
|
@ -1,2 +0,0 @@
|
||||||
google.com
|
|
||||||
yahoo.com
|
|
3
node_modules/n-readlines/test/fixtures/bigLines.json
generated
vendored
3
node_modules/n-readlines/test/fixtures/bigLines.json
generated
vendored
File diff suppressed because one or more lines are too long
1
node_modules/n-readlines/test/fixtures/eiffel.geojson
generated
vendored
1
node_modules/n-readlines/test/fixtures/eiffel.geojson
generated
vendored
File diff suppressed because one or more lines are too long
0
node_modules/n-readlines/test/fixtures/emptyFile.txt
generated
vendored
0
node_modules/n-readlines/test/fixtures/emptyFile.txt
generated
vendored
1
node_modules/n-readlines/test/fixtures/noNewLinesFile.txt
generated
vendored
1
node_modules/n-readlines/test/fixtures/noNewLinesFile.txt
generated
vendored
|
@ -1 +0,0 @@
|
||||||
no new line
|
|
3
node_modules/n-readlines/test/fixtures/normalFile.txt
generated
vendored
3
node_modules/n-readlines/test/fixtures/normalFile.txt
generated
vendored
|
@ -1,3 +0,0 @@
|
||||||
google.com
|
|
||||||
yahoo.com
|
|
||||||
yandex.ru
|
|
2
node_modules/n-readlines/test/fixtures/twoLineFile.txt
generated
vendored
2
node_modules/n-readlines/test/fixtures/twoLineFile.txt
generated
vendored
|
@ -1,2 +0,0 @@
|
||||||
hello
|
|
||||||
hello2
|
|
5
node_modules/n-readlines/test/fixtures/withEmptyLines.txt
generated
vendored
5
node_modules/n-readlines/test/fixtures/withEmptyLines.txt
generated
vendored
|
@ -1,5 +0,0 @@
|
||||||
hello
|
|
||||||
hello4
|
|
||||||
|
|
||||||
hello2
|
|
||||||
hello3
|
|
BIN
node_modules/n-readlines/test/fixtures/withNULL.txt
generated
vendored
BIN
node_modules/n-readlines/test/fixtures/withNULL.txt
generated
vendored
Binary file not shown.
132
node_modules/n-readlines/test/readlines.test.js
generated
vendored
132
node_modules/n-readlines/test/readlines.test.js
generated
vendored
|
@ -1,132 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
const lineByLine = require('../readlines.js');
|
|
||||||
const path = require('path');
|
|
||||||
const test = require('tape');
|
|
||||||
|
|
||||||
test('should get all lines', (t) => {
|
|
||||||
const liner = new lineByLine(path.resolve(__dirname, 'fixtures/twoLineFile.txt'));
|
|
||||||
|
|
||||||
t.equals(liner.next().toString('ascii'), 'hello', 'line 0: hello');
|
|
||||||
t.equals(liner.next().toString('ascii'), 'hello2', 'line 1: hello2');
|
|
||||||
t.equals(liner.next(), false, 'line 3: false');
|
|
||||||
t.equals(liner.next(), false, 'line 4: false');
|
|
||||||
t.equals(liner.fd, null, 'fd null');
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should get all lines even if the file doesnt end with new line', (t) => {
|
|
||||||
const liner = new lineByLine(path.resolve(__dirname, 'fixtures/badEndFile.txt'));
|
|
||||||
|
|
||||||
t.equals(liner.next().toString('ascii'), 'google.com', 'line 0: google.com');
|
|
||||||
t.equals(liner.next().toString('ascii'), 'yahoo.com', 'line 1: yahoo.com');
|
|
||||||
t.equals(liner.next(), false, 'line 3: false');
|
|
||||||
t.equals(liner.fd, null, 'fd is null');
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should get all lines if there is no new lines', (t) => {
|
|
||||||
const liner = new lineByLine(path.resolve(__dirname, 'fixtures/noNewLinesFile.txt'));
|
|
||||||
|
|
||||||
t.equals(liner.next().toString('ascii'), 'no new line', 'line 0: no new line');
|
|
||||||
t.equals(liner.next(), false, 'line 1: false');
|
|
||||||
t.equals(liner.fd, null, 'fd is null');
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should handle empty files', (t) => {
|
|
||||||
const liner = new lineByLine(path.resolve(__dirname, 'fixtures/emptyFile.txt'));
|
|
||||||
|
|
||||||
t.equals(liner.next(), false, 'line 0: false');
|
|
||||||
t.equals(liner.fd, null, 'line 0: false');
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should read right between two chunks', (t) => {
|
|
||||||
const liner = new lineByLine(path.resolve(__dirname, 'fixtures/normalFile.txt'), {
|
|
||||||
readChunk: 16
|
|
||||||
});
|
|
||||||
|
|
||||||
t.equals(liner.next().toString('ascii'), 'google.com', 'line 0: google.com');
|
|
||||||
t.equals(liner.next().toString('ascii'), 'yahoo.com', 'line 1: yahoo.com');
|
|
||||||
t.equals(liner.next().toString('ascii'), 'yandex.ru', 'line 2: yandex.ru');
|
|
||||||
t.equals(liner.next(), false, 'line 3: false');
|
|
||||||
t.equals(liner.fd, null, 'fs is null');
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should read empty lines', (t) => {
|
|
||||||
const liner = new lineByLine(path.resolve(__dirname, 'fixtures/withEmptyLines.txt'));
|
|
||||||
|
|
||||||
t.equals(liner.next().toString('ascii'), 'hello', 'line 0: hello');
|
|
||||||
t.equals(liner.next().toString('ascii'), 'hello4', 'line 1: hello4');
|
|
||||||
t.equals(liner.next().toString('ascii'), '', 'line 2: ');
|
|
||||||
t.equals(liner.next().toString('ascii'), 'hello2', 'line 3: hello2');
|
|
||||||
t.equals(liner.next().toString('ascii'), 'hello3', 'line 4: hello3');
|
|
||||||
t.equals(liner.next(), false, 'line 5: false');
|
|
||||||
t.equals(liner.fd, null, 'fs is null');
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should reset and start from the beggining', (t) => {
|
|
||||||
const liner = new lineByLine(path.resolve(__dirname, 'fixtures/normalFile.txt'), {
|
|
||||||
readChunk: 16
|
|
||||||
});
|
|
||||||
|
|
||||||
t.equals(liner.next().toString('ascii'), 'google.com', 'line 0: google.com');
|
|
||||||
t.equals(liner.next().toString('ascii'), 'yahoo.com', 'line 1: yahoo.com');
|
|
||||||
|
|
||||||
liner.reset()
|
|
||||||
|
|
||||||
t.equals(liner.next().toString('ascii'), 'google.com', 'line 0: google.com');
|
|
||||||
t.equals(liner.next().toString('ascii'), 'yahoo.com', 'line 1: yahoo.com');
|
|
||||||
t.equals(liner.next().toString('ascii'), 'yandex.ru', 'line 2: yandex.ru');
|
|
||||||
t.equals(liner.next(), false, 'line 3: false');
|
|
||||||
t.equals(liner.fd, null, 'fd is null');
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should read big lines', (t) => {
|
|
||||||
const liner = new lineByLine(path.resolve(__dirname, 'fixtures/bigLines.json'));
|
|
||||||
|
|
||||||
|
|
||||||
t.ok(JSON.parse(liner.next()), 'line 0: valid JSON');
|
|
||||||
t.ok(JSON.parse(liner.next()), 'line 1: valid JSON');
|
|
||||||
t.ok(JSON.parse(liner.next()), 'line 2: valid JSON');
|
|
||||||
|
|
||||||
t.equals(liner.next(), false, 'line 3: false');
|
|
||||||
t.equals(liner.fd, null, 'fd is null');
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Non-Latin Char JSON', (t) => {
|
|
||||||
const liner = new lineByLine(path.resolve(__dirname, 'fixtures/eiffel.geojson'));
|
|
||||||
|
|
||||||
t.ok(JSON.parse(liner.next().toString()), 'line 0: valid JSON');
|
|
||||||
|
|
||||||
t.equals(liner.fd, null, 'fd is null');
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Manually Close', (t) => {
|
|
||||||
const liner = new lineByLine(path.resolve(__dirname, 'fixtures/normalFile.txt'));
|
|
||||||
|
|
||||||
t.equals(liner.next().toString(), 'google.com', 'line 0: google.com');
|
|
||||||
|
|
||||||
liner.close();
|
|
||||||
t.equals(liner.fd, null, 'fd is null');
|
|
||||||
|
|
||||||
t.equals(liner.next(), false, 'line after close: false');
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should correctly processes NULL character in lines', (t) => {
|
|
||||||
const liner = new lineByLine(path.resolve(__dirname, 'fixtures/withNULL.txt'));
|
|
||||||
|
|
||||||
t.equals(liner.next().toString(), 'line without null', 'line 0: line without null');
|
|
||||||
t.equals(liner.next().toString(), 'line wi'+String.fromCharCode(0)+'th null', 'line 1: line with null');
|
|
||||||
t.equals(liner.next().toString(), 'another line without null', 'line 2: another line without null');
|
|
||||||
|
|
||||||
t.equals(liner.fd, null, 'fd is null');
|
|
||||||
t.end();
|
|
||||||
})
|
|
2264
package-lock.json
generated
2264
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -10,5 +10,8 @@
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"n-readlines": "^1.0.1"
|
"n-readlines": "^1.0.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"nodemon": "^2.0.6"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
38
start.js
38
start.js
|
@ -1,26 +1,36 @@
|
||||||
const trackNum = process.argv[2];
|
const trackNum = process.argv[2]
|
||||||
if (!trackNum) { console.error('Usage: node start <daynumber>'); process.exit(1); }
|
if (!trackNum) { console.error('Usage: node start <daynumber>'); process.exit(1) }
|
||||||
|
|
||||||
const satriani = require('./rockstar/satriani/satriani.js');
|
const satriani = require('./rockstar/satriani/satriani.js')
|
||||||
const fs = require('fs');
|
const path = require('path')
|
||||||
const lineByLine = require('n-readlines');
|
const fs = require('fs')
|
||||||
|
const lineByLine = require('n-readlines')
|
||||||
|
|
||||||
const rockstar = new satriani.Interpreter();
|
const rockstar = new satriani.Interpreter()
|
||||||
const program = fs.readFileSync(`lyrics/${trackNum}.rock`, {encoding:'utf8', flag:'r'});
|
const source = path.normalize(
|
||||||
const inputByLine = new lineByLine(`inputs/${trackNum}.txt`, {encoding:'utf8', flag:'r'});
|
`${
|
||||||
|
fs.existsSync(path.normalize(`lyrics/${trackNum}.rock`))
|
||||||
|
? 'lyrics'
|
||||||
|
: 'contracts'
|
||||||
|
}/${trackNum}.rock`)
|
||||||
|
const program = fs.readFileSync(source, { encoding: 'utf8', flag: 'r' })
|
||||||
|
const inputByLine = new lineByLine(
|
||||||
|
path.normalize(`music/${trackNum}.txt`),
|
||||||
|
{ encoding: 'utf8', flag: 'r' }
|
||||||
|
)
|
||||||
const getNextInputLineAscii = () => {
|
const getNextInputLineAscii = () => {
|
||||||
const next = inputByLine.next();
|
const next = inputByLine.next()
|
||||||
if (next === false) {
|
if (next === false) {
|
||||||
return null;
|
return null
|
||||||
} else {
|
} else {
|
||||||
return next.toString('ascii');
|
return next.toString('ascii')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const ast = rockstar.parse(program);
|
const ast = rockstar.parse(program)
|
||||||
// Draw the abstract syntax tree (AST) to the console as a JSON object
|
// Draw the abstract syntax tree (AST) to the console as a JSON object
|
||||||
//console.log(JSON.stringify(ast, null, 2))
|
// console.log(JSON.stringify(ast, null, 2))
|
||||||
|
|
||||||
const output = console.log
|
const output = console.log
|
||||||
const result = rockstar.run(ast, getNextInputLineAscii, output)
|
const result = rockstar.run(ast, getNextInputLineAscii, output)
|
||||||
if (result) console.log(result);
|
if (result) console.log(result)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue