Fix bugs in number literals

This commit is contained in:
James Westman 2023-03-12 14:29:20 -05:00
parent fad3b35531
commit b636d9ed71
4 changed files with 29 additions and 27 deletions

View file

@ -31,7 +31,13 @@ class ResponseId(AstNode):
grammar = [ grammar = [
Keyword("response"), 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)]), Optional([Keyword("default"), UseLiteral("is_default", True)]),
] ]
@ -81,14 +87,14 @@ class ResponseId(AstNode):
gir = self.root.gir gir = self.root.gir
response = self.tokens["response_id"] response = self.tokens["response_id"]
if isinstance(response, int): if self.tokens["sign"] == "-":
if response < 0:
raise CompileError("Numeric response type can't be negative") raise CompileError("Numeric response type can't be negative")
elif isinstance(response, float):
if isinstance(response, float):
raise CompileError( raise CompileError(
"Response type must be GtkResponseType member or integer," " not float" "Response type must be GtkResponseType member or integer," " not float"
) )
else: elif not isinstance(response, int):
responses = gir.get_type("ResponseType", "Gtk").members.keys() responses = gir.get_type("ResponseType", "Gtk").members.keys()
if response not in responses: if response not in responses:
raise CompileError(f'Response type "{response}" doesn\'t exist') raise CompileError(f'Response type "{response}" doesn\'t exist')

View file

@ -145,39 +145,35 @@ class NumberLiteral(AstNode):
UseNumber("value"), UseNumber("value"),
] ]
@property
def type(self) -> gir.GirType:
if isinstance(self.value, int):
return gir.IntType()
else:
return gir.FloatType()
@property @property
def value(self) -> T.Union[int, float]: def value(self) -> T.Union[int, float]:
if self.tokens["sign"] == "-":
return -self.tokens["value"]
else:
return self.tokens["value"] return self.tokens["value"]
@validate() @validate()
def validate_for_type(self) -> None: def validate_for_type(self) -> None:
expected_type = self.context[ValueTypeCtx].value_type expected_type = self.context[ValueTypeCtx].value_type
if isinstance(expected_type, gir.IntType): if isinstance(expected_type, gir.IntType):
try: if not isinstance(self.value, int):
int(self.tokens["value"])
except:
raise CompileError( raise CompileError(
f"Cannot convert {self.group.tokens['value']} to integer" f"Cannot convert {self.group.tokens['value']} to integer"
) )
elif isinstance(expected_type, gir.UIntType): elif isinstance(expected_type, gir.UIntType):
try: if self.value < 0:
int(self.tokens["value"])
if int(self.tokens["value"]) < 0:
raise Exception()
except:
raise CompileError( raise CompileError(
f"Cannot convert {self.group.tokens['value']} to unsigned integer" 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: elif expected_type is not None:
raise CompileError(f"Cannot convert number to {expected_type.full_name}") raise CompileError(f"Cannot convert number to {expected_type.full_name}")

View file

@ -41,8 +41,8 @@ _tokens = [
(TokenType.QUOTED, r'"(\\"|[^"\n])*"'), (TokenType.QUOTED, r'"(\\"|[^"\n])*"'),
(TokenType.QUOTED, r"'(\\'|[^'\n])*'"), (TokenType.QUOTED, r"'(\\'|[^'\n])*'"),
(TokenType.NUMBER, r"0x[A-Za-z0-9_]+"), (TokenType.NUMBER, r"0x[A-Za-z0-9_]+"),
(TokenType.NUMBER, r"[-+]?[\d_]+(\.[\d_]+)?"), (TokenType.NUMBER, r"[\d_]+(\.[\d_]+)?"),
(TokenType.NUMBER, r"[-+]?\.[\d_]+"), (TokenType.NUMBER, r"\.[\d_]+"),
(TokenType.WHITESPACE, r"\s+"), (TokenType.WHITESPACE, r"\s+"),
(TokenType.COMMENT, r"\/\*[\s\S]*?\*\/"), (TokenType.COMMENT, r"\/\*[\s\S]*?\*\/"),
(TokenType.COMMENT, r"\/\/[^\n]*"), (TokenType.COMMENT, r"\/\/[^\n]*"),
@ -71,7 +71,7 @@ class Token:
if string.startswith("0x"): if string.startswith("0x"):
return int(string, 16) return int(string, 16)
else: else:
return float(string.replace("_", "")) return float(string)
except: except:
raise CompileError( raise CompileError(
f"{str(self)} is not a valid number literal", self.start, self.end f"{str(self)} is not a valid number literal", self.start, self.end

View file

@ -1 +1 @@
4,24,4,Numeric response type can't be negative 4,25,3,Numeric response type can't be negative