diff --git a/js/applesoft/compiler.ts b/js/applesoft/compiler.ts index 63490d3..7757673 100644 --- a/js/applesoft/compiler.ts +++ b/js/applesoft/compiler.ts @@ -61,7 +61,7 @@ class LineBuffer implements IterableIterator { return new LineBuffer(this.line, this.curChar); } - next(): IteratorResult { + next(): IteratorResult { if (this.atEnd()) { return { done: true, value: undefined }; } @@ -74,10 +74,10 @@ class LineBuffer implements IterableIterator { * the token matches, the current buffer location is advanced passed * the token and this method returns `true`. Otherwise, this method * returns `false`. - * + * * The input is assumed to be an all-uppercase string and the tokens * in the buffer are uppercased before the comparison. - * + * * @param token An all-uppercase string to match. */ lookingAtToken(token: string): boolean { @@ -123,11 +123,9 @@ class LineBuffer implements IterableIterator { export default class ApplesoftCompiler { private lines: Map = new Map(); - constructor() { } - /** * Loads an AppleSoft BASIC program into memory. - * + * * @param mem Memory, including zero page, into which the program is * loaded. * @param program A string with a BASIC program to compile (tokenize). @@ -197,7 +195,7 @@ export default class ApplesoftCompiler { // Backup to before the token lineBuffer.backup(); // and emit the 'A' (upper- or lower-case) - return lineBuffer.next().value.charCodeAt(0); + return lineBuffer.next().value?.charCodeAt(0) ?? 0; } } return STRING_TO_TOKEN[possibleToken]; @@ -205,7 +203,7 @@ export default class ApplesoftCompiler { } // If not a token, output the character upper-cased - return lineBuffer.next().value.toUpperCase().charCodeAt(0); + return lineBuffer.next().value?.toUpperCase().charCodeAt(0) ?? 0; } private compileLine(line: string | null | undefined) { @@ -306,7 +304,7 @@ export default class ApplesoftCompiler { const lineNumbers = [...this.lines.keys()].sort(); for (const lineNo of lineNumbers) { - const lineBytes = this.lines.get(lineNo)!; + const lineBytes = this.lines.get(lineNo) || []; const nextLineAddr = programStart + result.length + 4 + lineBytes.length + 1; // +1 for the zero at end of line result.push(nextLineAddr & 0xff, nextLineAddr >> 8); diff --git a/js/applesoft/decompiler.ts b/js/applesoft/decompiler.ts index a1124c2..37260fb 100644 --- a/js/applesoft/decompiler.ts +++ b/js/applesoft/decompiler.ts @@ -30,7 +30,7 @@ export default class ApplesoftDecompiler { /** * Returns a decompiler for the program in the given memory. - * + * * The memory is assumed to have set `TXTTAB` and `PRGEND` correctly. */ static decompilerFromMemory(ram: Memory): ApplesoftDecompiler { @@ -50,9 +50,9 @@ export default class ApplesoftDecompiler { * assumed to be a dump of memory beginning at `base`. If the data * does not cover the whole program, attempting to decompile will * fail. - * + * * @param program The program bytes. - * @param base + * @param base */ constructor(private readonly program: ReadonlyUint8Array, private readonly base: word = 0x801) { @@ -66,8 +66,8 @@ export default class ApplesoftDecompiler { /** * Iterates through the lines of the given program in the order of * the linked list of lines, starting from the first line. This - * does _not_ mean that all lines in memory will - * + * does _not_ mean that all lines in memory will + * * @param from First line for which to call the callback. * @param to Last line for which to call the callback. * @param callback A function to call for each line. The first parameter @@ -79,12 +79,12 @@ export default class ApplesoftDecompiler { let offset = 0; let nextLineAddr = this.wordAt(offset); let nextLineNo = this.wordAt(offset + 2); - while (nextLineAddr != 0 && nextLineNo < from) { + while (nextLineAddr !== 0 && nextLineNo < from) { offset = nextLineAddr; nextLineAddr = this.wordAt(offset); nextLineNo = this.wordAt(offset + 2); } - while (nextLineAddr != 0 && nextLineNo <= to) { + while (nextLineAddr !== 0 && nextLineNo <= to) { callback(offset + 2); offset = nextLineAddr - this.base; nextLineAddr = this.wordAt(offset); @@ -105,14 +105,14 @@ export default class ApplesoftDecompiler { if (options.apple2 === 'e') { line += ' '; // D6F9: JSR SPCLIN } - line += lineNo + ' '; // D6FC, always 1 space after line number + line += `${lineNo} `; // D6FC, always 1 space after line number offset += 2; // In the original ROM, the line length is checked immediately // after the line number is printed. For simplicity, this method // always assumes that there is space for one token—which would // have been the case on a realy Apple. - while (this.program[offset] != 0) { + while (this.program[offset] !== 0) { const token = this.program[offset]; if (token >= 0x80 && token <= 0xea) { line += ' '; // D750, always put a space in front of token @@ -158,13 +158,13 @@ export default class ApplesoftDecompiler { /** * Lists the program in the same format that an Apple II prints to the * screen. - * + * * This method also accepts a starting and ending line number. Like on * an Apple II, this will print all of the lines between `from` and `to` * (inclusive) regardless of the actual line numbers between them. - * + * * To list a single line, pass the same number for both `from` and `to`. - * + * * @param options The options for formatting the output. * @param from The first line to print (default 0). * @param to The last line to print (default end of program). @@ -193,7 +193,7 @@ export default class ApplesoftDecompiler { spaceIf = (nextToken: string) => /^\d/.test(nextToken); offset += 2; - while (this.program[offset] != 0) { + while (this.program[offset] !== 0) { const token = this.program[offset]; let tokenString: string; if (token >= 0x80 && token <= 0xea) { @@ -235,10 +235,10 @@ export default class ApplesoftDecompiler { let spaceIf: (char: byte) => boolean = () => false; const lineNo = this.wordAt(offset); - result += lineNo + ' '; + result += `${lineNo} `; offset += 2; - while (this.program[offset] != 0) { + while (this.program[offset] !== 0) { const token = this.program[offset]; let tokenString: string; if (token >= 0x80 && token <= 0xea) { @@ -290,4 +290,4 @@ export default class ApplesoftDecompiler { }); return results.join('\n'); } -} \ No newline at end of file +}