🐐 Array slicing

This commit is contained in:
2026-04-21 22:53:40 +02:00
parent 559b1b100e
commit 378c28102c
13 changed files with 423 additions and 2 deletions

View File

@@ -11,7 +11,7 @@ from parameterized import parameterized
from fractions import Fraction
from centvrion.ast_nodes import (
ArrayIndex, Bool, BinOp, BuiltIn, DataArray, DataDict, DataRangeArray,
ArrayIndex, ArraySlice, Bool, BinOp, BuiltIn, DataArray, DataDict, DataRangeArray,
Defini, Continva, Designa, DesignaDestructure, DesignaIndex, DumStatement,
Erumpe, ExpressionStatement, Fvnctio, ID, InterpolatedString, Invoca,
ModuleCall, Nullus, Numeral, PerStatement, Program, Redi, SiStatement,
@@ -673,6 +673,15 @@ error_tests = [
("DESIGNA a, b VT III", CentvrionError), # destructure non-array
("DESIGNA a, b VT [I]", CentvrionError), # destructure length mismatch: too many targets
("DESIGNA a, b VT [I, II, III]", CentvrionError), # destructure length mismatch: too few targets
("[I, II, III][II VSQVE IV]", CentvrionError), # slice upper bound out of range
("[I, II, III][NVLLVS VSQVE II]", CentvrionError), # slice with non-integer bound
("I[I VSQVE II]", CentvrionError), # slice on non-array
("[I, II, III][III VSQVE I]", CentvrionError), # slice from > to
("CVM SVBNVLLA\n[I, II, III][-I VSQVE II]", CentvrionError), # slice with negative lower bound
("CVM SVBNVLLA\n[I, II, III][I VSQVE -I]", CentvrionError), # slice with negative upper bound
("CVM FRACTIO\n[I, II, III][IIIS VSQVE III]", CentvrionError), # slice with fractional lower bound
("CVM FRACTIO\n[I, II, III][I VSQVE IIIS]", CentvrionError), # slice with fractional upper bound
("CVM FRACTIO\n[I, II, III][I / II VSQVE III]", CentvrionError), # slice with division-fraction lower bound
]
class TestErrors(unittest.TestCase):
@@ -1517,6 +1526,63 @@ class TestArrayIndexAssign(unittest.TestCase):
run_test(self, source, nodes, value)
# --- Array slicing ---
array_slice_tests = [
# basic slice from middle
("[X, XX, XXX, XL, L][II VSQVE IV]",
Program([], [ExpressionStatement(ArraySlice(
DataArray([Numeral("X"), Numeral("XX"), Numeral("XXX"), Numeral("XL"), Numeral("L")]),
Numeral("II"), Numeral("IV")))]),
ValList([ValInt(20), ValInt(30), ValInt(40)])),
# slice of length 1
("[I, II, III][II VSQVE II]",
Program([], [ExpressionStatement(ArraySlice(
DataArray([Numeral("I"), Numeral("II"), Numeral("III")]),
Numeral("II"), Numeral("II")))]),
ValList([ValInt(2)])),
# full array slice
("[I, II, III][I VSQVE III]",
Program([], [ExpressionStatement(ArraySlice(
DataArray([Numeral("I"), Numeral("II"), Numeral("III")]),
Numeral("I"), Numeral("III")))]),
ValList([ValInt(1), ValInt(2), ValInt(3)])),
# slice on variable
("DESIGNA a VT [I, II, III, IV, V]\na[II VSQVE IV]",
Program([], [
Designa(ID("a"), DataArray([Numeral("I"), Numeral("II"), Numeral("III"), Numeral("IV"), Numeral("V")])),
ExpressionStatement(ArraySlice(ID("a"), Numeral("II"), Numeral("IV"))),
]),
ValList([ValInt(2), ValInt(3), ValInt(4)])),
# slice then index (chained)
("[I, II, III, IV][I VSQVE III][II]",
Program([], [ExpressionStatement(ArrayIndex(
ArraySlice(
DataArray([Numeral("I"), Numeral("II"), Numeral("III"), Numeral("IV")]),
Numeral("I"), Numeral("III")),
Numeral("II")))]),
ValInt(2)),
# slice on range array
("[I VSQVE X][III VSQVE VII]",
Program([], [ExpressionStatement(ArraySlice(
DataRangeArray(Numeral("I"), Numeral("X")),
Numeral("III"), Numeral("VII")))]),
ValList([ValInt(3), ValInt(4), ValInt(5), ValInt(6), ValInt(7)])),
# expression as slice bounds
("[I, II, III, IV, V][I + I VSQVE II + II]",
Program([], [ExpressionStatement(ArraySlice(
DataArray([Numeral("I"), Numeral("II"), Numeral("III"), Numeral("IV"), Numeral("V")]),
BinOp(Numeral("I"), Numeral("I"), "SYMBOL_PLUS"),
BinOp(Numeral("II"), Numeral("II"), "SYMBOL_PLUS")))]),
ValList([ValInt(2), ValInt(3), ValInt(4)])),
]
class TestArraySlice(unittest.TestCase):
@parameterized.expand(array_slice_tests)
def test_array_slice(self, source, nodes, value):
run_test(self, source, nodes, value)
# --- Comments ---
comment_tests = [