🐐 Array slicing
This commit is contained in:
@@ -847,6 +847,49 @@ class ArrayIndex(Node):
|
||||
return vtable, lst[i - 1]
|
||||
|
||||
|
||||
def _to_index_int(val):
|
||||
if isinstance(val, ValInt):
|
||||
return val.value()
|
||||
if isinstance(val, ValFrac) and val.value().denominator == 1:
|
||||
return val.value().numerator
|
||||
raise CentvrionError("Array index must be a number")
|
||||
|
||||
|
||||
class ArraySlice(Node):
|
||||
def __init__(self, array, from_index, to_index) -> None:
|
||||
self.array = array
|
||||
self.from_index = from_index
|
||||
self.to_index = to_index
|
||||
|
||||
def __eq__(self, other):
|
||||
return (type(self) == type(other)
|
||||
and self.array == other.array
|
||||
and self.from_index == other.from_index
|
||||
and self.to_index == other.to_index)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"ArraySlice({self.array!r}, {self.from_index!r}, {self.to_index!r})"
|
||||
|
||||
def print(self):
|
||||
return f"{self.array.print()}[{self.from_index.print()} VSQVE {self.to_index.print()}]"
|
||||
|
||||
def _eval(self, vtable):
|
||||
vtable, array = self.array.eval(vtable)
|
||||
vtable, from_val = self.from_index.eval(vtable)
|
||||
vtable, to_val = self.to_index.eval(vtable)
|
||||
if not isinstance(array, ValList):
|
||||
raise CentvrionError("Cannot slice a non-array value")
|
||||
from_int = _to_index_int(from_val)
|
||||
to_int = _to_index_int(to_val)
|
||||
lst = array.value()
|
||||
if from_int < 1 or to_int > len(lst) or from_int > to_int:
|
||||
raise CentvrionError(
|
||||
f"Slice [{from_int} VSQVE {to_int}] out of range"
|
||||
f" for array of length {len(lst)}"
|
||||
)
|
||||
return vtable, ValList(lst[from_int - 1 : to_int])
|
||||
|
||||
|
||||
class SiStatement(Node):
|
||||
def __init__(self, test, statements, else_part) -> None:
|
||||
self.test = test
|
||||
|
||||
Reference in New Issue
Block a user