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.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}")
|
||||||
|
|||||||
@@ -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}")
|
||||||
|
|||||||
@@ -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 ".":
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user