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