feat: handle not operator
This commit is contained in:
@@ -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}")
|
||||
|
||||
@@ -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}")
|
||||
|
||||
@@ -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 ".":
|
||||
|
||||
@@ -36,6 +36,7 @@ class TokenType(Enum):
|
||||
EQUAL = auto()
|
||||
EQUAL_EQUAL = auto()
|
||||
BANG_EQUAL = auto()
|
||||
BANG = auto()
|
||||
|
||||
# Literals
|
||||
IDENTIFIER = auto()
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user