🐐 Unpacking arrays

This commit is contained in:
2026-04-21 14:54:36 +02:00
parent c28ffbbf45
commit 63c35605a2
7 changed files with 127 additions and 4 deletions

View File

@@ -11,8 +11,8 @@ from fractions import Fraction
from centvrion.ast_nodes import (
ArrayIndex, Bool, BinOp, BuiltIn, DataArray, DataRangeArray, Defini,
Continva, Designa, DesignaIndex, DumStatement, Erumpe, ExpressionStatement, ID,
Invoca, ModuleCall, Nullus, Numeral, PerStatement,
Continva, Designa, DesignaDestructure, DesignaIndex, DumStatement, Erumpe,
ExpressionStatement, ID, Invoca, ModuleCall, Nullus, Numeral, PerStatement,
Program, Redi, SiStatement, String, UnaryMinus, UnaryNot,
Fractio, frac_to_fraction, fraction_to_frac,
num_to_int, int_to_num, make_string,
@@ -298,6 +298,57 @@ class TestAssignment(unittest.TestCase):
run_test(self, source, nodes, value)
# --- Destructuring ---
destructuring_tests = [
# basic: unpack multi-return function
(
"DEFINI pair (a, b) VT { REDI (a, b) }\nDESIGNA x, y VT INVOCA pair (III, VII)\nx + y",
Program([], [
Defini(ID("pair"), [ID("a"), ID("b")], [Redi([ID("a"), ID("b")])]),
DesignaDestructure([ID("x"), ID("y")], Invoca(ID("pair"), [Numeral("III"), Numeral("VII")])),
ExpressionStatement(BinOp(ID("x"), ID("y"), "SYMBOL_PLUS")),
]),
ValInt(10),
),
# unpack array literal
(
"DESIGNA a, b VT [I, II]\na + b",
Program([], [
DesignaDestructure([ID("a"), ID("b")], DataArray([Numeral("I"), Numeral("II")])),
ExpressionStatement(BinOp(ID("a"), ID("b"), "SYMBOL_PLUS")),
]),
ValInt(3),
),
# three variables
(
"DESIGNA a, b, c VT [X, XX, XXX]\na + b + c",
Program([], [
DesignaDestructure([ID("a"), ID("b"), ID("c")], DataArray([Numeral("X"), Numeral("XX"), Numeral("XXX")])),
ExpressionStatement(BinOp(BinOp(ID("a"), ID("b"), "SYMBOL_PLUS"), ID("c"), "SYMBOL_PLUS")),
]),
ValInt(60),
),
# destructure into individual use
(
"DEFINI pair (a, b) VT { REDI (a, b) }\nDESIGNA x, y VT INVOCA pair (V, II)\nDICE(x)\nDICE(y)",
Program([], [
Defini(ID("pair"), [ID("a"), ID("b")], [Redi([ID("a"), ID("b")])]),
DesignaDestructure([ID("x"), ID("y")], Invoca(ID("pair"), [Numeral("V"), Numeral("II")])),
ExpressionStatement(BuiltIn("DICE", [ID("x")])),
ExpressionStatement(BuiltIn("DICE", [ID("y")])),
]),
ValStr("II"),
"V\nII\n",
),
]
class TestDestructuring(unittest.TestCase):
@parameterized.expand(destructuring_tests)
def test_destructuring(self, source, nodes, value, output=""):
run_test(self, source, nodes, value, output)
# --- Control flow ---
control_tests = [
@@ -539,6 +590,9 @@ error_tests = [
("NON I", CentvrionError), # NON on integer
("DESIGNA z VT I - I\nNON z", CentvrionError), # NON on zero integer
('NON "hello"', CentvrionError), # NON on string
("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
]
class TestErrors(unittest.TestCase):