feat: handle not operator

This commit is contained in:
2026-07-06 17:06:21 +02:00
parent a640b8b3dd
commit 164648e8df
5 changed files with 16 additions and 3 deletions

View File

@@ -28,7 +28,7 @@ from midas.checker.types import (
)
from midas.checker.variance import VarianceInferrer
from midas.lexer.midas import MidasLexer
from midas.lexer.token import Token
from midas.lexer.token import Token, TokenType
from midas.parser.midas import MidasParser
@@ -297,6 +297,11 @@ class MidasTyper(m.Stmt.Visitor[None], m.Expr.Visitor[Type], m.Type.Visitor[Type
return result.result
def visit_unary_expr(self, expr: m.UnaryExpr) -> Type:
# Special case because there is no __not__ dunder method
match expr.operator:
case Token(type=TokenType.BANG):
return self.types.get_type("bool")
method: Optional[str] = MIDAS_UNARY_METHODS.get(expr.operator.type)
if method is None:
self.logger.warning(f"Unsupported operator {expr.operator.lexeme}")

View File

@@ -686,6 +686,11 @@ class PythonTyper(
return UnknownType()
def visit_unary_expr(self, expr: p.UnaryExpr) -> Type:
# Special case because there is no __not__ dunder method
match expr.operator:
case ast.Not():
return self.types.get_type("bool")
method: Optional[str] = PY_UNARY_METHODS.get(expr.operator.__class__)
if method is None:
self.logger.warning(f"Unsupported operator {expr.operator}")

View File

@@ -32,6 +32,8 @@ class MidasLexer(Lexer):
)
case "!" if self.match("="):
self.add_token(TokenType.BANG_EQUAL)
case "!":
self.add_token(TokenType.BANG)
case ":":
self.add_token(TokenType.COLON)
case ".":

View File

@@ -36,6 +36,7 @@ class TokenType(Enum):
EQUAL = auto()
EQUAL_EQUAL = auto()
BANG_EQUAL = auto()
BANG = auto()
# Literals
IDENTIFIER = auto()

View File

@@ -487,12 +487,12 @@ class MidasParser(Parser[list[Stmt]]):
"""Parse a unary expression
A unary consists of a call expression (see :func:`call`) optionally
preceded by zero or more unary operators (`+`, `-`)
preceded by zero or more unary operators (`+`, `-`, `!`)
Returns:
Expr: the parsed expression
"""
if self.match(TokenType.PLUS, TokenType.MINUS):
if self.match(TokenType.PLUS, TokenType.MINUS, TokenType.BANG):
operator: Token = self.previous()
right: Expr = self.unary()
location: Location = Location.span(operator.get_location(), right.location)