From 3f63a110cf9fc3a058c5093a9cf0e7118d89c8aa Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Tue, 26 Nov 2024 23:12:45 +0100 Subject: [PATCH 1/2] feat: show a better error message upon crash --- src/arch/z80/peephole/evaluator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arch/z80/peephole/evaluator.py b/src/arch/z80/peephole/evaluator.py index 291564583..82c57632f 100644 --- a/src/arch/z80/peephole/evaluator.py +++ b/src/arch/z80/peephole/evaluator.py @@ -195,7 +195,7 @@ def __init__(self, expression): expression[2] = Evaluator(expression[2]) else: # It's a list assert len(expression) % 2 # Must be odd length - assert all(x == FN.OP_COMMA for i, x in enumerate(expression) if i % 2) + assert all(x == FN.OP_COMMA for i, x in enumerate(expression) if i % 2), f"Invalid expression {expression}" self.expression = [Evaluator(x) if not i % 2 else x for i, x in enumerate(expression)] @staticmethod From 97dd4108fe6a49b805c55b1f11ba44d300eee20f Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Tue, 26 Nov 2024 23:27:48 +0100 Subject: [PATCH 2/2] fix: crash on undetected syntax error --- src/arch/z80/peephole/parser.py | 4 ++ tests/arch/zx48k/peephole/test_parser.py | 68 +++++++++++++++--------- 2 files changed, 46 insertions(+), 26 deletions(-) diff --git a/src/arch/z80/peephole/parser.py b/src/arch/z80/peephole/parser.py index 47332f3b1..99d2958e8 100644 --- a/src/arch/z80/peephole/parser.py +++ b/src/arch/z80/peephole/parser.py @@ -161,6 +161,10 @@ def parse_ifline(if_line: str, lineno: int) -> TreeType | None: errmsg.warning(lineno, "missing element in list") return None + if any(x != FN.OP_COMMA for i, x in enumerate(expr) if i % 2): + errmsg.warning(lineno, f"Invalid list {expr}") + return None + stack[-1].append(expr) expr = stack.pop() else: diff --git a/tests/arch/zx48k/peephole/test_parser.py b/tests/arch/zx48k/peephole/test_parser.py index 844f2b24d..54762b2e2 100644 --- a/tests/arch/zx48k/peephole/test_parser.py +++ b/tests/arch/zx48k/peephole/test_parser.py @@ -399,14 +399,8 @@ def test_parse_if_must_start_in_a_new_line(self): def test_parse_with_ending_binary_error(self): result = parser.parse_str( """ - ;; Remove the boolean normalization if it's done after calling - ;; certain routines that return the bool result already normalized. - - ;; The sequence - ;; sub 1 - ;; sbc a, a - ;; inc a - ;; can be removed + ;; Sample Comment + ;; OLEVEL: 1 OFLAG: 20 @@ -428,15 +422,6 @@ def test_parse_with_ending_binary_error(self): def test_parse_with_comma_error(self): result = parser.parse_str( """ - ;; Remove the boolean normalization if it's done after calling - ;; certain routines that return the bool result already normalized. - - ;; The sequence - ;; sub 1 - ;; sbc a, a - ;; inc a - ;; can be removed - OLEVEL: 1 OFLAG: 20 @@ -458,15 +443,6 @@ def test_parse_with_comma_error(self): def test_parse_with_nested_comma_error(self): result = parser.parse_str( """ - ;; Remove the boolean normalization if it's done after calling - ;; certain routines that return the bool result already normalized. - - ;; The sequence - ;; sub 1 - ;; sbc a, a - ;; inc a - ;; can be removed - OLEVEL: 1 OFLAG: 20 @@ -484,3 +460,43 @@ def test_parse_with_nested_comma_error(self): """ ) assert result is None + + def test_parse_with_list_error(self): + result = parser.parse_str( + """ + OLEVEL: 1 + OFLAG: 20 + + REPLACE {{ + $1 + }} + + WITH {{ + }} + + IF {{ + $1 IN ("x", "y" . "pera") + }} + """ + ) + assert result is None + + def test_parse_with_list_error2(self): + result = parser.parse_str( + """ + OLEVEL: 1 + OFLAG: 20 + + REPLACE {{ + $1 + }} + + WITH {{ + }} + + IF {{ + $1 IN ("x", , , "pera") + }} + """ + ) + assert result is None