assembler - Change to a tidier approach, made possible by new Opter library

This commit is contained in:
n loewen 2023-09-02 20:55:45 -07:00
parent 101421c4c3
commit 77a41d47c3
1 changed files with 31 additions and 24 deletions

View File

@ -175,6 +175,7 @@ function handleConstantDefinitions(op, arg, IP, constants) {
* @param {string} source - Assembly source to decode
* @return {{ sourceInfo: Object, machineCode: Array }};
**/
// TODO rename?
function decodeInstructions(source) {
dbg.nit('Pre-parsing...');
let lines = preparseSourceCode(source);
@ -212,8 +213,8 @@ function decodeInstructions(source) {
let labels = {};
let constants = {};
// Decode line by line...
for (let i = 0; i < lines.length; i++) {
let line = lines[i];
// dbg(2, `line info:`);
@ -239,7 +240,6 @@ function decodeInstructions(source) {
}
}
// *** Decode special operations ***
// Opcodes - Handle label definitions
@ -350,7 +350,6 @@ function decodeInstructions(source) {
machine: [decodedOp, decodedArg]
};
dbg.i();
dbg.i(`Line ${line.number}: ${line.source}`);
if (line.argument) {
@ -409,27 +408,37 @@ function stripWhitespaceFromEnds(line) {
* If 'includeMetadata' is true, a JSON object containing
* both machine code and metadata is written to the output file.
* Otherwise, a string of decimal numbers is written.
* @arg {string} sourceCode - Source code to assemble
* @arg {string} [outputFile] - Output file for machine code (and optional metadata)
* @arg {boolean} [includeMetadata=false] - Include metadata when writing output to a file? (for use when debugging using the simulator)
* @arg {string} inputFilename File containing code to assemble
* @arg {boolean} outputToFile If false, output is on stdout
* @arg {boolean} includeMetadata Include metadata when writing output to a file? (for use when debugging using the simulator)
* @arg {string} [outputFilename] Output file for machine code (and optional metadata)
**/
function assemble(sourceCode, outputFile='out.txt', includeMetadata=false) {
function assemble(inputFilename, outputToFile, includeMetadata, outputFilename=null) {
const sourceCode = fs.readFileSync(inputFilename, 'utf8');
const out = decodeInstructions(sourceCode);
if (returnOnStdout) {
if (includeMetadata) {
const debugJSON = JSON.stringify(out);
console.log(debugJSON);
} else if (!includeMetadata) {
const asciiMachineCode = out.machineCode.toString().replace(/,/g, ' ');
fs.writeFileSync(outputFile, asciiMachineCode);
if (outputToFile) {
fs.writeFileSync(outputFilename, debugJSON);
} else {
console.log(debugJSON);
}
} else {
const debugJSON = JSON.stringify(out);
fs.writeFileSync(outputFile, debugJSON);
const asciiMachineCode = out.machineCode.toString().replace(/,/g, ' ');
if (outputToFile) {
fs.writeFileSync(outputFilename, asciiMachineCode);
} else {
console.log(asciiMachineCode);
}
}
}
/** MAIN **/
// Initialize debugger...
const dbg = new DBG('nitpick');
// Handle command-line options...
const opts = new Opter(process.argv);
opts.synonymize('-d', '--debug');
@ -438,16 +447,14 @@ opts.requireOptionArgument('-i', 1, 1, 'Input file required (-i prog.asm)');
opts.requireOptionArgument('-o', 1, 1, 'Missing output file name (-o prog.asm)');
const inputFilename = opts.opts.i[0];
const inputFile_str = fs.readFileSync(inputFilename, 'utf8');
let outputFileProvided = opts.contains('-o');
let returnOnStdout = !outputFileProvided;
let outputFilename = outputFileProvided ? opts.opts.o[0] : null;
const outputToFile = opts.contains('-o');
let outputWithMetadata = opts.contains('--debug');
// Initialize debugger...
const dbg = returnOnStdout ? new DBG('none') : new DBG('nitpick');
// Assemble...!
assemble(inputFile_str, outputFilename, outputWithMetadata);
if (outputToFile) {
const outputFilename = opts.opts.o[0];
assemble(inputFilename, outputToFile, outputWithMetadata, outputFilename);
} else {
dbg.setLevel('none');
assemble(inputFilename, outputToFile, outputWithMetadata);
}