aboutsummaryrefslogtreecommitdiff
path: root/src/js/extract_genome.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/js/extract_genome.js')
-rw-r--r--src/js/extract_genome.js84
1 files changed, 62 insertions, 22 deletions
diff --git a/src/js/extract_genome.js b/src/js/extract_genome.js
index 89bebe3..4ef2c43 100644
--- a/src/js/extract_genome.js
+++ b/src/js/extract_genome.js
@@ -1,18 +1,52 @@
+// converts the compiler genome and the memory map into the javascript vm's
+// layout files. everything it writes is generated, so it goes to build/js/ and
+// nothing is left in the tree.
+//
+// node src/js/extract_genome.js [--genome PATH] [--map PATH] [--out DIR]
+//
+// the genome is the one make genome produced in build/core/genome.h, and the
+// map is src/core/memmap.h. outputs, in the out directory:
+// genome.json the genome words, for the vm that has no compiler inside it
+// layout.ts the map as typescript constants
+// layout.js the map as commonjs constants
const fs = require('fs');
const path = require('path');
-if (process.argv.length > 2) {
- if (process.argv.length === 3 && ['--help', '-h'].includes(process.argv[2])) {
- console.log('usage: node src/js/extract_genome.js [--help|-h]\nconverts src/core/genome.h and memmap.h into the javascript genome and layout files.');
- process.exit(0);
- }
- console.error('extract_genome: unexpected arguments; use --help for usage');
+const root = path.join(__dirname, '..', '..');
+
+const args = process.argv.slice(2);
+const opt = (name) => {
+ const i = args.indexOf(name);
+ return i >= 0 && args[i + 1] ? args[i + 1] : null;
+};
+if (args.includes('--help') || args.includes('-h')) {
+ console.log([
+ 'usage: node src/js/extract_genome.js [--genome PATH] [--map PATH] [--out DIR]',
+ 'converts the compiler genome and memory map into the javascript layout files.',
+ 'options:',
+ ' --genome PATH the genome header to read; defaults to build/core/genome.h',
+ ' --map PATH the memory map header to read; defaults to src/core/memmap.h',
+ ' --out DIR where to write; defaults to build/js',
+ ' --help, -h show this help and exit',
+ ].join('\n'));
+ process.exit(0);
+}
+const unknown = args.filter((a) => !['--genome', '--map', '--out'].includes(a));
+if (unknown.length) {
+ console.error('extract_genome: unexpected arguments: ' + unknown.join(' ') + '; use --help for usage');
process.exit(2);
}
-const srcPath = path.join(__dirname, '..', 'core', 'genome.h');
-const outPath = path.join(__dirname, 'genome.json');
+const genomePath = opt('--genome') || path.join(root, 'build', 'core', 'genome.h');
+const mapPath = opt('--map') || path.join(__dirname, '..', 'core', 'memmap.h');
+const outDir = opt('--out') || path.join(root, 'build', 'js');
+
+if (!fs.existsSync(genomePath)) {
+ console.error('extract_genome: no genome at ' + genomePath + '; run `make genome` first');
+ process.exit(1);
+}
+fs.mkdirSync(outDir, { recursive: true });
-const text = fs.readFileSync(srcPath, 'utf8');
+const text = fs.readFileSync(genomePath, 'utf8');
const gorgMatch = text.match(/#define\s+GORG\s+(\d+)/);
const glenMatch = text.match(/#define\s+GLEN\s+(\d+)/);
@@ -21,33 +55,39 @@ const glen = parseInt(glenMatch[1], 10);
const arrMatch = text.match(/genome\[\]\s*=\s*\{([\s\S]*?)\};/);
if (!arrMatch) {
- console.error('Could not find genome array in genome.h');
+ console.error('extract_genome: could not find the genome array in ' + genomePath);
process.exit(1);
}
const words = arrMatch[1]
.split(',')
.map(s => s.trim())
- .filter(s => s.length > 0)
- .map(s => s); // keep as string numbers
+ .filter(s => s.length > 0);
console.log(`Parsed genome: GORG=${gorg}, GLEN=${words.length}`);
if (words.length !== glen) throw new Error('genome length does not match GLEN');
-// the compiler's map, from src/core/memmap.h, as typescript constants: the js vm reads
-// them instead of its own copies. the values are computed here, from the map.
+// the compiler's map, as typescript constants: the js vm reads them instead of
+// its own copies. the values are computed here, from the map.
const { mapValues } = require('./mapvalues.js');
const names = ['MW', 'PW', 'ZFP', 'GORG', 'DS0', 'DSLIM', 'RS0', 'RSLIM', 'SYSGATE', 'HEAP_LO', 'HEAP_HI'];
-const map = mapValues(path.join(__dirname, '..', 'core', 'memmap.h'), names);
+const map = mapValues(mapPath, names);
if (map.GORG !== gorg) throw new Error('genome GORG ' + gorg + ' is not the map GORG ' + map.GORG);
-fs.writeFileSync(outPath, JSON.stringify({ gorg, glen, words }));
-console.log(`saved genome to ${outPath}`);
+
+const genomeJson = path.join(outDir, 'genome.json');
+fs.writeFileSync(genomeJson, JSON.stringify({ gorg, glen, words }));
+console.log('saved genome to ' + genomeJson);
+
const lines = names.map(k => ` ${k}: ${map[k]},`).join('\n');
-fs.writeFileSync(path.join(__dirname, 'layout.ts'),
- '// generated by src/js/extract_genome.js from src/core/memmap.h. do not edit.\n' +
+const layoutTs = path.join(outDir, 'layout.ts');
+fs.writeFileSync(layoutTs,
+ '// generated by src/js/extract_genome.js from ' + path.relative(root, mapPath) + '. do not edit.\n' +
'export const MAP = {\n' + lines + '\n} as const;\n');
-console.log(`Saved the map to ${path.join(__dirname, 'layout.ts')}`);
-fs.writeFileSync(path.join(__dirname, 'layout.js'),
- '// generated by src/js/extract_genome.js from src/core/memmap.h. do not edit.\n' +
+console.log('saved the map to ' + layoutTs);
+
+const layoutJs = path.join(outDir, 'layout.js');
+fs.writeFileSync(layoutJs,
+ '// generated by src/js/extract_genome.js from ' + path.relative(root, mapPath) + '. do not edit.\n' +
'exports.MAP = ' + JSON.stringify(map, null, 4) + ';\n');
+console.log('saved the map to ' + layoutJs); \ No newline at end of file