feat(checker): define members on builtin types
This commit is contained in:
152
midas/checker/builtins.midas
Normal file
152
midas/checker/builtins.midas
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
extend float {
|
||||||
|
def hex: fn() -> str
|
||||||
|
def is_integer: fn() -> bool
|
||||||
|
prop real: float
|
||||||
|
prop imag: float
|
||||||
|
def conjugate: fn() -> float
|
||||||
|
def __add__: fn(value: float, /) -> float
|
||||||
|
def __sub__: fn(value: float, /) -> float
|
||||||
|
def __mul__: fn(value: float, /) -> float
|
||||||
|
def __floordiv__: fn(value: float, /) -> float
|
||||||
|
def __truediv__: fn(value: float, /) -> float
|
||||||
|
def __mod__: fn(value: float, /) -> float
|
||||||
|
// def __divmod__: fn(value: float, /) -> tuple[float, float]
|
||||||
|
|
||||||
|
def __pow__: fn(value: int, /) -> float
|
||||||
|
// positive __value -> float; negative __value -> complex
|
||||||
|
// return type must be Any as `float | complex` causes too many false-positive errors
|
||||||
|
def __pow__: fn(value: float, /) -> Any
|
||||||
|
def __radd__: fn(value: float, /) -> float
|
||||||
|
def __rsub__: fn(value: float, /) -> float
|
||||||
|
def __rmul__: fn(value: float, /) -> float
|
||||||
|
def __rfloordiv__: fn(value: float, /) -> float
|
||||||
|
def __rtruediv__: fn(value: float, /) -> float
|
||||||
|
def __rmod__: fn(value: float, /) -> float
|
||||||
|
// def __rdivmod__: fn(value: float, /) -> tuple[float, float]
|
||||||
|
// def __rpow__: fn(value: _PositiveInteger, mod: None = None, /) -> float
|
||||||
|
// def __rpow__: fn(value: _NegativeInteger, mod: None = None, /) -> complex
|
||||||
|
// Returning `complex` for the general case gives too many false-positive errors.
|
||||||
|
// def __rpow__: fn(value: float, mod: None = None, /) -> Any
|
||||||
|
// def __getnewargs__: fn() -> tuple[float]
|
||||||
|
def __trunc__: fn() -> int
|
||||||
|
def __ceil__: fn() -> int
|
||||||
|
def __floor__: fn() -> int
|
||||||
|
def __round__: fn(ndigits: None?, /) -> int
|
||||||
|
def __round__: fn(ndigits: int, /) -> float
|
||||||
|
def __eq__: fn(value: object, /) -> bool
|
||||||
|
def __ne__: fn(value: object, /) -> bool
|
||||||
|
def __lt__: fn(value: float, /) -> bool
|
||||||
|
def __le__: fn(value: float, /) -> bool
|
||||||
|
def __gt__: fn(value: float, /) -> bool
|
||||||
|
def __ge__: fn(value: float, /) -> bool
|
||||||
|
def __neg__: fn() -> float
|
||||||
|
def __pos__: fn() -> float
|
||||||
|
def __int__: fn() -> int
|
||||||
|
def __float__: fn() -> float
|
||||||
|
def __abs__: fn() -> float
|
||||||
|
def __hash__: fn() -> int
|
||||||
|
def __bool__: fn() -> bool
|
||||||
|
def __format__: fn(format_spec: str, /) -> str
|
||||||
|
}
|
||||||
|
|
||||||
|
extend int {
|
||||||
|
prop real: int
|
||||||
|
prop imag: int
|
||||||
|
prop numerator: int
|
||||||
|
prop denominator: int
|
||||||
|
def conjugate: fn() -> int
|
||||||
|
def bit_length: fn() -> int
|
||||||
|
def bit_count: fn() -> int
|
||||||
|
def to_bytes: fn(length: int?, byteorder: str?, *, signed: bool?) -> bytes
|
||||||
|
|
||||||
|
def __add__: fn(value: int, /) -> int
|
||||||
|
def __sub__: fn(value: int, /) -> int
|
||||||
|
def __mul__: fn(value: int, /) -> int
|
||||||
|
def __floordiv__: fn(value: int, /) -> int
|
||||||
|
def __truediv__: fn(value: int, /) -> float
|
||||||
|
def __mod__: fn(value: int, /) -> int
|
||||||
|
// def __divmod__: fn(value: int, /) -> tuple[int, int]
|
||||||
|
def __radd__: fn(value: int, /) -> int
|
||||||
|
def __rsub__: fn(value: int, /) -> int
|
||||||
|
def __rmul__: fn(value: int, /) -> int
|
||||||
|
def __rfloordiv__: fn(value: int, /) -> int
|
||||||
|
def __rtruediv__: fn(value: int, /) -> float
|
||||||
|
def __rmod__: fn(value: int, /) -> int
|
||||||
|
// def __rdivmod__: fn(value: int, /) -> tuple[int, int]
|
||||||
|
def __pow__: fn(value: int, /) -> int
|
||||||
|
// def __pow__: fn(value: _PositiveInteger, mod: None = None, /) -> int
|
||||||
|
// def __pow__: fn(value: _NegativeInteger, mod: None = None, /) -> float
|
||||||
|
// positive __value -> int; negative __value -> float
|
||||||
|
// return type must be Any as `int | float` causes too many false-positive errors
|
||||||
|
// def __pow__: fn(value: int, mod: None = None, /) -> Any
|
||||||
|
// def __pow__: fn(value: int, mod: int, /) -> int
|
||||||
|
def __rpow__: fn(value: int, /) -> Any
|
||||||
|
def __and__: fn(value: int, /) -> int
|
||||||
|
def __or__: fn(value: int, /) -> int
|
||||||
|
def __xor__: fn(value: int, /) -> int
|
||||||
|
def __lshift__: fn(value: int, /) -> int
|
||||||
|
def __rshift__: fn(value: int, /) -> int
|
||||||
|
def __rand__: fn(value: int, /) -> int
|
||||||
|
def __ror__: fn(value: int, /) -> int
|
||||||
|
def __rxor__: fn(value: int, /) -> int
|
||||||
|
def __rlshift__: fn(value: int, /) -> int
|
||||||
|
def __rrshift__: fn(value: int, /) -> int
|
||||||
|
def __neg__: fn() -> int
|
||||||
|
def __pos__: fn() -> int
|
||||||
|
def __invert__: fn() -> int
|
||||||
|
def __trunc__: fn() -> int
|
||||||
|
def __ceil__: fn() -> int
|
||||||
|
def __floor__: fn() -> int
|
||||||
|
def __round__: fn(ndigits: None?, /) -> int
|
||||||
|
def __round__: fn(ndigits: int, /) -> int
|
||||||
|
|
||||||
|
// def __getnewargs__: fn() -> tuple[int]
|
||||||
|
def __eq__: fn(value: object, /) -> bool
|
||||||
|
def __ne__: fn(value: object, /) -> bool
|
||||||
|
def __lt__: fn(value: int, /) -> bool
|
||||||
|
def __le__: fn(value: int, /) -> bool
|
||||||
|
def __gt__: fn(value: int, /) -> bool
|
||||||
|
def __ge__: fn(value: int, /) -> bool
|
||||||
|
def __float__: fn() -> float
|
||||||
|
def __int__: fn() -> int
|
||||||
|
def __abs__: fn() -> int
|
||||||
|
def __hash__: fn() -> int
|
||||||
|
def __bool__: fn() -> bool
|
||||||
|
def __index__: fn() -> int
|
||||||
|
def __format__: fn(format_spec: str, /) -> str
|
||||||
|
}
|
||||||
|
|
||||||
|
extend list[T] {
|
||||||
|
def copy: fn () -> list[T]
|
||||||
|
def append: fn (object: T, /) -> None
|
||||||
|
def extend: fn (iterable: list[T], /) -> None
|
||||||
|
def pop: fn (index: int?, /) -> T
|
||||||
|
def index: fn (value: T, start: int?, stop: int?, /) -> int
|
||||||
|
def count: fn (value: T, /) -> int
|
||||||
|
def insert: fn (index: int, object: T, /) -> None
|
||||||
|
def remove: fn (value: T, /) -> None
|
||||||
|
def sort: fn (*, reverse: bool?) -> None
|
||||||
|
def __len__: fn () -> int
|
||||||
|
// def __iter__: fn () -> Iterator[T]
|
||||||
|
def __getitem__: fn (i: int, /) -> T
|
||||||
|
//__getitem__: fn (s: slice, /) -> list[T]
|
||||||
|
def __setitem__: fn (key: int, value: T, /) -> None
|
||||||
|
//__setitem__: fn (key: slice, value: list[T], /) -> None
|
||||||
|
def __delitem__: fn (key: int, /) -> None
|
||||||
|
// def __delitem__: fn (key: slice, /) -> None
|
||||||
|
// def __add__: fn[S <: T] (value: list[S], /) -> list[T]
|
||||||
|
def __add__: fn (value: list[T], /) -> list[T]
|
||||||
|
def __iadd__: fn (value: list[T], /) -> list[T]
|
||||||
|
def __mul__: fn (value: int, /) -> list[T]
|
||||||
|
def __rmul__: fn (value: int, /) -> list[T]
|
||||||
|
def __imul__: fn (value: int, /) -> list[T]
|
||||||
|
def __contains__: fn (key: object, /) -> bool
|
||||||
|
// def __reversed__: fn (self) -> Iterator[_T]
|
||||||
|
def __gt__: fn (value: list[T], /) -> bool
|
||||||
|
def __ge__: fn (value: list[T], /) -> bool
|
||||||
|
def __lt__: fn (value: list[T], /) -> bool
|
||||||
|
def __le__: fn (value: list[T], /) -> bool
|
||||||
|
def __eq__: fn (value: object, /) -> bool
|
||||||
|
|
||||||
|
prop __doc__: str
|
||||||
|
}
|
||||||
@@ -4,8 +4,6 @@ from typing import TYPE_CHECKING
|
|||||||
|
|
||||||
from midas.checker.types import (
|
from midas.checker.types import (
|
||||||
BaseType,
|
BaseType,
|
||||||
ComplexType,
|
|
||||||
Function,
|
|
||||||
GenericType,
|
GenericType,
|
||||||
Type,
|
Type,
|
||||||
TypeVar,
|
TypeVar,
|
||||||
@@ -43,70 +41,17 @@ def basic_op(reg: TypesRegistry, type: Type, op: str):
|
|||||||
def define_builtins(reg: TypesRegistry):
|
def define_builtins(reg: TypesRegistry):
|
||||||
"""Define builtin types and operations"""
|
"""Define builtin types and operations"""
|
||||||
unit = reg.define_type("None", UnitType())
|
unit = reg.define_type("None", UnitType())
|
||||||
|
object = reg.define_type("object", BaseType(name="object"))
|
||||||
bool = reg.define_type("bool", BaseType(name="bool"))
|
bool = reg.define_type("bool", BaseType(name="bool"))
|
||||||
int = reg.define_type("int", BaseType(name="int"))
|
int = reg.define_type("int", BaseType(name="int"))
|
||||||
float = reg.define_type("float", BaseType(name="float"))
|
float = reg.define_type("float", BaseType(name="float"))
|
||||||
str = reg.define_type("str", BaseType(name="str"))
|
str = reg.define_type("str", BaseType(name="str"))
|
||||||
|
|
||||||
basic_op(reg, int, "__add__") # int + int = int
|
|
||||||
basic_op(reg, int, "__sub__") # int - int = int
|
|
||||||
basic_op(reg, int, "__mul__") # int * int = int
|
|
||||||
basic_op(reg, int, "__pow__") # int ** int = int
|
|
||||||
basic_op(reg, int, "__mod__") # int % int = int
|
|
||||||
basic_op(reg, int, "__and__") # int & int = int
|
|
||||||
basic_op(reg, int, "__or__") # int | int = int
|
|
||||||
basic_op(reg, int, "__xor__") # int ^ int = int
|
|
||||||
op(reg, int, "__lt__", int, bool) # int < int = bool
|
|
||||||
op(reg, int, "__gt__", int, bool) # int > int = bool
|
|
||||||
op(reg, int, "__le__", int, bool) # int <= int = bool
|
|
||||||
op(reg, int, "__ge__", int, bool) # int >= int = bool
|
|
||||||
op(reg, int, "__eq__", int, bool) # int == int = bool
|
|
||||||
basic_op(reg, float, "__add__") # float + float = float
|
|
||||||
basic_op(reg, float, "__sub__") # float - float = float
|
|
||||||
basic_op(reg, float, "__mul__") # float * float = float
|
|
||||||
basic_op(reg, float, "__truediv__") # float / float = float
|
|
||||||
op(reg, float, "__lt__", float, bool) # float < float = bool
|
|
||||||
op(reg, float, "__gt__", float, bool) # float > float = bool
|
|
||||||
op(reg, float, "__le__", float, bool) # float <= float = bool
|
|
||||||
op(reg, float, "__ge__", float, bool) # float >= float = bool
|
|
||||||
op(reg, float, "__eq__", float, bool) # float == float = bool
|
|
||||||
basic_op(reg, str, "__add__") # str + str = str
|
|
||||||
op(reg, str, "__eq__", str, bool) # str == str = bool
|
|
||||||
|
|
||||||
op(reg, int, "__lt__", float, bool) # int < float = bool
|
|
||||||
op(reg, int, "__gt__", float, bool) # int > float = bool
|
|
||||||
op(reg, int, "__le__", float, bool) # int <= float = bool
|
|
||||||
op(reg, int, "__ge__", float, bool) # int >= float = bool
|
|
||||||
op(reg, int, "__eq__", float, bool) # int == float = bool
|
|
||||||
|
|
||||||
op(reg, float, "__lt__", int, bool) # float < int = bool
|
|
||||||
op(reg, float, "__gt__", int, bool) # float > int = bool
|
|
||||||
op(reg, float, "__le__", int, bool) # float <= int = bool
|
|
||||||
op(reg, float, "__ge__", int, bool) # float >= int = bool
|
|
||||||
op(reg, float, "__eq__", int, bool) # float == int = bool
|
|
||||||
|
|
||||||
list = reg.define_type(
|
list = reg.define_type(
|
||||||
"list",
|
"list",
|
||||||
GenericType(
|
GenericType(
|
||||||
name="list",
|
name="list",
|
||||||
params=[TypeVar(name="T", bound=None)],
|
params=[TypeVar(name="T", bound=None)],
|
||||||
body=ComplexType(
|
body=BaseType(name="list"),
|
||||||
properties={
|
|
||||||
"append": Function(
|
|
||||||
name="append",
|
|
||||||
pos_args=[
|
|
||||||
Function.Argument(
|
|
||||||
pos=0,
|
|
||||||
name="object",
|
|
||||||
type=TypeVar(name="T", bound=None),
|
|
||||||
required=True,
|
|
||||||
)
|
|
||||||
],
|
|
||||||
args=[],
|
|
||||||
kw_args=[],
|
|
||||||
returns=UnitType(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import logging
|
import logging
|
||||||
|
from pathlib import Path
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
import midas.ast.midas as m
|
import midas.ast.midas as m
|
||||||
@@ -33,6 +34,8 @@ class MidasTyper(m.Stmt.Visitor[None], m.Expr.Visitor[None], m.Type.Visitor[Type
|
|||||||
self._current_name: Optional[str] = None
|
self._current_name: Optional[str] = None
|
||||||
|
|
||||||
define_builtins(self.types)
|
define_builtins(self.types)
|
||||||
|
builtins_path: Path = (Path(__file__).parent / "builtins.midas").resolve()
|
||||||
|
self.process(builtins_path.read_text(), str(builtins_path))
|
||||||
|
|
||||||
def process(self, source: str, path: Optional[str]):
|
def process(self, source: str, path: Optional[str]):
|
||||||
self.reporter = self.reporter.for_file(path)
|
self.reporter = self.reporter.for_file(path)
|
||||||
|
|||||||
Reference in New Issue
Block a user