aboutsummaryrefslogtreecommitdiff
path: root/src/js/mklayout.js
blob: 8e41f41defda59b6fa3f28bf3d89d0eabc1fd76e (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
// writes the javascript vm's view of a memory map: the map's constants as
// typescript and commonjs modules. the vm reads its genome image itself, from
// genome.bin beside tinyvm.js, so only the layout is generated here. everything
// it writes is generated, so it goes to build/js/ and nothing is left in the tree.
//
//   node src/js/mklayout.js [--map PATH] [--out DIR]
//
// the map is the default one `make` generates in build/core/map/memmap.h.
// outputs, in the out directory:
//   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/mklayout.js [--map PATH] [--out DIR]',
        'converts a memory map header into the javascript vm layout files.',
        'options:',
        '  --map PATH      the memory map header to read; defaults to build/core/map/memmap.h',
        '  --out DIR       where to write; defaults to build/js',
        '  --help, -h      show this help and exit',
    ].join('\n'));
    process.exit(0);
}
for (let i = 0; i < args.length; i += 2) {
    if (!['--map', '--out'].includes(args[i]) || args[i + 1] === undefined) {
        console.error('mklayout: unexpected arguments: ' + args.join(' ') + '; use --help for usage');
        process.exit(2);
    }
}

const mapPath = opt('--map') || path.join(root, 'build', 'core', 'map', 'memmap.h');
const outDir = opt('--out') || path.join(root, 'build', 'js');
if (!fs.existsSync(mapPath) || !fs.statSync(mapPath).isFile()) {
    console.error('mklayout: no memory map header at ' + mapPath + '; run `make` first');
    process.exit(1);
}
fs.mkdirSync(outDir, { recursive: true });

// the compiler's map, as constants: the js vm reads them instead of its own copies.
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);

const lines = names.map(k => `    ${k}: ${map[k]},`).join('\n');
const layoutTs = path.join(outDir, 'layout.ts');
fs.writeFileSync(layoutTs,
    '// generated by src/js/mklayout.js from ' + path.relative(root, mapPath) + '. do not edit.\n' +
    'export const MAP = {\n' + lines + '\n} as const;\n');
const layoutJs = path.join(outDir, 'layout.js');
fs.writeFileSync(layoutJs,
    '// generated by src/js/mklayout.js from ' + path.relative(root, mapPath) + '. do not edit.\n' +
    'exports.MAP = ' + JSON.stringify(map, null, 4) + ';\n');
console.log('wrote ' + path.relative(root, layoutJs) + ' and layout.ts');