Implement Range

This commit is contained in:
Shunsuke Shibayama 2022-10-10 13:51:07 +09:00
parent 81726a0142
commit ff1ead75ff
2 changed files with 94 additions and 1 deletions

View file

@ -1441,7 +1441,8 @@ impl Context {
/* Range */ /* Range */
let range_t = builtin_poly("Range", vec![TyParam::t(mono_q("T"))]); let range_t = builtin_poly("Range", vec![TyParam::t(mono_q("T"))]);
let mut range = Self::builtin_poly_class("Range", vec![PS::t_nd("T")], 2); let mut range = Self::builtin_poly_class("Range", vec![PS::t_nd("T")], 2);
range.register_superclass(Obj, &obj); // range.register_superclass(Obj, &obj);
range.register_superclass(Type, &type_);
range.register_marker_trait(builtin_poly("Output", vec![ty_tp(mono_q("T"))])); range.register_marker_trait(builtin_poly("Output", vec![ty_tp(mono_q("T"))]));
let mut range_eq = Self::builtin_methods("Eq", 2); let mut range_eq = Self::builtin_methods("Eq", 2);
range_eq.register_builtin_impl( range_eq.register_builtin_impl(

View file

@ -1,3 +1,5 @@
from collections.abc import Iterable, Sequence, Iterator, Container
def in_operator(x, y): def in_operator(x, y):
if type(y) == type: if type(y) == type:
if isinstance(x, y): if isinstance(x, y):
@ -13,3 +15,93 @@ def in_operator(x, y):
NotImplemented NotImplemented
else: else:
return x in y return x in y
class Range:
def __init__(self, start, end):
self.start = start
self.end = end
def __contains__(self, item):
pass
def __getitem__(self, item):
pass
def __len__(self):
pass
def __iter__(self):
return RangeIterator(rng=self)
Sequence.register(Range)
Container.register(Range)
Iterable.register(Range)
# represents `start<..end`
class LeftOpenRange(Range):
def __contains__(self, item):
return self.start < item <= self.end
def __getitem__(self, item):
return NotImplemented
def __len__(self):
return NotImplemented
# represents `start..<end`
class RightOpenRange(Range):
def __contains__(self, item):
return self.start <= item < self.end
def __getitem__(self, item):
return NotImplemented
def __len__(self):
return NotImplemented
# represents `start<..<end`
class OpenRange(Range):
def __contains__(self, item):
return self.start < item < self.end
def __getitem__(self, item):
return NotImplemented
def __len__(self):
return NotImplemented
# represents `start..end`
class ClosedRange(Range):
def __contains__(self, item):
return self.start <= item <= self.end
def __getitem__(self, item):
return NotImplemented
def __len__(self):
return NotImplemented
class RangeIterator:
def __init__(self, rng):
self.rng = rng
self.needle = self.rng.start
if type(self.rng.start) == int:
if not(self.needle in self.rng):
self.needle += 1
elif type(self.rng.start) == str:
if not(self.needle in self.rng):
self.needle = chr(ord(self.needle) + 1)
else:
if not(self.needle in self.rng):
self.needle = self.needle.incremented()
def __iter__(self):
return self
def __next__(self):
if type(self.rng.start) == int:
if self.needle in self.rng:
result = self.needle
self.needle += 1
return result
elif type(self.rng.start) == str:
if self.needle in self.rng:
result = self.needle
self.needle = chr(ord(self.needle) + 1)
return result
else:
if self.needle in self.rng:
result = self.needle
self.needle = self.needle.incremented()
return result
raise StopIteration
Iterator.register(RangeIterator)