Compare commits
2
Commits
54919a3565
...
c1ca254b51
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c1ca254b51
|
||
|
|
0bb862a1db
|
@@ -9,3 +9,5 @@ d = True
|
|||||||
e = d + d
|
e = d + d
|
||||||
|
|
||||||
f: float = a
|
f: float = a
|
||||||
|
|
||||||
|
f = -f
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ type Second = float
|
|||||||
type MeterPerSecond = float
|
type MeterPerSecond = float
|
||||||
|
|
||||||
extend Meter {
|
extend Meter {
|
||||||
op __add__(Meter) -> Meter
|
def __add__: fn(Meter, /) -> Meter
|
||||||
op __sub__(Meter) -> Meter
|
def __sub__: fn(Meter, /) -> Meter
|
||||||
op __truediv__(Second) -> MeterPerSecond
|
def __truediv__: fn(Second, /) -> MeterPerSecond
|
||||||
}
|
}
|
||||||
|
|
||||||
extend Second {
|
extend Second {
|
||||||
op __add__(Second) -> Second
|
def __add__: fn(Second, /) -> Second
|
||||||
op __sub__(Second) -> Second
|
def __sub__: fn(Second, /) -> Second
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-8
@@ -105,24 +105,32 @@ class MidasTyper(m.Stmt.Visitor[None], m.Expr.Visitor[None], m.Type.Visitor[Type
|
|||||||
member.kind == m.MemberKind.METHOD,
|
member.kind == m.MemberKind.METHOD,
|
||||||
)
|
)
|
||||||
|
|
||||||
def visit_predicate_stmt(self, stmt: m.PredicateStmt) -> None: ...
|
def visit_predicate_stmt(self, stmt: m.PredicateStmt) -> None:
|
||||||
|
self.reporter.warning(stmt.location, "PredicateStmt not yet supported")
|
||||||
|
|
||||||
def visit_logical_expr(self, expr: m.LogicalExpr) -> None: ...
|
def visit_logical_expr(self, expr: m.LogicalExpr) -> None:
|
||||||
|
self.reporter.warning(expr.location, "LogicalExpr not yet supported")
|
||||||
|
|
||||||
def visit_binary_expr(self, expr: m.BinaryExpr) -> None: ...
|
def visit_binary_expr(self, expr: m.BinaryExpr) -> None:
|
||||||
|
self.reporter.warning(expr.location, "BinaryExpr not yet supported")
|
||||||
|
|
||||||
def visit_unary_expr(self, expr: m.UnaryExpr) -> None: ...
|
def visit_unary_expr(self, expr: m.UnaryExpr) -> None:
|
||||||
|
self.reporter.warning(expr.location, "UnaryExpr not yet supported")
|
||||||
|
|
||||||
def visit_get_expr(self, expr: m.GetExpr) -> None: ...
|
def visit_get_expr(self, expr: m.GetExpr) -> None:
|
||||||
|
self.reporter.warning(expr.location, "GetExpr not yet supported")
|
||||||
|
|
||||||
def visit_variable_expr(self, expr: m.VariableExpr) -> None: ...
|
def visit_variable_expr(self, expr: m.VariableExpr) -> None:
|
||||||
|
self.reporter.warning(expr.location, "VariableExpr not yet supported")
|
||||||
|
|
||||||
def visit_grouping_expr(self, expr: m.GroupingExpr) -> None:
|
def visit_grouping_expr(self, expr: m.GroupingExpr) -> None:
|
||||||
return expr.expr.accept(self)
|
return expr.expr.accept(self)
|
||||||
|
|
||||||
def visit_literal_expr(self, expr: m.LiteralExpr) -> None: ...
|
def visit_literal_expr(self, expr: m.LiteralExpr) -> None:
|
||||||
|
self.reporter.warning(expr.location, "LiteralExpr not yet supported")
|
||||||
|
|
||||||
def visit_wildcard_expr(self, expr: m.WildcardExpr) -> None: ...
|
def visit_wildcard_expr(self, expr: m.WildcardExpr) -> None:
|
||||||
|
self.reporter.warning(expr.location, "WildcardExpr not yet supported")
|
||||||
|
|
||||||
def visit_named_type(self, type: m.NamedType) -> Type:
|
def visit_named_type(self, type: m.NamedType) -> Type:
|
||||||
name: str = type.name.lexeme
|
name: str = type.name.lexeme
|
||||||
|
|||||||
@@ -29,3 +29,10 @@ COMPARATOR_METHODS: dict[Type[ast.cmpop], str] = {
|
|||||||
# ast.In: "__in__",
|
# ast.In: "__in__",
|
||||||
# ast.NotIn: "__notin__",
|
# ast.NotIn: "__notin__",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UNARY_METHODS: dict[Type[ast.unaryop], str] = {
|
||||||
|
ast.Invert: "__invert__",
|
||||||
|
# ast.Not: "",
|
||||||
|
ast.UAdd: "__pos__",
|
||||||
|
ast.USub: "__neg__",
|
||||||
|
}
|
||||||
|
|||||||
+51
-5
@@ -6,7 +6,7 @@ from typing import Optional
|
|||||||
import midas.ast.python as p
|
import midas.ast.python as p
|
||||||
from midas.ast.location import Location
|
from midas.ast.location import Location
|
||||||
from midas.checker.environment import Environment
|
from midas.checker.environment import Environment
|
||||||
from midas.checker.operators import COMPARATOR_METHODS, OPERATOR_METHODS
|
from midas.checker.operators import COMPARATOR_METHODS, OPERATOR_METHODS, UNARY_METHODS
|
||||||
from midas.checker.registry import TypesRegistry
|
from midas.checker.registry import TypesRegistry
|
||||||
from midas.checker.reporter import FileReporter, Reporter
|
from midas.checker.reporter import FileReporter, Reporter
|
||||||
from midas.checker.resolver import Resolver
|
from midas.checker.resolver import Resolver
|
||||||
@@ -375,7 +375,38 @@ class PythonTyper(
|
|||||||
self.reporter.warning(location, f"Unsupported operation {operation}")
|
self.reporter.warning(location, f"Unsupported operation {operation}")
|
||||||
return UnknownType()
|
return UnknownType()
|
||||||
|
|
||||||
def visit_unary_expr(self, expr: p.UnaryExpr) -> Type: ...
|
def visit_unary_expr(self, expr: p.UnaryExpr) -> Type:
|
||||||
|
method: Optional[str] = UNARY_METHODS.get(expr.operator.__class__)
|
||||||
|
if method is None:
|
||||||
|
self.logger.warning(f"Unsupported operator {expr.operator}")
|
||||||
|
self.reporter.warning(
|
||||||
|
expr.location, f"Unsupported operator {expr.operator}"
|
||||||
|
)
|
||||||
|
return UnknownType()
|
||||||
|
|
||||||
|
operand: Type = self.type_of(expr.right)
|
||||||
|
operation: Optional[Type] = self.types.lookup_member(operand, method)
|
||||||
|
if operation is None:
|
||||||
|
self.reporter.error(
|
||||||
|
expr.location,
|
||||||
|
f"Undefined operation {method} for {operand}",
|
||||||
|
)
|
||||||
|
return UnknownType()
|
||||||
|
|
||||||
|
match operation:
|
||||||
|
case Function() as function:
|
||||||
|
if not self._is_unary_function(function):
|
||||||
|
self.reporter.error(
|
||||||
|
expr.location,
|
||||||
|
f"Wrong definition of unary operation. Expected function with 0 parameters, got {function}",
|
||||||
|
)
|
||||||
|
return UnknownType()
|
||||||
|
return function.returns
|
||||||
|
case _:
|
||||||
|
self.reporter.warning(
|
||||||
|
expr.location, f"Unsupported operation {operation}"
|
||||||
|
)
|
||||||
|
return UnknownType()
|
||||||
|
|
||||||
def visit_call_expr(self, expr: p.CallExpr) -> Type:
|
def visit_call_expr(self, expr: p.CallExpr) -> Type:
|
||||||
callee: Type = self.type_of(expr.callee)
|
callee: Type = self.type_of(expr.callee)
|
||||||
@@ -494,11 +525,17 @@ class PythonTyper(
|
|||||||
return self.types.apply_generic(base, [param])
|
return self.types.apply_generic(base, [param])
|
||||||
return base
|
return base
|
||||||
|
|
||||||
def visit_constraint_type(self, node: p.ConstraintType) -> Type: ...
|
def visit_constraint_type(self, node: p.ConstraintType) -> Type:
|
||||||
|
self.reporter.warning(node.location, "ConstraintType not yet supported")
|
||||||
|
return UnknownType()
|
||||||
|
|
||||||
def visit_frame_column(self, node: p.FrameColumn) -> Type: ...
|
def visit_frame_column(self, node: p.FrameColumn) -> Type:
|
||||||
|
self.reporter.warning(node.location, "FrameColumn not yet supported")
|
||||||
|
return UnknownType()
|
||||||
|
|
||||||
def visit_frame_type(self, node: p.FrameType) -> Type: ...
|
def visit_frame_type(self, node: p.FrameType) -> Type:
|
||||||
|
self.reporter.warning(node.location, "FrameType not yet supported")
|
||||||
|
return UnknownType()
|
||||||
|
|
||||||
def map_call_arguments(
|
def map_call_arguments(
|
||||||
self, function: Function, call: p.CallExpr
|
self, function: Function, call: p.CallExpr
|
||||||
@@ -625,3 +662,12 @@ class PythonTyper(
|
|||||||
if len(function.kw_args) != 0:
|
if len(function.kw_args) != 0:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def _is_unary_function(self, function: Function) -> bool:
|
||||||
|
if len(function.pos_args) != 0:
|
||||||
|
return False
|
||||||
|
if len(function.args) != 0:
|
||||||
|
return False
|
||||||
|
if len(function.kw_args) != 0:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|||||||
Reference in New Issue
Block a user