js-slang
Version:
Javascript-based implementations of Source, written in Typescript
87 lines • 3.76 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.getSVMCCommand = exports.compileToChoices = void 0;
const extra_typings_1 = require("@commander-js/extra-typings");
const createContext_1 = require("../createContext");
const parser_1 = require("../parser/parser");
const types_1 = require("../types");
const formatters_1 = require("../utils/formatters");
const __1 = require("..");
const svml_assembler_1 = require("../vm/svml-assembler");
const svml_compiler_1 = require("../vm/svml-compiler");
const util_1 = require("../vm/util");
const utils_1 = require("./utils");
exports.compileToChoices = ['ast', 'binary', 'debug', 'json'];
const getSVMCCommand = () => new extra_typings_1.Command('svmc')
.argument('<inputFile>', 'File to read code from')
.addOption((0, utils_1.getChapterOption)(types_1.Chapter.SOURCE_3, utils_1.chapterParser))
.addOption(new extra_typings_1.Option('-t, --compileTo <compileOption>', (0, formatters_1.stripIndent) `
json: Compile only, but don't assemble.
binary: Compile and assemble.
debug: Compile and pretty-print the compiler output. For debugging the compiler.
ast: Parse and pretty-print the AST. For debugging the parser.`)
.choices(exports.compileToChoices)
.default('binary'))
.option('-o, --out <outFile>', (0, formatters_1.stripIndent) `
Sets the output filename.
Defaults to the input filename, minus any file extension, plus '.svm'.
`)
.addOption(new extra_typings_1.Option('-i, --internals <names>', `Sets the list of VM-internal functions. The argument should be a JSON array of
strings containing the names of the VM-internal functions.`)
.argParser(value => {
const parsed = JSON.parse(value);
if (!Array.isArray(parsed)) {
throw new extra_typings_1.InvalidArgumentError('Expected a JSON array of strings!');
}
for (const each of parsed) {
if (typeof each !== 'string') {
throw new extra_typings_1.InvalidArgumentError('Expected a JSON array of strings!');
}
}
return parsed;
})
.default([]))
.action(async (inputFile, opts) => {
const fs = require('fs/promises');
const vmInternalFunctions = opts.internals || [];
const source = await fs.readFile(inputFile, 'utf-8');
const context = (0, createContext_1.createEmptyContext)(opts.chapter, types_1.Variant.DEFAULT, undefined, [], null);
const program = (0, parser_1.parse)(source, context);
if (program === null) {
process.stderr.write((0, __1.parseError)(context.errors));
process.exit(1);
}
let output;
let ext;
if (opts.compileTo === 'ast') {
output = JSON.stringify(program, undefined, 2);
ext = '.json';
}
else {
const compiled = (0, svml_compiler_1.compileToIns)(program, undefined, vmInternalFunctions);
switch (opts.compileTo) {
case 'debug': {
output = (0, util_1.stringifyProgram)(compiled).trimEnd();
ext = '.svm';
break;
}
case 'json': {
output = JSON.stringify(compiled);
ext = '.json';
break;
}
case 'binary': {
output = (0, svml_assembler_1.assemble)(compiled);
ext = '.svm';
break;
}
}
}
const { extname, basename } = require('path');
const extToRemove = extname(inputFile);
const outputFileName = opts.out ?? `${basename(inputFile, extToRemove)}${ext}`;
await fs.writeFile(outputFileName, output);
console.log(`Output written to ${outputFileName}`);
});
exports.getSVMCCommand = getSVMCCommand;
//# sourceMappingURL=svmc.js.map
;