mirror of https://github.com/exaloop/codon.git
Generic Slices (#544)
* Changed slice fields to generics, added check to adjust_indices * fix typecheck * Refactored Slice class, fixed test * fix test * made slice fields optional, updated tests * Fix list optimization for new slices; update tests --------- Co-authored-by: A. R. Shajii <ars@ars.me>jit-fixes
parent
4be3bbf9e7
commit
4400e3d849
|
@ -14,7 +14,7 @@ namespace pythonic {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
static const std::string LIST = "std.internal.types.ptr.List";
|
static const std::string LIST = "std.internal.types.ptr.List";
|
||||||
static const std::string SLICE = "std.internal.types.slice.Slice";
|
static const std::string SLICE = "std.internal.types.slice.Slice[int,int,int]";
|
||||||
|
|
||||||
bool isList(Value *v) { return v->getType()->getName().rfind(LIST + "[", 0) == 0; }
|
bool isList(Value *v) { return v->getType()->getName().rfind(LIST + "[", 0) == 0; }
|
||||||
bool isSlice(Value *v) { return v->getType()->getName() == SLICE; }
|
bool isSlice(Value *v) { return v->getType()->getName() == SLICE; }
|
||||||
|
|
|
@ -2,14 +2,36 @@
|
||||||
|
|
||||||
@tuple
|
@tuple
|
||||||
class Slice:
|
class Slice:
|
||||||
start: Optional[int]
|
start: Optional[T]
|
||||||
stop: Optional[int]
|
stop: Optional[U]
|
||||||
step: Optional[int]
|
step: Optional[V]
|
||||||
|
T: type
|
||||||
|
U: type
|
||||||
|
V: type
|
||||||
|
|
||||||
def __new__(stop: Optional[int]):
|
def __new__(stop: Optional[U], U: type = int):
|
||||||
return Slice(None, stop, None)
|
return Slice(None, stop, None)
|
||||||
|
|
||||||
|
def __new__(
|
||||||
|
start: Optional[T],
|
||||||
|
stop: Optional[U],
|
||||||
|
T: type = int,
|
||||||
|
U: type = int):
|
||||||
|
return Slice(start, stop, None)
|
||||||
|
|
||||||
|
def __new__(
|
||||||
|
start: Optional[T],
|
||||||
|
stop: Optional[U],
|
||||||
|
step: Optional[V],
|
||||||
|
T: type = int,
|
||||||
|
U: type = int,
|
||||||
|
V: type = int) -> Slice[T, U, V]:
|
||||||
|
return (start, stop, step)
|
||||||
|
|
||||||
def adjust_indices(self, length: int) -> Tuple[int, int, int, int]:
|
def adjust_indices(self, length: int) -> Tuple[int, int, int, int]:
|
||||||
|
if not (T is int and U is int and V is int):
|
||||||
|
compile_error("slice indices must be integers or None")
|
||||||
|
|
||||||
step: int = self.step if self.step is not None else 1
|
step: int = self.step if self.step is not None else 1
|
||||||
start: int = 0
|
start: int = 0
|
||||||
stop: int = 0
|
stop: int = 0
|
||||||
|
@ -58,4 +80,10 @@ class Slice:
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"slice({self.start}, {self.stop}, {self.step})"
|
return f"slice({self.start}, {self.stop}, {self.step})"
|
||||||
|
|
||||||
|
def __eq__(self, other: Slice):
|
||||||
|
return self.start == other.start and self.step == other.step and self.stop == other.stop
|
||||||
|
|
||||||
|
def __ne__(self, other: Slice):
|
||||||
|
return not self.__eq__(other)
|
||||||
|
|
||||||
slice = Slice
|
slice = Slice
|
||||||
|
|
|
@ -764,6 +764,40 @@ def test_slice():
|
||||||
x = X(tmp)
|
x = X(tmp)
|
||||||
x[1:2] = 42
|
x[1:2] = 42
|
||||||
assert tmp == [(slice(1, 2), 42)]
|
assert tmp == [(slice(1, 2), 42)]
|
||||||
|
|
||||||
|
# Non-int elements
|
||||||
|
def check_types(s, T: type, U: type, V: type):
|
||||||
|
return (type(s.start) is Optional[T] and
|
||||||
|
type(s.stop) is Optional[U] and
|
||||||
|
type(s.step) is Optional[V])
|
||||||
|
assert check_types(slice(1j, 'x', 3.14), complex, str, float)
|
||||||
|
assert check_types(slice(None, 'x', 3.14), int, str, float)
|
||||||
|
assert check_types(slice(1j, None, 3.14), complex, int, float)
|
||||||
|
assert check_types(slice(1j, 'x', None), complex, str, int)
|
||||||
|
assert check_types(slice(1j, None, None), complex, int, int)
|
||||||
|
assert check_types(slice(None, 'x', None), int, str, int)
|
||||||
|
assert check_types(slice(None, None, 3.14), int, int, float)
|
||||||
|
assert check_types(slice(None, None, None), int, int, int)
|
||||||
|
assert check_types(slice(1j, 'x'), complex, str, int)
|
||||||
|
assert check_types(slice(None, 'x'), int, str, int)
|
||||||
|
assert check_types(slice(1j, None), complex, int, int)
|
||||||
|
assert check_types(slice(None, None), int, int, int)
|
||||||
|
assert check_types(slice(1j), int, complex, int)
|
||||||
|
assert check_types(slice(None), int, int, int)
|
||||||
|
|
||||||
|
# eq / ne
|
||||||
|
assert slice(1, 2, 3) == slice(1, 2, 3)
|
||||||
|
assert slice(0, 2, 3) != slice(1, 2, 3)
|
||||||
|
assert slice(1, 0, 3) != slice(1, 2, 3)
|
||||||
|
assert slice(1, 2, 0) != slice(1, 2, 3)
|
||||||
|
assert slice(None, None, None) == slice(None, None, None)
|
||||||
|
assert slice(None, 42, None) == slice(None, 42, None)
|
||||||
|
assert slice(None, 42, None) != slice(None, 43, None)
|
||||||
|
assert slice(1, None, 3) == slice(1, None, 3)
|
||||||
|
assert slice(1, None, 3) != slice(1, None, 0)
|
||||||
|
assert slice(1, None, 3) != slice(0, None, 3)
|
||||||
|
assert slice(1) == slice(1)
|
||||||
|
assert slice(1) != slice(2)
|
||||||
test_slice()
|
test_slice()
|
||||||
|
|
||||||
@test
|
@test
|
||||||
|
|
Loading…
Reference in New Issue