Compare commits
6 Commits
main
...
1aff8e574d
| Author | SHA1 | Date | |
|---|---|---|---|
|
1aff8e574d
|
|||
|
498e05f963
|
|||
|
a9a4d6d4c1
|
|||
|
60144f8671
|
|||
|
bbede34a84
|
|||
|
16d6e1b603
|
@@ -157,11 +157,6 @@ class ListExpr:
|
|||||||
items: list[Expr]
|
items: list[Expr]
|
||||||
|
|
||||||
|
|
||||||
class DictExpr:
|
|
||||||
keys: list[Optional[Expr]]
|
|
||||||
values: list[Expr]
|
|
||||||
|
|
||||||
|
|
||||||
class SubscriptExpr:
|
class SubscriptExpr:
|
||||||
object: Expr
|
object: Expr
|
||||||
index: Expr
|
index: Expr
|
||||||
|
|||||||
@@ -745,27 +745,6 @@ class PythonAstPrinter(
|
|||||||
self._mark_last()
|
self._mark_last()
|
||||||
item.accept(self)
|
item.accept(self)
|
||||||
|
|
||||||
def visit_dict_expr(self, expr: p.DictExpr) -> None:
|
|
||||||
self._write_line("DictExpr")
|
|
||||||
with self._child_level():
|
|
||||||
self._write_line("keys")
|
|
||||||
with self._child_level():
|
|
||||||
for i, key in enumerate(expr.keys):
|
|
||||||
self._idx = i
|
|
||||||
if i == len(expr.keys) - 1:
|
|
||||||
self._mark_last()
|
|
||||||
if key is None:
|
|
||||||
self._write_line("None")
|
|
||||||
else:
|
|
||||||
key.accept(self)
|
|
||||||
self._write_line("values", last=True)
|
|
||||||
with self._child_level():
|
|
||||||
for i, value in enumerate(expr.values):
|
|
||||||
self._idx = i
|
|
||||||
if i == len(expr.values) - 1:
|
|
||||||
self._mark_last()
|
|
||||||
value.accept(self)
|
|
||||||
|
|
||||||
def visit_subscript_expr(self, expr: p.SubscriptExpr) -> None:
|
def visit_subscript_expr(self, expr: p.SubscriptExpr) -> None:
|
||||||
self._write_line("SubscriptExpr")
|
self._write_line("SubscriptExpr")
|
||||||
with self._child_level():
|
with self._child_level():
|
||||||
|
|||||||
@@ -259,9 +259,6 @@ class Expr(ABC):
|
|||||||
@abstractmethod
|
@abstractmethod
|
||||||
def visit_list_expr(self, expr: ListExpr) -> T: ...
|
def visit_list_expr(self, expr: ListExpr) -> T: ...
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def visit_dict_expr(self, expr: DictExpr) -> T: ...
|
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def visit_subscript_expr(self, expr: SubscriptExpr) -> T: ...
|
def visit_subscript_expr(self, expr: SubscriptExpr) -> T: ...
|
||||||
|
|
||||||
@@ -373,15 +370,6 @@ class ListExpr(Expr):
|
|||||||
return visitor.visit_list_expr(self)
|
return visitor.visit_list_expr(self)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
|
||||||
class DictExpr(Expr):
|
|
||||||
keys: list[Optional[Expr]]
|
|
||||||
values: list[Expr]
|
|
||||||
|
|
||||||
def accept(self, visitor: Expr.Visitor[T]) -> T:
|
|
||||||
return visitor.visit_dict_expr(self)
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class SubscriptExpr(Expr):
|
class SubscriptExpr(Expr):
|
||||||
object: Expr
|
object: Expr
|
||||||
|
|||||||
@@ -150,32 +150,3 @@ extend list[T] {
|
|||||||
|
|
||||||
prop __doc__: str
|
prop __doc__: str
|
||||||
}
|
}
|
||||||
|
|
||||||
extend dict[K, V] {
|
|
||||||
def copy: fn() -> dict[K, V]
|
|
||||||
def keys: fn() -> list[K] // TODO: use builtin types
|
|
||||||
def values: fn() -> list[V] // TODO: use builtin types
|
|
||||||
// def items: fn() -> list[tuple[K, V]] // TODO: use builtin types
|
|
||||||
|
|
||||||
// def get: fn(key: K, default: None = None, /) -> V | None
|
|
||||||
def get: fn(key: K, default: V, /) -> V
|
|
||||||
// def get: fn[T](key: K, default: T, /) -> V | T
|
|
||||||
def pop: fn(key: K, /) -> V
|
|
||||||
def pop: fn(key: K, default: V, /) -> V
|
|
||||||
// def pop: fn[T](key: K, default: T, /) -> V | T
|
|
||||||
def __len__: fn() -> int
|
|
||||||
def __getitem__: fn(key: K, /) -> V
|
|
||||||
def __setitem__: fn(key: K, value: V, /) -> None
|
|
||||||
def __delitem__: fn(key: K, /) -> None
|
|
||||||
// def __iter__: fn() -> Iterator[K]
|
|
||||||
def __eq__: fn(value: object, /) -> bool
|
|
||||||
// def __reversed__: fn() -> Iterator[K]
|
|
||||||
|
|
||||||
def __or__: fn(value: dict[K, V], /) -> dict[K, V]
|
|
||||||
// def __or__: fn[K2, V2](value: dict[K2, V2], /) -> dict[K | K2, V | V2]
|
|
||||||
def __ror__: fn(value: dict[K, V], /) -> dict[K, V]
|
|
||||||
// def __ror__: fn[K2, V2](value: dict[K2, V2], /) -> dict[K | K2, V | V2]
|
|
||||||
// def __ior__: fn(value: SupportsKeysAndGetItem[K, V], /) -> dict[K, V]
|
|
||||||
// def __ior__: fn(value: Iterable[tuple[K, V]], /) -> dict[K, V]
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -39,14 +39,3 @@ def define_builtins(reg: TypesRegistry):
|
|||||||
body=BaseType(name="list"),
|
body=BaseType(name="list"),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
dict = reg.define_type(
|
|
||||||
"dict",
|
|
||||||
GenericType(
|
|
||||||
name="dict",
|
|
||||||
params=[
|
|
||||||
TypeVar(name="K", bound=None),
|
|
||||||
TypeVar(name="V", bound=None),
|
|
||||||
],
|
|
||||||
body=BaseType(name="dict"),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ class Preamble(Environment):
|
|||||||
# TODO: more specific arg types
|
# TODO: more specific arg types
|
||||||
self._def_function(
|
self._def_function(
|
||||||
name=name,
|
name=name,
|
||||||
pos=[Param("object", TopType(), required=False)],
|
pos=[Param("object", TopType())],
|
||||||
returns=self._types.get_type(name),
|
returns=self._types.get_type(name),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -552,46 +552,6 @@ class PythonTyper(
|
|||||||
)
|
)
|
||||||
return self.types.apply_generic(list_type, [UnknownType()])
|
return self.types.apply_generic(list_type, [UnknownType()])
|
||||||
|
|
||||||
def visit_dict_expr(self, expr: p.DictExpr) -> Type:
|
|
||||||
dict_type: Type = self.types.get_type("dict")
|
|
||||||
|
|
||||||
key_types: list[Type] = []
|
|
||||||
value_types: list[Type] = []
|
|
||||||
for key, value in zip(expr.keys, expr.values):
|
|
||||||
if key is None:
|
|
||||||
self.reporter.warning(
|
|
||||||
value.location, "Dictionary unpacking not supported"
|
|
||||||
)
|
|
||||||
continue
|
|
||||||
key_types.append(self.type_of(key))
|
|
||||||
value_types.append(self.type_of(value))
|
|
||||||
|
|
||||||
key_types = self.types.reduce_types(key_types)
|
|
||||||
value_types = self.types.reduce_types(value_types)
|
|
||||||
|
|
||||||
if len(key_types) == 0 or len(value_types) == 0:
|
|
||||||
return dict_type
|
|
||||||
|
|
||||||
key_type: Type = UnknownType()
|
|
||||||
value_type: Type = UnknownType()
|
|
||||||
|
|
||||||
if len(key_types) == 1:
|
|
||||||
key_type = key_types[0]
|
|
||||||
else:
|
|
||||||
self.reporter.error(
|
|
||||||
expr.location,
|
|
||||||
f"Heterogeneous dict keys: {key_types}",
|
|
||||||
)
|
|
||||||
|
|
||||||
if len(value_types) == 1:
|
|
||||||
value_type = value_types[0]
|
|
||||||
else:
|
|
||||||
self.reporter.error(
|
|
||||||
expr.location,
|
|
||||||
f"Heterogeneous dict values: {value_types}",
|
|
||||||
)
|
|
||||||
return self.types.apply_generic(dict_type, [key_type, value_type])
|
|
||||||
|
|
||||||
def visit_subscript_expr(self, expr: p.SubscriptExpr) -> Type:
|
def visit_subscript_expr(self, expr: p.SubscriptExpr) -> Type:
|
||||||
object: Type = self.type_of(expr.object)
|
object: Type = self.type_of(expr.object)
|
||||||
operation: Optional[Type] = self.types.lookup_member(object, "__getitem__")
|
operation: Optional[Type] = self.types.lookup_member(object, "__getitem__")
|
||||||
|
|||||||
@@ -213,13 +213,6 @@ class Resolver(p.Stmt.Visitor[None], p.Expr.Visitor[None]):
|
|||||||
for item in expr.items:
|
for item in expr.items:
|
||||||
self.resolve(item)
|
self.resolve(item)
|
||||||
|
|
||||||
def visit_dict_expr(self, expr: p.DictExpr) -> None:
|
|
||||||
for key in expr.keys:
|
|
||||||
if key is not None:
|
|
||||||
self.resolve(key)
|
|
||||||
for value in expr.values:
|
|
||||||
self.resolve(value)
|
|
||||||
|
|
||||||
def visit_subscript_expr(self, expr: p.SubscriptExpr) -> None:
|
def visit_subscript_expr(self, expr: p.SubscriptExpr) -> None:
|
||||||
self.resolve(expr.object)
|
self.resolve(expr.object)
|
||||||
self.resolve(expr.index)
|
self.resolve(expr.index)
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ from dataclasses import dataclass, field
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
import midas.ast.python as p
|
|
||||||
from midas.ast.location import Location
|
from midas.ast.location import Location
|
||||||
|
import midas.ast.python as p
|
||||||
from midas.checker.types import (
|
from midas.checker.types import (
|
||||||
AliasType,
|
AliasType,
|
||||||
AppliedType,
|
AppliedType,
|
||||||
@@ -139,12 +139,6 @@ class Generator(p.Stmt.Visitor[ast.stmt], p.Expr.Visitor[ast.expr]):
|
|||||||
elts=[item.accept(self) for item in expr.items],
|
elts=[item.accept(self) for item in expr.items],
|
||||||
)
|
)
|
||||||
|
|
||||||
def visit_dict_expr(self, expr: p.DictExpr) -> ast.expr:
|
|
||||||
return ast.Dict(
|
|
||||||
keys=[key.accept(self) if key is not None else None for key in expr.keys],
|
|
||||||
values=[value.accept(self) for value in expr.values],
|
|
||||||
)
|
|
||||||
|
|
||||||
def visit_subscript_expr(self, expr: p.SubscriptExpr) -> ast.expr:
|
def visit_subscript_expr(self, expr: p.SubscriptExpr) -> ast.expr:
|
||||||
return ast.Subscript(
|
return ast.Subscript(
|
||||||
value=expr.object.accept(self),
|
value=expr.object.accept(self),
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ from midas.ast.python import (
|
|||||||
CastExpr,
|
CastExpr,
|
||||||
CompareExpr,
|
CompareExpr,
|
||||||
ConstraintType,
|
ConstraintType,
|
||||||
DictExpr,
|
|
||||||
Expr,
|
Expr,
|
||||||
ExpressionStmt,
|
ExpressionStmt,
|
||||||
ForStmt,
|
ForStmt,
|
||||||
@@ -448,16 +447,6 @@ class PythonParser:
|
|||||||
items=[self.parse_expr(item) for item in items],
|
items=[self.parse_expr(item) for item in items],
|
||||||
)
|
)
|
||||||
|
|
||||||
case ast.Dict(keys=keys, values=values):
|
|
||||||
return DictExpr(
|
|
||||||
location=location,
|
|
||||||
keys=[
|
|
||||||
self.parse_expr(key) if key is not None else None
|
|
||||||
for key in keys
|
|
||||||
],
|
|
||||||
values=[self.parse_expr(value) for value in values],
|
|
||||||
)
|
|
||||||
|
|
||||||
case ast.Subscript(value=value, slice=index):
|
case ast.Subscript(value=value, slice=index):
|
||||||
return SubscriptExpr(
|
return SubscriptExpr(
|
||||||
location=location,
|
location=location,
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ from midas.ast.python import (
|
|||||||
CastExpr,
|
CastExpr,
|
||||||
CompareExpr,
|
CompareExpr,
|
||||||
ConstraintType,
|
ConstraintType,
|
||||||
DictExpr,
|
|
||||||
Expr,
|
Expr,
|
||||||
ExpressionStmt,
|
ExpressionStmt,
|
||||||
ForStmt,
|
ForStmt,
|
||||||
@@ -279,13 +278,6 @@ class PythonAstJsonSerializer(
|
|||||||
"items": [item.accept(self) for item in expr.items],
|
"items": [item.accept(self) for item in expr.items],
|
||||||
}
|
}
|
||||||
|
|
||||||
def visit_dict_expr(self, expr: DictExpr) -> dict:
|
|
||||||
return {
|
|
||||||
"_type": "DictExpr",
|
|
||||||
"keys": [self._serialize_optional(key) for key in expr.keys],
|
|
||||||
"values": self._serialize_list(expr.values),
|
|
||||||
}
|
|
||||||
|
|
||||||
def visit_subscript_expr(self, expr: SubscriptExpr) -> dict:
|
def visit_subscript_expr(self, expr: SubscriptExpr) -> dict:
|
||||||
return {
|
return {
|
||||||
"_type": "SubscriptExpr",
|
"_type": "SubscriptExpr",
|
||||||
|
|||||||
Reference in New Issue
Block a user