From dfc05bbe3ca693547848766f7a83839126352a9c Mon Sep 17 00:00:00 2001 From: Aaron Zuspan Date: Tue, 20 Aug 2024 19:01:40 -0700 Subject: [PATCH] Fix parsing of partial float literals --- src/spinasm_lsp/parser.py | 14 ++++++++++---- tests/test_parser.py | 23 +++++++++++++++++++++++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/spinasm_lsp/parser.py b/src/spinasm_lsp/parser.py index 2540b94..9fbbc4c 100644 --- a/src/spinasm_lsp/parser.py +++ b/src/spinasm_lsp/parser.py @@ -2,6 +2,8 @@ from __future__ import annotations +import contextlib + import lsprotocol.types as lsp from asfv1 import fv1parse @@ -64,10 +66,14 @@ def __next__(self) -> None: current_line_txt = self._source[self._current_line] current_symbol = self.parsed_symbol.txt - # Start at the current column to skip previous duplicates of the symbol - self._current_character = current_line_txt.index( - current_symbol, self._current_character - ) + # Update the current parsed character. This can fail under rare circumstances, + # in which case we'll leave _current_character unchanged. + # See https://github.com/aazuspan/spinasm-lsp/issues/31 + with contextlib.suppress(ValueError): + # Start at the current column to skip previous duplicates of the symbol + self._current_character = current_line_txt.index( + current_symbol, self._current_character + ) class SPINAsmDiagnosticParser(SPINAsmPositionParser): diff --git a/tests/test_parser.py b/tests/test_parser.py index cdbce3c..bf4cc3c 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -46,3 +46,26 @@ def test_example_patches(patch, data_regression): encoded = serialize_parser_output(parser) data_regression.check(encoded) + + +def test_parsing_as_typed(): + """Test that the parser is fault tolerant for partially entered programs.""" + + # Example program from SPINAsm documentation. Iteratively parsing at each character + # is slow, so we use a small sample program here rather than parameterizing over the + # larger test patches. + source = """ + ; Example program from SPINAsm documentation + Attn EQU 0.5 + Tmp_Reg EQU 63 + Tmp_Del EQU $2000 + + sof 0,0 + rda Tmp_Del,Attn + wrax Tmp_Reg,1.0 + wrax DACL + """ + source_chars = list(source) + for i in range(len(source_chars)): + partial_source = "".join(source_chars[:i]) + assert SPINAsmParser(partial_source)