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.checker.variance import VarianceInferrer
from midas.lexer.midas import MidasLexer 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 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 return result.result
def visit_unary_expr(self, expr: m.UnaryExpr) -> Type: 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) method: Optional[str] = MIDAS_UNARY_METHODS.get(expr.operator.type)
if method is None: if method is None:
self.logger.warning(f"Unsupported operator {expr.operator.lexeme}") self.logger.warning(f"Unsupported operator {expr.operator.lexeme}")

View File

@@ -686,6 +686,11 @@ class PythonTyper(
return UnknownType() return UnknownType()
def visit_unary_expr(self, expr: p.UnaryExpr) -> Type: 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__) method: Optional[str] = PY_UNARY_METHODS.get(expr.operator.__class__)
if method is None: if method is None:
self.logger.warning(f"Unsupported operator {expr.operator}") self.logger.warning(f"Unsupported operator {expr.operator}")

View File

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

View File

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

View File

@@ -487,12 +487,12 @@ class MidasParser(Parser[list[Stmt]]):
"""Parse a unary expression """Parse a unary expression
A unary consists of a call expression (see :func:`call`) optionally 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: Returns:
Expr: the parsed expression Expr: the parsed expression
""" """
if self.match(TokenType.PLUS, TokenType.MINUS): if self.match(TokenType.PLUS, TokenType.MINUS, TokenType.BANG):
operator: Token = self.previous() operator: Token = self.previous()
right: Expr = self.unary() right: Expr = self.unary()
location: Location = Location.span(operator.get_location(), right.location) location: Location = Location.span(operator.get_location(), right.location)