Spaces:
Running
Running
File size: 5,823 Bytes
884b387 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | #!/usr/bin/env node
/* split-src.mjs β μν°ν©νΈλ₯Ό λ§μ»€ κΈ°μ€μΌλ‘ μλΌ <unit>.src/ ννΈ + manifest.txt λ₯Ό λ§λ λ€.
Usage: node tools/split-src.mjs engine|app|all
μ»·μ μ€λ²νΈκ° μλλΌ **νμΌ μμμ μ μΌν λ§μ»€ λ¬Έμμ΄**λ‘ μ‘κ³ , λ§μ»€κ° μλ μ€μ
머리(byte offset)μμ μλ₯Έλ€. λ§μ»€κ° 0νκ±°λ 2ν μ΄μμ΄λ©΄, λλ νμΌ μμλλ‘
μ¦κ°νμ§ μμΌλ©΄ νλ μ€ν¨νλ€ β μ‘°μ©ν μλ±ν λ°λ₯Ό μλ₯΄λ κ²λ³΄λ€ λ«λ€.
λ°μ΄νΈ 곡κ°μμλ§ λ€λ£¬λ€(Buffer.indexOf): νκΈ μ£Όμμ΄ λ§μ»€μ λ€μ΄μλ UTF-16
μ½λμ λ μ€νμ
κ³Ό λ°μ΄νΈ μ€νμ
μ΄ μ΄κΈλμ§ μκ². */
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const ROOT = path.join(path.dirname(fileURLToPath(import.meta.url)), '..');
const SPEC = {
engine: {
out: 'engine.js',
dir: 'engine.src',
head: '000-shared-engine-body.js',
cuts: [
['010-stones.js', '/* ============ STONES FIELD MODULE'],
['020-toll.js', '/* ============ TOLL FIELD MODULE'],
['030-downed.js', '/* ============ DOWNED FIELD MODULE'],
['040-log.js', '/* ============ LOG FIELD MODULE'],
['050-shared-removed-five.js', '/* ============ FIVE FIELD MODULES LEFT HERE'],
['060-statue.js', '/* ============ STATUE FIELD MODULE'],
['070-flood.js', '/* ============ FLOOD FIELD MODULE'],
['080-carry.js', '/* ============ CARRY FIELD MODULE'],
['090-ledge.js', '/* ============ LEDGE FIELD MODULE'],
['100-relay.js', '/* ============ RELAY FIELD MODULE'],
['110-fire.js', '/* ============ FIRE FIELD MODULE'],
['120-tower.js', '/* ============ TOWER FIELD MODULE'],
['130-bomb.js', '/* ============ BOMB FIELD MODULE'],
['140-shared-removed-bomb2.js', '/* ============ BOMB2 (y22) LEFT ON'],
['150-lantern.js', '/* ============ LANTERN FIELD MODULE'],
['160-yield.js', '/* ============ YIELD FIELD MODULE'],
['170-siege.js', '/* ============ SIEGE FIELD MODULE'],
['180-escape.js', '/* ============ ESCAPE FIELD MODULE'],
['190-alley.js', '/* ============ ALLEY FIELD MODULE'],
['200-beacon.js', '/* ============ BEACON FIELD MODULE'],
['210-burst.js', '/* ============ BURST FIELD MODULE'],
['220-shared-removed-shifter.js', '/* ============ SHIFTER (y54) LEFT ON'],
['230-road.js', '/* ============ ROAD FIELD MODULE'],
['240-plaza.js', '/* ============ PLAZA FIELD MODULE'],
['250-shared-exports-tail.js', '/* ================================ EXPORTS =========='],
],
},
app: {
out: 'app.js',
dir: 'app.src',
head: '000-shared-app-body.js',
cuts: [
['010-stones.js', '// y12 STONES FIELD LAYER'],
['020-toll.js', '// y14 TOLL FIELD LAYER'],
['030-downed.js', '// y3 DOWNED FIELD LAYER'],
['040-log.js', '// y8 ROLLING-LOG FIELD LAYER'],
['050-alley-bull.js', '// THE BULL FIELD LAYER'],
['060-statue.js', '// y29 STATUE FIELD LAYER'],
['070-relay.js', '// y31 RELAY FIELD LAYER'],
['080-flood.js', '// y10 RISING-WATER FIELD LAYER'],
['090-shared-post-registry.js', '// WHY A SECOND REGISTRY RATHER THAN A FLAG ON THE FIRST'],
['100-lantern.js', '// y24 LANTERN FIELD LAYER'],
['110-statue-live.js', '// y29 THE GLOW AND THE POST'],
['120-siege.js', '// ---- y46 v2 THE FOUR SEATS'],
['130-alley.js', '// y50 ALLEY FIELD LAYER'],
['140-escape.js', '// ---- y51 ESCAPE: the two glyph primitives'],
['150-beacon.js', '/* y53 BEACON FIELD LAYER'],
['160-burst.js', '/* y52 BURST FIELD LAYER'],
['170-shared-removed-shifter.js', '/* y54 SHIFTER FIELD LAYER'],
['180-carry.js', '// y16 CARRY FIELD LAYER'],
['190-ledge.js', '// y26 LEDGE FIELD LAYER'],
['200-fire.js', '// y17 FIRE FIELD LAYER'],
['210-tower.js', '// y19 TOWER FIELD LAYER'],
['220-bomb.js', '// y20 BOMB FIELD LAYER'],
['230-flood-storm.js', '// y23 STORM FIELD LAYER'],
['240-yield.js', '// y33 YIELD FIELD LAYER'],
['250-road.js', '/* y58 νλ₯΄λ λλ‘ FIELD LAYER'],
['260-plaza.js', '/* y59 PLAZA FIELD LAYER'],
['270-shared-app-tail.js', '// P13 PUSH VERB LAYER'],
],
},
};
function split(key) {
const unit = SPEC[key];
const src = fs.readFileSync(path.join(ROOT, unit.out));
const bounds = [];
let prev = 0;
for (const [name, marker] of unit.cuts) {
const m = Buffer.from(marker, 'utf8');
const i = src.indexOf(m);
if (i < 0) throw new Error(`[${key}] λ§μ»€λ₯Ό μ°Ύμ μ μμ΅λλ€: ${marker}`);
if (i !== src.lastIndexOf(m)) throw new Error(`[${key}] λ§μ»€κ° μ μΌνμ§ μμ΅λλ€: ${marker}`);
const start = src.lastIndexOf(0x0a, i) + 1; // μ€ λ¨Έλ¦¬μμ μλ₯Έλ€
if (start <= prev) throw new Error(`[${key}] λ§μ»€ μμκ° νμΌ μμμ μ΄κΈλ©λλ€: ${marker}`);
bounds.push([name, start]);
prev = start;
}
const dir = path.join(ROOT, unit.dir);
fs.mkdirSync(dir, { recursive: true });
const names = [unit.head, ...bounds.map(([n]) => n)];
const offs = [0, ...bounds.map(([, s]) => s), src.length];
for (let k = 0; k < names.length; k++) {
fs.writeFileSync(path.join(dir, names[k]), src.subarray(offs[k], offs[k + 1]));
}
fs.writeFileSync(path.join(dir, 'manifest.txt'), names.join('\n') + '\n');
const total = names.reduce((a, n) => a + fs.statSync(path.join(dir, n)).size, 0);
console.log(`${unit.dir}: ${names.length} parts, ${total} bytes (artifact ${src.length} bytes)`);
if (total !== src.length) throw new Error(`[${key}] ννΈ ν©κ³κ° μν°ν©νΈμ λ€λ¦
λλ€`);
}
const arg = process.argv[2] || 'all';
for (const key of arg === 'all' ? Object.keys(SPEC) : [arg]) split(key);
|