aboutsummaryrefslogtreecommitdiff
path: root/src/js/extract_genome.js
blob: 4ef2c431e7facc7df7aea4644f3d755852328f69 (plain) (blame)
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
// 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');
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 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(genomePath, 'utf8');
const gorgMatch = text.match(/#define\s+GORG\s+(\d+)/);
const glenMatch = text.match(/#define\s+GLEN\s+(\d+)/);

const gorg = parseInt(gorgMatch[1], 10);
const glen = parseInt(glenMatch[1], 10);

const arrMatch = text.match(/genome\[\]\s*=\s*\{([\s\S]*?)\};/);
if (!arrMatch) {
    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);

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, 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(mapPath, names);
if (map.GORG !== gorg) throw new Error('genome GORG ' + gorg + ' is not the map GORG ' + map.GORG);

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');
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 ' + 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);