From 28b92b49807797797776bada9eb41cfb6cc25559 Mon Sep 17 00:00:00 2001 From: n loewen Date: Tue, 29 Aug 2023 11:51:53 -0400 Subject: [PATCH] assembler - Replace debugging with new debugging library --- src/assembler.js | 116 +++++++++++++++++++++++------------------------ 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/src/assembler.js b/src/assembler.js index c55a0fd..2e7cb1c 100644 --- a/src/assembler.js +++ b/src/assembler.js @@ -1,22 +1,10 @@ +const fs = require('fs'); + const { logMemory, num2hex } = require('./logging.js'); +const DBG = require('./dbg.js'); + const CFG = require('./machine.config.js'); -// 1 = verbose -// 2 = what i'm currently focusing on -// 3 = always print -// 4 = silent -const DEBUG_LEVEL = 2; -let DEBUG; // Turn debugging on/off -- set by assemble() - -/** - * @param {string} assemblyCode - * @param {Boolean} [debug = false] - **/ -exports.assemble = (assemblyCode, debug = false) => { - DEBUG = debug; - return decodeInstructions(assemblyCode); -} - // Configure pseudo-ops: const ASM_IP_LABEL = '*'; const ASM_CONSTANT_PREFIX = '#'; @@ -36,7 +24,6 @@ const mnemonics2opcodes = { nop: { direct: 15, indirect: 15 }, }; - /** * @typedef {('code'|'comment'|'blank')} SourceLineType **/ @@ -73,15 +60,15 @@ function preparseSourceCode(source) { } return lines.map((line, index) => { - dbg(1, ` in: ${line}`); + dbg.nit(` in: ${line}`); let info = { number: index + 1, source: line, sanitized: stripWhitespaceFromEnds(stripComments(line)), type: getLineType(line), }; - dbg(1, ` → ${info.number} - ${info.type}: ${info.sanitized}`); - dbg(1, ``); + dbg.nit(` → ${info.number} - ${info.type}: ${info.sanitized}`); + dbg.nit(``); if (info.type === 'code') { const op_arg_array = info.sanitized.split(/\s+/); // split line into an array of [op, arg, extra_arg] @@ -142,10 +129,10 @@ function handleLabelDefinition(op, IP, labels) { bytesToReplace: [], }; } - dbg(1, ` Label definition:`); - dbg(1, ` Points to byte: ${labels[label].pointsToByte}`); - dbg(1, ` Bytes to replace: ${labels[label].bytesToReplace}`); - dbg(1, ` IP: $${num2hex(IP)}, new code: none`); + dbg.nit(` Label definition:`); + dbg.nit(` Points to byte: ${labels[label].pointsToByte}`); + dbg.nit(` Bytes to replace: ${labels[label].bytesToReplace}`); + dbg.nit(` IP: $${num2hex(IP)}, new code: none`); dbgGroupEnd(1, 'Input line'); return labels; } @@ -163,10 +150,10 @@ function handleConstantDefinitions(op, arg, IP, constants) { constantValue = IP.toString(); } constants[constantName] = constantValue; - dbg(1, ''); - dbg(1, `Constants:`); - dbg(1, constants); - dbg(1, ''); + dbg.nit(''); + dbg.nit(`Constants:`); + dbg.nit(constants); + dbg.nit(''); return constants; } @@ -181,12 +168,12 @@ function handleConstantDefinitions(op, arg, IP, constants) { * @return {{ debugInfo: Object, machineCode: Uint8Array }}; **/ function decodeInstructions(source) { - dbg(1, 'Pre-parsing...'); + dbg.nit('Pre-parsing...'); let lines = preparseSourceCode(source); - dbg(1, ''); - dbg(1, 'Done pre-parsing.'); - dbg(1, ''); - dbg(1, 'Assembling...'); + dbg.nit(''); + dbg.nit('Done pre-parsing.'); + dbg.nit(''); + dbg.nit('Assembling...'); // Figure out where to start assembly... @@ -283,23 +270,23 @@ function decodeInstructions(source) { if (line.argument.startsWith(ASM_LABEL_PREFIX)) { let label = line.argument.substring(1); // strip label prefix if (label in labels) { - dbg(1, `'${label}' already in labels object`); + dbg.nit(`'${label}' already in labels object`); labels[label].bytesToReplace.push(IP + 1); } else { - dbg(1, `'${label}' NOT in labels object`); + dbg.nit(`'${label}' NOT in labels object`); labels[label] = { bytesToReplace: [IP + 1], }; } - dbg(1, `Label reference:`); - dbg(1, ` Points to byte: ${labels[label].pointsToByte}`); - dbg(1, ` Bytes to replace: ${labels[label].bytesToReplace}`); + dbg.nit(`Label reference:`); + dbg.nit(` Points to byte: ${labels[label].pointsToByte}`); + dbg.nit(` Bytes to replace: ${labels[label].bytesToReplace}`); decodedArg = 0; // Return 0 for operand for now -- we'll replace it later } // Operands - Handle references to the Instruction Pointer if (line.argument === ASM_IP_LABEL) { - dbg(1, ` References current IP - ${IP}`); + dbg.nit(` References current IP - ${IP}`); if (typeof line.extraArgument === 'undefined') { decodedArg = IP; } else { @@ -309,7 +296,7 @@ function decodeInstructions(source) { // Operands - Handle references to constants if (line.argument.startsWith(ASM_CONSTANT_PREFIX)) { - dbg(1, `References '${line.argument}'`); + dbg.nit(`References '${line.argument}'`); if (typeof constants[line.argument.substring(1)] === 'undefined') { console.error(); console.error(`Error: Undefined constant '${line.argument}'`); @@ -322,7 +309,7 @@ function decodeInstructions(source) { // Operands - Handle references to constants in indirect mode if (line.argument.startsWith(`(${ASM_CONSTANT_PREFIX}`)) { addressingMode = "indirect"; - dbg(1, `(Indirectly) References '${line.argument}'`); + dbg.nit(`(Indirectly) References '${line.argument}'`); let constName = line.argument.replace(`(${ASM_CONSTANT_PREFIX}`, ""); constName = constName.replace(")", ""); decodedArg = decodeNumericOp(constants[constName]); @@ -356,31 +343,31 @@ function decodeInstructions(source) { }; - dbg(3, ``); - dbg(3, `Line ${line.number}: ${line.source}`); + dbg.i(); + dbg.i(`Line ${line.number}: ${line.source}`); if (line.argument) { - dbg(3, ` Asm operation: ${line.operation.toUpperCase()} ${line.argument}`); + dbg.i(` Asm operation: ${line.operation.toUpperCase()} ${line.argument}`); } else if (line.operation) { - dbg(3, ` Asm operation: ${line.operation.toUpperCase()}`); + dbg.i(` Asm operation: ${line.operation.toUpperCase()}`); } - dbg(3, ` Machine code: $${num2hex(decodedOp)} $${num2hex(decodedArg)}`); - dbg(3, ` IP: $${num2hex(IP)}`); + dbg.i(` Machine code: $${num2hex(decodedOp)} $${num2hex(decodedArg)}`); + dbg.i(` IP: $${num2hex(IP)}`); IP += 2; }; } - dbg(1, ''); - dbgGroup(1, 'Memory before filling in label constants'); - dbgExec(1, () => logMemory(new Uint8Array(machineCode))); - dbgGroupEnd(1); + dbg.nit(''); + dbg.nitGroup('Memory before filling in label constants'); + dbg.nitExec(() => logMemory(new Uint8Array(machineCode))); + dbg.nitGroupEnd(); // Backfill label references for (let k of Object.keys(labels)) { dbgGroup(1, `${ASM_LABEL_PREFIX}${k}`); let label = labels[k]; - dbg(1, `Points to byte: ${label.pointsToByte}`); - dbg(1, `Bytes to replace: ${label.bytesToReplace}`); + dbg.nit(`Points to byte: ${label.pointsToByte}`); + dbg.nit(`Bytes to replace: ${label.bytesToReplace}`); dbgGroupEnd(1); for (let j = 0; j < label.bytesToReplace.length; j++) { machineCode[label.bytesToReplace[j]] = label.pointsToByte; @@ -411,8 +398,21 @@ function stripWhitespaceFromEnds(line) { function hex2num(hex) { return parseInt(hex, 16) }; -// Debug helpers -const dbg = (lvl, s) => { if (DEBUG && (lvl >= DEBUG_LEVEL)) console.log(s) }; -const dbgGroup = (lvl, s) => { if (DEBUG && (lvl >= DEBUG_LEVEL)) console.group(s) }; -const dbgGroupEnd = (lvl, s) => { if (DEBUG && (lvl >= DEBUG_LEVEL)) console.groupEnd() }; -const dbgExec = (lvl, func) => { if (DEBUG && (lvl >= DEBUG_LEVEL)) func(); } \ No newline at end of file + +/** MAIN **/ + +// Initialize debugger +const dbg = new DBG('nitpick'); + +// Get input +const filename = process.argv[2]; // FIXME +const inputFile_str = fs.readFileSync(filename, 'utf8'); +assemble(inputFile_str); + + +/** + * @param {string} assemblyCode + **/ +function assemble(assemblyCode) { + return decodeInstructions(assemblyCode); +} \ No newline at end of file