From a38b64e1a1bf14dd9c42629f219b0e422aebe52a Mon Sep 17 00:00:00 2001 From: Jan Tuomi Date: Tue, 11 Apr 2023 17:30:08 +0300 Subject: Add hover and go to definition to extension --- asm/ext_std.py | 97 ++++++++++ asm/fibo.atk16 | 13 +- asm/ram_offset.atk16 | 2 + atk16-syntax-highlighting/README.md | 9 - .../atk16-syntax-highlighting-0.0.1.vsix | Bin 2321 -> 0 bytes .../language-configuration.json | 41 ----- atk16-syntax-highlighting/package.json | 28 --- .../syntaxes/atk16.tmLanguage.json | 48 ----- atk16-syntax/README.md | 9 + atk16-syntax/atk16-syntax-0.0.1.vsix | Bin 0 -> 4725 bytes atk16-syntax/extension.js | 197 +++++++++++++++++++++ atk16-syntax/language-configuration.json | 41 +++++ atk16-syntax/package.json | 39 ++++ atk16-syntax/syntaxes/atk16.tmLanguage.json | 52 ++++++ atk16-syntax/themes/atk16-color-theme.json | 41 +++++ src/asm_pass0.py | 48 +++++ src/asm_pass1.py | 13 +- src/asm_pass2.py | 2 + src/asm_pass3.py | 2 + src/asm_pass4.py | 5 +- src/assembler.py | 4 +- src/ext_std.py | 97 ---------- 22 files changed, 549 insertions(+), 239 deletions(-) create mode 100644 asm/ext_std.py create mode 100644 asm/ram_offset.atk16 delete mode 100644 atk16-syntax-highlighting/README.md delete mode 100644 atk16-syntax-highlighting/atk16-syntax-highlighting-0.0.1.vsix delete mode 100644 atk16-syntax-highlighting/language-configuration.json delete mode 100644 atk16-syntax-highlighting/package.json delete mode 100644 atk16-syntax-highlighting/syntaxes/atk16.tmLanguage.json create mode 100644 atk16-syntax/README.md create mode 100644 atk16-syntax/atk16-syntax-0.0.1.vsix create mode 100644 atk16-syntax/extension.js create mode 100644 atk16-syntax/language-configuration.json create mode 100644 atk16-syntax/package.json create mode 100644 atk16-syntax/syntaxes/atk16.tmLanguage.json create mode 100644 atk16-syntax/themes/atk16-color-theme.json create mode 100644 src/asm_pass0.py delete mode 100644 src/ext_std.py diff --git a/asm/ext_std.py b/asm/ext_std.py new file mode 100644 index 0000000..11da8aa --- /dev/null +++ b/asm/ext_std.py @@ -0,0 +1,97 @@ +from asm_ops import * + +def expand_add(left: str, right: str, target: str) -> ExpandResult: + return [["alr", "al_plus", left, right, target]] + +def expand_sub(left: str, right: str, target: str) -> ExpandResult: + return [["alr", "al_minus", left, right, target]] + +def expand_addi(left: str, imm: str, target: str) -> ExpandResult: + return [["ali", "al_plus", left, imm, target]] + +def expand_subi(left: str, imm: str, target: str) -> ExpandResult: + return [["ali", "al_minus", left, imm, target]] + +def expand_and(left: str, right: str, target: str) -> ExpandResult: + return [["alr", "al_and", left, right, target]] + +def expand_or(left: str, right: str, target: str) -> ExpandResult: + return [["alr", "al_or", left, right, target]] + +def expand_xor(left: str, right: str, target: str) -> ExpandResult: + return [["alr", "al_xor", left, right, target]] + +def expand_sll(left: str, right: str, target: str) -> ExpandResult: + return [["alr", "al_sll", left, right, target]] + +def expand_slr(left: str, right: str, target: str) -> ExpandResult: + return [["alr", "al_slr", left, right, target]] + +def expand_sar(left: str, right: str, target: str) -> ExpandResult: + return [["alr", "al_sar", left, right, target]] + +def expand_slli(left: str, imm: str, target: str) -> ExpandResult: + return [["ali", "al_sll", left, imm, target]] + +def expand_slri(left: str, imm: str, target: str) -> ExpandResult: + return [["ali", "al_slr", left, imm, target]] + +def expand_sari(left: str, imm: str, target: str) -> ExpandResult: + return [["ali", "al_sar", left, imm, target]] + +def expand_inc(reg: str) -> ExpandResult: + return [["ali", "al_plus", reg, "1", reg]] + +def expand_dec(reg: str) -> ExpandResult: + return [["ali", "al_minus", reg, "1", reg]] + +def expand_mov(from_reg: str, to_reg: str) -> ExpandResult: + return [["ali", "al_plus", from_reg, "0", to_reg]] + +def expand_spu(reg: str) -> ExpandResult: + return [["str", reg, "__STACK_POINTER"]] + expand_inc("__STACK_POINTER") + +def expand_spo(reg: str): + return expand_dec("__STACK_POINTER") + [["ldr", "__STACK_POINTER", reg]] + +def expand_csr(addr_reg: str): + return [ + ["lpc", "__CSR_SCRATCH"], + *expand_addi("__CSR_SCRATCH", "4", "__CSR_SCRATCH"), + *expand_spu("__CSR_SCRATCH"), + ["jpr", addr_reg] + ] + +def expand_csi(addr_imm: str): + return [ + ["lpc", "__CSR_SCRATCH"], + *expand_addi("__CSR_SCRATCH", "4", "__CSR_SCRATCH"), + *expand_spu("__CSR_SCRATCH"), + ["jpi", addr_imm] + ] +def expand_rsr(): + return expand_spo("__CSR_SCRATCH") + [["jpr", "__CSR_SCRATCH"]] + +expansions: OpExpansionDict = { + "add": expand_add, + "sub": expand_sub, + "addi": expand_addi, + "subi": expand_subi, + "and": expand_and, + "or": expand_or, + "xor": expand_xor, + "sll": expand_sll, + "slr": expand_slr, + "sar": expand_sar, + "slli": expand_slli, + "slri": expand_slri, + "sari": expand_sari, + "inc": expand_inc, + "dec": expand_dec, + "mov": expand_mov, + "spu": expand_spu, + "spo": expand_spo, + "csr": expand_csr, + "csi": expand_csi, + "rsr": expand_rsr, +} diff --git a/asm/fibo.atk16 b/asm/fibo.atk16 index 8bb7a6e..198ae8b 100644 --- a/asm/fibo.atk16 +++ b/asm/fibo.atk16 @@ -6,12 +6,11 @@ jpi program ; data segment -@label ram_offset - 0x8000 +@include ram_offset @label program ; set up stack pointer to point to beginning of RAM - ldi ram_offset RA + ldi ram_offset_addr RA ldr RA RF ; call fibo subroutine with parameter 10 @@ -20,11 +19,9 @@ hlt @label fibo -; function fibo -; parameters: -; RA n : u16 -; return value: -; RA fibo(n) : u16 +;? subroutine fibo +;? param RA N +;? return RA Nth fibonacci number ; store RB, RC on stack spu RB diff --git a/asm/ram_offset.atk16 b/asm/ram_offset.atk16 new file mode 100644 index 0000000..e8c9255 --- /dev/null +++ b/asm/ram_offset.atk16 @@ -0,0 +1,2 @@ +@label ram_offset_addr + 0x8000 diff --git a/atk16-syntax-highlighting/README.md b/atk16-syntax-highlighting/README.md deleted file mode 100644 index da81144..0000000 --- a/atk16-syntax-highlighting/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# VSCode syntax highlighting extension for ATK16 assembly - -## Installation - -In `atk16-syntax-highlighting` directory, run: - - npx @vscode/vsce package - -Then go to VSCode > Command Palette > Extensions: Install from VSIX and select the generated `.vsix` file. diff --git a/atk16-syntax-highlighting/atk16-syntax-highlighting-0.0.1.vsix b/atk16-syntax-highlighting/atk16-syntax-highlighting-0.0.1.vsix deleted file mode 100644 index 5d4a42d..0000000 Binary files a/atk16-syntax-highlighting/atk16-syntax-highlighting-0.0.1.vsix and /dev/null differ diff --git a/atk16-syntax-highlighting/language-configuration.json b/atk16-syntax-highlighting/language-configuration.json deleted file mode 100644 index c186b1b..0000000 --- a/atk16-syntax-highlighting/language-configuration.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "comments": { - "lineComment": ";" - }, - "brackets": [ - [ - "{", - "}" - ], - [ - "[", - "]" - ], - [ - "(", - ")" - ] - ], - "autoClosingPairs": [ - [ - "{", - "}" - ], - [ - "[", - "]" - ], - [ - "(", - ")" - ], - [ - "\"", - "\"" - ], - [ - "'", - "'" - ] - ] -} \ No newline at end of file diff --git a/atk16-syntax-highlighting/package.json b/atk16-syntax-highlighting/package.json deleted file mode 100644 index ff6be2b..0000000 --- a/atk16-syntax-highlighting/package.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "name": "atk16-syntax-highlighting", - "displayName": "ATK16 Syntax Highlighting", - "description": "Syntax highlighting for ATK16 assembly language", - "version": "0.0.1", - "publisher": "Jan Tuomi", - "engines": { - "vscode": "^1.60.0" - }, - "categories": ["Programming Languages"], - "contributes": { - "languages": [ - { - "id": "atk16", - "aliases": ["ATK16 Assembly", "atk16"], - "extensions": [".atk16"], - "configuration": "./language-configuration.json" - } - ], - "grammars": [ - { - "language": "atk16", - "scopeName": "source.atk16", - "path": "./syntaxes/atk16.tmLanguage.json" - } - ] - } -} diff --git a/atk16-syntax-highlighting/syntaxes/atk16.tmLanguage.json b/atk16-syntax-highlighting/syntaxes/atk16.tmLanguage.json deleted file mode 100644 index 6028be3..0000000 --- a/atk16-syntax-highlighting/syntaxes/atk16.tmLanguage.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", - "name": "ATK16", - "patterns": [ - { - "name": "comment.line.semicolon.atk16", - "match": ";.*" - }, - { - "name": "keyword.control.directive.atk16", - "match": "@\\w+" - }, - { - "name": "variable.other.register.atk16", - "match": "R\\w+" - }, - { - "name": "constant.numeric.hex.atk16", - "match": "0x[0-9a-fA-F]+" - }, - { - "name": "constant.numeric.binary.atk16", - "match": "0b[01]+" - }, - { - "name": "constant.numeric.decimal.atk16", - "match": "[0-9]+" - }, - { - "name": "entity.name.function.atk16", - "match": "\\w+(?=\\s*\\()" - }, - { - "name": "entity.name.label.atk16", - "match": "\\w+(?=\\s*:)" - }, - { - "name": "keyword.control.instruction.atk16", - "match": "^\\s+[a-zA-Z]+" - }, - { - "name": "constant.language.flag.atk16", - "match": "\\b(carry|overflow|zero|sign)\\b" - } - ], - "repository": {}, - "scopeName": "source.atk16" -} diff --git a/atk16-syntax/README.md b/atk16-syntax/README.md new file mode 100644 index 0000000..da81144 --- /dev/null +++ b/atk16-syntax/README.md @@ -0,0 +1,9 @@ +# VSCode syntax highlighting extension for ATK16 assembly + +## Installation + +In `atk16-syntax-highlighting` directory, run: + + npx @vscode/vsce package + +Then go to VSCode > Command Palette > Extensions: Install from VSIX and select the generated `.vsix` file. diff --git a/atk16-syntax/atk16-syntax-0.0.1.vsix b/atk16-syntax/atk16-syntax-0.0.1.vsix new file mode 100644 index 0000000..b6aa9dc Binary files /dev/null and b/atk16-syntax/atk16-syntax-0.0.1.vsix differ diff --git a/atk16-syntax/extension.js b/atk16-syntax/extension.js new file mode 100644 index 0000000..e49dd07 --- /dev/null +++ b/atk16-syntax/extension.js @@ -0,0 +1,197 @@ +const vscode = require('vscode'); +const path = require('path'); + +class ATK16HoverProvider { + async provideHover(document, position, token) { + const range = document.getWordRangeAtPosition(position, /[\w-/.]+/); + const labelText = document.getText(range); + const subroutineDefinition = await findSubroutineInDocument(document, labelText); + if (subroutineDefinition) { + const hoverText = new vscode.MarkdownString(subroutineDefinition); + hoverText.isTrusted = true; + return new vscode.Hover(hoverText); + } + + // Search for labels in included files + for (let i = 0; i < document.lineCount; i++) { + const line = document.lineAt(i); + const includeMatch = line.text.match(/@include\s+(\S+)/); + if (includeMatch) { + const includedFilePath = path.join( + path.dirname(document.fileName), + `${includeMatch[1]}.atk16` + ); + + if (await vscode.workspace.fs.stat(vscode.Uri.file(includedFilePath))) { + const includedDocument = await vscode.workspace.openTextDocument( + includedFilePath + ); + const subroutineDefinition = await findSubroutineInDocument(includedDocument, labelText); + if (subroutineDefinition) { + const hoverText = new vscode.MarkdownString(subroutineDefinition); + hoverText.isTrusted = true; + return new vscode.Hover(hoverText); + } + } + } + } + + return null; + } +} + +class ATK16DefinitionProvider { + async provideDefinition(document, position, token) { + const range = document.getWordRangeAtPosition(position, /[\w-/.]+/); + const text = document.getText(range); + + const line = document.lineAt(position); + const includeMatch = line.text.match(/@include\s+(\S+)/); + const useMatch = line.text.match(/@use\s+(\S+):/); + + if (includeMatch && includeMatch[1] === text) { + const includedFilePath = path.join( + path.dirname(document.fileName), + `${includeMatch[1]}.atk16` + ); + + try { + await vscode.workspace.fs.stat(vscode.Uri.file(includedFilePath)); + return new vscode.Location( + vscode.Uri.file(includedFilePath), + new vscode.Position(0, 0) + ); + } catch (err) { + vscode.window.showErrorMessage( + `ATK16: File not found: ${includedFilePath}` + ); + } + } else if (useMatch && useMatch[1] === text) { + const includedFilePath = path.join( + path.dirname(document.fileName), + `${useMatch[1]}.py` + ); + + try { + await vscode.workspace.fs.stat(vscode.Uri.file(includedFilePath)); + return new vscode.Location( + vscode.Uri.file(includedFilePath), + new vscode.Position(0, 0) + ); + } catch (err) { + vscode.window.showErrorMessage( + `ATK16: File not found: ${includedFilePath}` + ); + } + } else { + const labelText = document.getText(range); + let labelLocation = await findLabelInDocument(document, labelText); + if (labelLocation) { + return labelLocation; + } + + // Search for labels in included files + for (let i = 0; i < document.lineCount; i++) { + const line = document.lineAt(i); + const includeMatch = line.text.match(/@include\s+(\S+)/); + if (includeMatch) { + const includedFilePath = path.join( + path.dirname(document.fileName), + `${includeMatch[1]}.atk16` + ); + + if (await vscode.workspace.fs.stat(vscode.Uri.file(includedFilePath))) { + const includedDocument = await vscode.workspace.openTextDocument( + includedFilePath + ); + labelLocation = await findLabelInDocument(includedDocument, labelText); + if (labelLocation) { + return labelLocation; + } + } + } + } + } + + return null; + } +} + +async function findLabelInDocument(document, labelText) { + for (let i = 0; i < document.lineCount; i++) { + const line = document.lineAt(i); + if (line.text.includes(`@label ${labelText}`)) { + return new vscode.Location(document.uri, line.range.start); + } + } + return null; +} + +async function findSubroutineInDocument(document, labelText) { + let name = null; + const params = []; + const returns = []; + let extra = ""; + for (let i = 0; i < document.lineCount; i++) { + const line = document.lineAt(i); + if (line.text.includes(`@label ${labelText}`)) { + let labelDefinition = ''; + for (let j = i + 1; j < document.lineCount; j++) { + const docLine = document.lineAt(j); + const docCommentMatch = docLine.text.match(/;\? (.*)/); + if (docCommentMatch) { + const lineText = docCommentMatch[1]; + const parts = lineText.split(/\s/); + if (lineText.startsWith('subroutine')) { + name = parts[parts.length - 1]; + } else if (lineText.startsWith('param')) { + const [_, reg, ...desc] = parts; + params.push([reg, desc.join(" ")]) + } else if (lineText.startsWith('return')) { + const [_, reg, ...desc] = parts; + returns.push([reg, desc.join(" ")]) + } else { + extra += `${lineText}\n`; + } + } else { + break; + } + } + } + } + + if (name === null) return null; + + let definition = `### ${name}\n_Subroutine_\n\n`; + definition += extra; + if (params.length > 0) { + definition += "\n\n|Reg|Parameter|\n"; + definition += "|:---|:---|\n"; + } + for (const [reg, desc] of params) { + definition += `|${reg}|${desc}|\n`; + } + + if (returns.length > 0) { + definition += "\n|Reg|Return|\n"; + definition += "|:---|:---|\n"; + } + for (const [reg, desc] of returns) { + definition += `|${reg}|${desc}|\n`; + } + return definition; +} + +function activate(context) { + context.subscriptions.push( + vscode.languages.registerDefinitionProvider('atk16', new ATK16DefinitionProvider()), + vscode.languages.registerHoverProvider('atk16', new ATK16HoverProvider()) + ); +} + +function deactivate() {} + +module.exports = { + activate, + deactivate, +}; \ No newline at end of file diff --git a/atk16-syntax/language-configuration.json b/atk16-syntax/language-configuration.json new file mode 100644 index 0000000..c186b1b --- /dev/null +++ b/atk16-syntax/language-configuration.json @@ -0,0 +1,41 @@ +{ + "comments": { + "lineComment": ";" + }, + "brackets": [ + [ + "{", + "}" + ], + [ + "[", + "]" + ], + [ + "(", + ")" + ] + ], + "autoClosingPairs": [ + [ + "{", + "}" + ], + [ + "[", + "]" + ], + [ + "(", + ")" + ], + [ + "\"", + "\"" + ], + [ + "'", + "'" + ] + ] +} \ No newline at end of file diff --git a/atk16-syntax/package.json b/atk16-syntax/package.json new file mode 100644 index 0000000..bdfbb74 --- /dev/null +++ b/atk16-syntax/package.json @@ -0,0 +1,39 @@ +{ + "name": "atk16-syntax", + "displayName": "ATK16 Syntax", + "description": "Syntax highlighting and support for ATK16 assembly language", + "version": "0.0.1", + "publisher": "JanTuomi", + "engines": { + "vscode": "^1.60.0" + }, + "categories": ["Programming Languages"], + "activationEvents": [ + "onLanguage:atk16" + ], + "main": "./extension.js", + "contributes": { + "languages": [ + { + "id": "atk16", + "aliases": ["ATK16 Assembly", "atk16"], + "extensions": [".atk16"], + "configuration": "./language-configuration.json" + } + ], + "grammars": [ + { + "language": "atk16", + "scopeName": "source.atk16", + "path": "./syntaxes/atk16.tmLanguage.json" + } + ], + "themes": [ + { + "label": "ATK16 Color Theme", + "uiTheme": "vs-dark", + "path": "./themes/atk16-color-theme.json" + } + ] + } +} diff --git a/atk16-syntax/syntaxes/atk16.tmLanguage.json b/atk16-syntax/syntaxes/atk16.tmLanguage.json new file mode 100644 index 0000000..1faadf9 --- /dev/null +++ b/atk16-syntax/syntaxes/atk16.tmLanguage.json @@ -0,0 +1,52 @@ +{ + "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", + "name": "ATK16", + "patterns": [ + { + "name": "comment.documentation.atk16", + "match": ";\\?.*$" + }, + { + "name": "comment.line.semicolon.atk16", + "match": ";.*" + }, + { + "name": "keyword.control.directive.atk16", + "match": "^@\\w+" + }, + { + "name": "variable.other.register.atk16", + "match": "R\\w+" + }, + { + "name": "constant.numeric.hex.atk16", + "match": "0x[0-9a-fA-F]+" + }, + { + "name": "constant.numeric.binary.atk16", + "match": "0b[01]+" + }, + { + "name": "constant.numeric.decimal.atk16", + "match": "[0-9]+" + }, + { + "name": "entity.name.function.atk16", + "match": "\\w+(?=\\s*\\()" + }, + { + "name": "entity.name.label.atk16", + "match": "\\w+(?=\\s*:)" + }, + { + "name": "keyword.control.instruction.atk16", + "match": "^\\s+[a-zA-Z]+" + }, + { + "name": "constant.language.flag.atk16", + "match": "\\b(carry|overflow|zero|sign)\\b" + } + ], + "repository": {}, + "scopeName": "source.atk16" +} diff --git a/atk16-syntax/themes/atk16-color-theme.json b/atk16-syntax/themes/atk16-color-theme.json new file mode 100644 index 0000000..d1aebb9 --- /dev/null +++ b/atk16-syntax/themes/atk16-color-theme.json @@ -0,0 +1,41 @@ +{ + "name": "ATK16", + "type": "dark", + "colors": { + "editor.background": "#1E1E1E", + "editor.foreground": "#D4D4D4", + "editor.lineHighlightBackground": "#2D2D30" + }, + "tokenColors": [ + { + "scope": "keyword.control.directive.atk16", + "settings": {} + }, + { + "scope": "variable.parameter.register.atk16", + "settings": {} + }, + { + "scope": "constant.numeric.binary.atk16", + "settings": {} + }, + { + "scope": "keyword.control.instruction.atk16", + "settings": {} + }, + { + "scope": "support.function.atk16", + "settings": {} + }, + { + "scope": "entity.name.label.atk16", + "settings": {} + }, + { + "scope": "comment.documentation.atk16", + "settings": { + "fontStyle": "italic" + } + } + ] +} \ No newline at end of file diff --git a/src/asm_pass0.py b/src/asm_pass0.py new file mode 100644 index 0000000..be6c46a --- /dev/null +++ b/src/asm_pass0.py @@ -0,0 +1,48 @@ +from dataclasses import dataclass +from asm_ops import * +from asm_eval import * + +@dataclass +class Result0Line: + line_num: int + src_file: str + line: str + +@dataclass +class Result0: + lines: list[Result0Line] + options: Options + operations: OpExpansionDict + +def pass_0(lines: list[str], file_name: str) -> Result0: + options = Options() + result_lines: list[Result0Line] = [] + operations: OpExpansionDict = default_expansions.copy() + + for (line_num, line) in enumerate(lines): + line = line.split(";")[0].strip() + if line == "": continue + keyword, *args = line.lower().split() + match keyword: + case "@include": + asm_file_name = args[0] + with open(asm_file_name, "r") as f: + for incl_line in f.readlines(): + result_lines.append(Result0Line( + src_file=asm_file_name, + line_num=line_num, + line=incl_line + )) + + case _: + result_lines.append(Result0Line( + src_file=file_name, + line_num=line_num, + line=line + )) + + return Result0( + operations=operations, + options=options, + lines=result_lines + ) diff --git a/src/asm_pass1.py b/src/asm_pass1.py index 606a1a1..fee72ff 100644 --- a/src/asm_pass1.py +++ b/src/asm_pass1.py @@ -2,10 +2,12 @@ import importlib from dataclasses import dataclass from asm_ops import * from asm_eval import * +from asm_pass0 import * @dataclass class Result1Line: line_num: int + src_file: str parts: list[str] @dataclass @@ -14,15 +16,13 @@ class Result1: options: Options operations: OpExpansionDict -def pass_1(lines: list[str]) -> Result1: +def pass_1(result0: Result0) -> Result1: options = Options() result_lines: list[Result1Line] = [] operations: OpExpansionDict = default_expansions.copy() - for (line_num, line) in enumerate(lines): - line = line.split(";")[0].strip() - if line == "": continue - keyword, *args = line.lower().split() + for line in result0.lines: + keyword, *args = line.line.lower().split() match keyword: case "@opt": opt_name, opt_value = args @@ -41,7 +41,8 @@ def pass_1(lines: list[str]) -> Result1: operations[op] = expansion case _: result_lines.append(Result1Line( - line_num=line_num, + src_file=line.src_file, + line_num=line.line_num, parts=[keyword, *args] )) diff --git a/src/asm_pass2.py b/src/asm_pass2.py index e7f48ac..7272dcf 100644 --- a/src/asm_pass2.py +++ b/src/asm_pass2.py @@ -6,6 +6,7 @@ from asm_pass1 import * @dataclass class Result2Line: line_num: int + src_file: str parts: list[str] original_parts: list[str] @@ -30,6 +31,7 @@ def pass_2(result1: Result1) -> Result2: for (idx, parts) in enumerate(output): result_lines.append(Result2Line( line_num=line.line_num, + src_file=line.src_file, parts=parts, original_parts=line.parts if idx == 0 else ["..."] )) diff --git a/src/asm_pass3.py b/src/asm_pass3.py index 038e3f7..76e7b84 100644 --- a/src/asm_pass3.py +++ b/src/asm_pass3.py @@ -6,6 +6,7 @@ from asm_pass2 import * @dataclass class Result3Line: line_num: int + src_file: str address: int parts: list[str] original_parts: list[str] @@ -34,6 +35,7 @@ def pass_3(result2: Result2) -> Result3: case _: result_lines.append(Result3Line( line_num=line.line_num, + src_file=line.src_file, parts=line.parts, address=address, original_parts=line.original_parts, diff --git a/src/asm_pass4.py b/src/asm_pass4.py index 3d4f45c..dc65b65 100644 --- a/src/asm_pass4.py +++ b/src/asm_pass4.py @@ -6,6 +6,7 @@ from asm_pass3 import * @dataclass class Result4Line: line_num: int + src_file: str address: int word: int text: str @@ -43,6 +44,7 @@ def pass_4(result3: Result3) -> Result4: word = fn(meta, result3.labels, *args) result_lines.append(Result4Line( line_num=line.line_num, + src_file=line.src_file, address=line.address, word=word, text=text, @@ -52,13 +54,14 @@ def pass_4(result3: Result3) -> Result4: try: result_lines.append(Result4Line( line_num=line.line_num, + src_file=line.src_file, address=line.address, word=eval_expr(result3.labels, keyword), text=text, original_text=original_text, )) except: - raise Exception(f"Invalid assembly at {line.line_num + 1}\n\n{line}") + raise Exception(f"Invalid assembly at {line.src_file}:{line.line_num + 1}\n\n{line}") address += 1 diff --git a/src/assembler.py b/src/assembler.py index 3f0c8bc..8f84288 100755 --- a/src/assembler.py +++ b/src/assembler.py @@ -4,6 +4,7 @@ import sys from asm_ops import * from asm_eval import * +from asm_pass0 import pass_0 from asm_pass1 import pass_1 from asm_pass2 import pass_2 from asm_pass3 import pass_3 @@ -49,7 +50,8 @@ def parse(line: str) -> list[str]: result.append(acc) return list(filter(lambda x: len(x) > 0, result)) -result1 = pass_1(src_lines) +result0 = pass_0(src_lines, infile_path) +result1 = pass_1(result0) result2 = pass_2(result1) result3 = pass_3(result2) result4 = pass_4(result3) diff --git a/src/ext_std.py b/src/ext_std.py deleted file mode 100644 index 11da8aa..0000000 --- a/src/ext_std.py +++ /dev/null @@ -1,97 +0,0 @@ -from asm_ops import * - -def expand_add(left: str, right: str, target: str) -> ExpandResult: - return [["alr", "al_plus", left, right, target]] - -def expand_sub(left: str, right: str, target: str) -> ExpandResult: - return [["alr", "al_minus", left, right, target]] - -def expand_addi(left: str, imm: str, target: str) -> ExpandResult: - return [["ali", "al_plus", left, imm, target]] - -def expand_subi(left: str, imm: str, target: str) -> ExpandResult: - return [["ali", "al_minus", left, imm, target]] - -def expand_and(left: str, right: str, target: str) -> ExpandResult: - return [["alr", "al_and", left, right, target]] - -def expand_or(left: str, right: str, target: str) -> ExpandResult: - return [["alr", "al_or", left, right, target]] - -def expand_xor(left: str, right: str, target: str) -> ExpandResult: - return [["alr", "al_xor", left, right, target]] - -def expand_sll(left: str, right: str, target: str) -> ExpandResult: - return [["alr", "al_sll", left, right, target]] - -def expand_slr(left: str, right: str, target: str) -> ExpandResult: - return [["alr", "al_slr", left, right, target]] - -def expand_sar(left: str, right: str, target: str) -> ExpandResult: - return [["alr", "al_sar", left, right, target]] - -def expand_slli(left: str, imm: str, target: str) -> ExpandResult: - return [["ali", "al_sll", left, imm, target]] - -def expand_slri(left: str, imm: str, target: str) -> ExpandResult: - return [["ali", "al_slr", left, imm, target]] - -def expand_sari(left: str, imm: str, target: str) -> ExpandResult: - return [["ali", "al_sar", left, imm, target]] - -def expand_inc(reg: str) -> ExpandResult: - return [["ali", "al_plus", reg, "1", reg]] - -def expand_dec(reg: str) -> ExpandResult: - return [["ali", "al_minus", reg, "1", reg]] - -def expand_mov(from_reg: str, to_reg: str) -> ExpandResult: - return [["ali", "al_plus", from_reg, "0", to_reg]] - -def expand_spu(reg: str) -> ExpandResult: - return [["str", reg, "__STACK_POINTER"]] + expand_inc("__STACK_POINTER") - -def expand_spo(reg: str): - return expand_dec("__STACK_POINTER") + [["ldr", "__STACK_POINTER", reg]] - -def expand_csr(addr_reg: str): - return [ - ["lpc", "__CSR_SCRATCH"], - *expand_addi("__CSR_SCRATCH", "4", "__CSR_SCRATCH"), - *expand_spu("__CSR_SCRATCH"), - ["jpr", addr_reg] - ] - -def expand_csi(addr_imm: str): - return [ - ["lpc", "__CSR_SCRATCH"], - *expand_addi("__CSR_SCRATCH", "4", "__CSR_SCRATCH"), - *expand_spu("__CSR_SCRATCH"), - ["jpi", addr_imm] - ] -def expand_rsr(): - return expand_spo("__CSR_SCRATCH") + [["jpr", "__CSR_SCRATCH"]] - -expansions: OpExpansionDict = { - "add": expand_add, - "sub": expand_sub, - "addi": expand_addi, - "subi": expand_subi, - "and": expand_and, - "or": expand_or, - "xor": expand_xor, - "sll": expand_sll, - "slr": expand_slr, - "sar": expand_sar, - "slli": expand_slli, - "slri": expand_slri, - "sari": expand_sari, - "inc": expand_inc, - "dec": expand_dec, - "mov": expand_mov, - "spu": expand_spu, - "spo": expand_spo, - "csr": expand_csr, - "csi": expand_csi, - "rsr": expand_rsr, -} -- cgit v1.3