From b636d9ed7134f3ccff7edd1b4f86390c0562f055 Mon Sep 17 00:00:00 2001 From: James Westman Date: Sun, 12 Mar 2023 14:29:20 -0500 Subject: [PATCH] Fix bugs in number literals --- blueprintcompiler/language/response_id.py | 18 +++++++---- blueprintcompiler/language/values.py | 30 ++++++++----------- blueprintcompiler/tokenizer.py | 6 ++-- .../action_widget_negative_response.err | 2 +- 4 files changed, 29 insertions(+), 27 deletions(-) diff --git a/blueprintcompiler/language/response_id.py b/blueprintcompiler/language/response_id.py index 073173a..e3b44a9 100644 --- a/blueprintcompiler/language/response_id.py +++ b/blueprintcompiler/language/response_id.py @@ -31,7 +31,13 @@ class ResponseId(AstNode): grammar = [ Keyword("response"), "=", - AnyOf(UseIdent("response_id"), UseNumber("response_id")), + AnyOf( + UseIdent("response_id"), + [ + Optional(UseExact("sign", "-")), + UseNumber("response_id"), + ], + ), Optional([Keyword("default"), UseLiteral("is_default", True)]), ] @@ -81,14 +87,14 @@ class ResponseId(AstNode): gir = self.root.gir response = self.tokens["response_id"] - if isinstance(response, int): - if response < 0: - raise CompileError("Numeric response type can't be negative") - elif isinstance(response, float): + if self.tokens["sign"] == "-": + raise CompileError("Numeric response type can't be negative") + + if isinstance(response, float): raise CompileError( "Response type must be GtkResponseType member or integer," " not float" ) - else: + elif not isinstance(response, int): responses = gir.get_type("ResponseType", "Gtk").members.keys() if response not in responses: raise CompileError(f'Response type "{response}" doesn\'t exist') diff --git a/blueprintcompiler/language/values.py b/blueprintcompiler/language/values.py index d03fc84..ca10f50 100644 --- a/blueprintcompiler/language/values.py +++ b/blueprintcompiler/language/values.py @@ -145,39 +145,35 @@ class NumberLiteral(AstNode): UseNumber("value"), ] + @property + def type(self) -> gir.GirType: + if isinstance(self.value, int): + return gir.IntType() + else: + return gir.FloatType() + @property def value(self) -> T.Union[int, float]: - return self.tokens["value"] + if self.tokens["sign"] == "-": + return -self.tokens["value"] + else: + return self.tokens["value"] @validate() def validate_for_type(self) -> None: expected_type = self.context[ValueTypeCtx].value_type if isinstance(expected_type, gir.IntType): - try: - int(self.tokens["value"]) - except: + if not isinstance(self.value, int): raise CompileError( f"Cannot convert {self.group.tokens['value']} to integer" ) elif isinstance(expected_type, gir.UIntType): - try: - int(self.tokens["value"]) - if int(self.tokens["value"]) < 0: - raise Exception() - except: + if self.value < 0: raise CompileError( f"Cannot convert {self.group.tokens['value']} to unsigned integer" ) - elif isinstance(expected_type, gir.FloatType): - try: - float(self.tokens["value"]) - except: - raise CompileError( - f"Cannot convert {self.group.tokens['value']} to float" - ) - elif expected_type is not None: raise CompileError(f"Cannot convert number to {expected_type.full_name}") diff --git a/blueprintcompiler/tokenizer.py b/blueprintcompiler/tokenizer.py index 170316c..5a40803 100644 --- a/blueprintcompiler/tokenizer.py +++ b/blueprintcompiler/tokenizer.py @@ -41,8 +41,8 @@ _tokens = [ (TokenType.QUOTED, r'"(\\"|[^"\n])*"'), (TokenType.QUOTED, r"'(\\'|[^'\n])*'"), (TokenType.NUMBER, r"0x[A-Za-z0-9_]+"), - (TokenType.NUMBER, r"[-+]?[\d_]+(\.[\d_]+)?"), - (TokenType.NUMBER, r"[-+]?\.[\d_]+"), + (TokenType.NUMBER, r"[\d_]+(\.[\d_]+)?"), + (TokenType.NUMBER, r"\.[\d_]+"), (TokenType.WHITESPACE, r"\s+"), (TokenType.COMMENT, r"\/\*[\s\S]*?\*\/"), (TokenType.COMMENT, r"\/\/[^\n]*"), @@ -71,7 +71,7 @@ class Token: if string.startswith("0x"): return int(string, 16) else: - return float(string.replace("_", "")) + return float(string) except: raise CompileError( f"{str(self)} is not a valid number literal", self.start, self.end diff --git a/tests/sample_errors/action_widget_negative_response.err b/tests/sample_errors/action_widget_negative_response.err index 6e6836d..6f0a627 100644 --- a/tests/sample_errors/action_widget_negative_response.err +++ b/tests/sample_errors/action_widget_negative_response.err @@ -1 +1 @@ -4,24,4,Numeric response type can't be negative +4,25,3,Numeric response type can't be negative