🐐 VSQVE change

This commit is contained in:
2026-04-21 22:35:22 +02:00
parent 5961884219
commit 559b1b100e
9 changed files with 62 additions and 47 deletions

View File

@@ -105,10 +105,14 @@ Arrays are defined using square brackets (`[]`) and commas (`,`):
![Array literal](snippets/array_literal.png) ![Array literal](snippets/array_literal.png)
An array of integers can also be initialized with the `VSQVE` keyword: An array of integers can also be initialized with the `VSQVE` keyword. The range is inclusive on both ends:
![Array with VSQVE](snippets/array_vsqve.png) ![Array with VSQVE](snippets/array_vsqve.png)
```
> [I, II, III, IV, V, VI, VII, VIII, IX, X]
```
Individual elements can be accessed by index using square brackets. Indexing is 1-based, so `I` refers to the first element: Individual elements can be accessed by index using square brackets. Indexing is 1-based, so `I` refers to the first element:
![Array indexing](snippets/array_index.png) ![Array indexing](snippets/array_index.png)
@@ -178,7 +182,7 @@ The keyword `ET` can be used as a boolean "and". The keyword `AVT` can be used a
![DONICVM loop](snippets/donicvm.png) ![DONICVM loop](snippets/donicvm.png)
``` ```
> XLV > LV
``` ```
### DVM loops ### DVM loops

View File

@@ -280,7 +280,7 @@ class DataRangeArray(Node):
raise CentvrionError("Range bounds must be numbers") raise CentvrionError("Range bounds must be numbers")
from_int = from_val.value() or 0 from_int = from_val.value() or 0
to_int = to_val.value() or 0 to_int = to_val.value() or 0
return vtable, ValList([ValInt(i) for i in range(from_int, to_int)]) return vtable, ValList([ValInt(i) for i in range(from_int, to_int + 1)])
class DataDict(Node): class DataDict(Node):

View File

@@ -135,10 +135,10 @@ def emit_expr(node, ctx):
hi_lines, hi_var = emit_expr(node.to_value, ctx) hi_lines, hi_var = emit_expr(node.to_value, ctx)
tmp = ctx.fresh_tmp() tmp = ctx.fresh_tmp()
i_var = ctx.fresh_tmp() i_var = ctx.fresh_tmp()
cap = f"({hi_var}.ival > {lo_var}.ival ? (int)({hi_var}.ival - {lo_var}.ival) : 0)" cap = f"({hi_var}.ival >= {lo_var}.ival ? (int)({hi_var}.ival - {lo_var}.ival + 1) : 0)"
lines = lo_lines + hi_lines + [ lines = lo_lines + hi_lines + [
f"CentValue {tmp} = cent_list_new({cap});", f"CentValue {tmp} = cent_list_new({cap});",
f"for (long {i_var} = {lo_var}.ival; {i_var} < {hi_var}.ival; {i_var}++) {{", f"for (long {i_var} = {lo_var}.ival; {i_var} <= {hi_var}.ival; {i_var}++) {{",
f" cent_list_push(&{tmp}, cent_int({i_var}));", f" cent_list_push(&{tmp}, cent_int({i_var}));",
"}", "}",
] ]

View File

@@ -3,8 +3,8 @@
DESIGNA arr VT [V, III, VIII, I, IX, II, VII, IV, VI, X] DESIGNA arr VT [V, III, VIII, I, IX, II, VII, IV, VI, X]
DESIGNA n VT LONGITVDO(arr) DESIGNA n VT LONGITVDO(arr)
DONICVM i VT I VSQVE n FACE { DONICVM i VT I VSQVE n - I FACE {
DONICVM k VT I VSQVE n - i + I FACE { DONICVM k VT I VSQVE n - i FACE {
SI arr[k] PLVS arr[k + I] TVNC { SI arr[k] PLVS arr[k + I] TVNC {
DESIGNA temp VT arr[k] DESIGNA temp VT arr[k]
DESIGNA arr[k] VT arr[k + I] DESIGNA arr[k] VT arr[k + I]

View File

@@ -6,7 +6,7 @@
// Returns the bottommost empty row in col, or NVLLVS if full // Returns the bottommost empty row in col, or NVLLVS if full
DEFINI find_slot(b, col) VT { DEFINI find_slot(b, col) VT {
DESIGNA ans VT NVLLVS DESIGNA ans VT NVLLVS
DONICVM r VT I VSQVE VII FACE { DONICVM r VT I VSQVE VI FACE {
SI b[(r - I) * VII + col] EST NVLLVS TVNC { SI b[(r - I) * VII + col] EST NVLLVS TVNC {
DESIGNA ans VT r DESIGNA ans VT r
} }
@@ -16,32 +16,32 @@ DEFINI find_slot(b, col) VT {
// Returns VERITAS if player has four in a row // Returns VERITAS if player has four in a row
DEFINI est_victor(b, player) VT { DEFINI est_victor(b, player) VT {
DONICVM r VT I VSQVE VII FACE { DONICVM r VT I VSQVE VI FACE {
DONICVM c VT I VSQVE V FACE { DONICVM c VT I VSQVE IV FACE {
DESIGNA idx VT (r - I) * VII + c DESIGNA idx VT (r - I) * VII + c
SI b[idx] EST player ET b[idx + I] EST player ET b[idx + II] EST player ET b[idx + III] EST player TVNC { SI b[idx] EST player ET b[idx + I] EST player ET b[idx + II] EST player ET b[idx + III] EST player TVNC {
REDI(VERITAS) REDI(VERITAS)
} }
} }
} }
DONICVM r VT I VSQVE IV FACE { DONICVM r VT I VSQVE III FACE {
DONICVM c VT I VSQVE VIII FACE { DONICVM c VT I VSQVE VII FACE {
DESIGNA idx VT (r - I) * VII + c DESIGNA idx VT (r - I) * VII + c
SI b[idx] EST player ET b[idx + VII] EST player ET b[idx + XIV] EST player ET b[idx + XXI] EST player TVNC { SI b[idx] EST player ET b[idx + VII] EST player ET b[idx + XIV] EST player ET b[idx + XXI] EST player TVNC {
REDI(VERITAS) REDI(VERITAS)
} }
} }
} }
DONICVM r VT I VSQVE IV FACE { DONICVM r VT I VSQVE III FACE {
DONICVM c VT I VSQVE V FACE { DONICVM c VT I VSQVE IV FACE {
DESIGNA idx VT (r - I) * VII + c DESIGNA idx VT (r - I) * VII + c
SI b[idx] EST player ET b[idx + VIII] EST player ET b[idx + XVI] EST player ET b[idx + XXIV] EST player TVNC { SI b[idx] EST player ET b[idx + VIII] EST player ET b[idx + XVI] EST player ET b[idx + XXIV] EST player TVNC {
REDI(VERITAS) REDI(VERITAS)
} }
} }
} }
DONICVM r VT I VSQVE IV FACE { DONICVM r VT I VSQVE III FACE {
DONICVM c VT IV VSQVE VIII FACE { DONICVM c VT IV VSQVE VII FACE {
DESIGNA idx VT (r - I) * VII + c DESIGNA idx VT (r - I) * VII + c
SI b[idx] EST player ET b[idx + VI] EST player ET b[idx + XII] EST player ET b[idx + XVIII] EST player TVNC { SI b[idx] EST player ET b[idx + VI] EST player ET b[idx + XII] EST player ET b[idx + XVIII] EST player TVNC {
REDI(VERITAS) REDI(VERITAS)
@@ -53,9 +53,9 @@ DEFINI est_victor(b, player) VT {
DEFINI print_board(b) VT { DEFINI print_board(b) VT {
DICE("+---+---+---+---+---+---+---+") DICE("+---+---+---+---+---+---+---+")
DONICVM r VT I VSQVE VII FACE { DONICVM r VT I VSQVE VI FACE {
DESIGNA line VT "| " DESIGNA line VT "| "
DONICVM c VT I VSQVE VIII FACE { DONICVM c VT I VSQVE VII FACE {
DESIGNA cell VT b[(r - I) * VII + c] DESIGNA cell VT b[(r - I) * VII + c]
SI cell EST I TVNC { SI cell EST I TVNC {
DESIGNA line VT line & "X | " DESIGNA line VT line & "X | "
@@ -101,35 +101,35 @@ DEFINI score_fenestram(a, b, c, d) VT {
DEFINI aestima(b) VT { DEFINI aestima(b) VT {
DESIGNA score VT NVLLVS DESIGNA score VT NVLLVS
// Center column preference: each AI piece in column IV is worth +1 // Center column preference: each AI piece in column IV is worth +1
DONICVM r VT I VSQVE VII FACE { DONICVM r VT I VSQVE VI FACE {
SI b[(r - I) * VII + IV] EST II TVNC { SI b[(r - I) * VII + IV] EST II TVNC {
DESIGNA score VT score + I DESIGNA score VT score + I
} }
} }
// Horizontal windows (6 rows x 4 starting columns = 24) // Horizontal windows (6 rows x 4 starting columns = 24)
DONICVM r VT I VSQVE VII FACE { DONICVM r VT I VSQVE VI FACE {
DONICVM c VT I VSQVE V FACE { DONICVM c VT I VSQVE IV FACE {
DESIGNA idx VT (r - I) * VII + c DESIGNA idx VT (r - I) * VII + c
DESIGNA score VT score + INVOCA score_fenestram(b[idx], b[idx + I], b[idx + II], b[idx + III]) DESIGNA score VT score + INVOCA score_fenestram(b[idx], b[idx + I], b[idx + II], b[idx + III])
} }
} }
// Vertical windows (3 starting rows x 7 columns = 21) // Vertical windows (3 starting rows x 7 columns = 21)
DONICVM r VT I VSQVE IV FACE { DONICVM r VT I VSQVE III FACE {
DONICVM c VT I VSQVE VIII FACE { DONICVM c VT I VSQVE VII FACE {
DESIGNA idx VT (r - I) * VII + c DESIGNA idx VT (r - I) * VII + c
DESIGNA score VT score + INVOCA score_fenestram(b[idx], b[idx + VII], b[idx + XIV], b[idx + XXI]) DESIGNA score VT score + INVOCA score_fenestram(b[idx], b[idx + VII], b[idx + XIV], b[idx + XXI])
} }
} }
// Diagonal up-right windows (3 starting rows x 4 starting columns = 12) // Diagonal up-right windows (3 starting rows x 4 starting columns = 12)
DONICVM r VT I VSQVE IV FACE { DONICVM r VT I VSQVE III FACE {
DONICVM c VT I VSQVE V FACE { DONICVM c VT I VSQVE IV FACE {
DESIGNA idx VT (r - I) * VII + c DESIGNA idx VT (r - I) * VII + c
DESIGNA score VT score + INVOCA score_fenestram(b[idx], b[idx + VIII], b[idx + XVI], b[idx + XXIV]) DESIGNA score VT score + INVOCA score_fenestram(b[idx], b[idx + VIII], b[idx + XVI], b[idx + XXIV])
} }
} }
// Diagonal up-left windows (3 starting rows x 4 starting columns = 12) // Diagonal up-left windows (3 starting rows x 4 starting columns = 12)
DONICVM r VT I VSQVE IV FACE { DONICVM r VT I VSQVE III FACE {
DONICVM c VT IV VSQVE VIII FACE { DONICVM c VT IV VSQVE VII FACE {
DESIGNA idx VT (r - I) * VII + c DESIGNA idx VT (r - I) * VII + c
DESIGNA score VT score + INVOCA score_fenestram(b[idx], b[idx + VI], b[idx + XII], b[idx + XVIII]) DESIGNA score VT score + INVOCA score_fenestram(b[idx], b[idx + VI], b[idx + XII], b[idx + XVIII])
} }
@@ -219,8 +219,8 @@ DEFINI ai_move(b) VT {
} }
// --- Board setup --- // --- Board setup ---
DESIGNA board VT [I VSQVE XLIII] DESIGNA board VT [I VSQVE XLII]
DONICVM i VT I VSQVE XLIII FACE { DONICVM i VT I VSQVE XLII FACE {
DESIGNA board[i] VT NVLLVS DESIGNA board[i] VT NVLLVS
} }

View File

@@ -1,9 +1,9 @@
// Prints an X×X multiplication table // Prints an X×X multiplication table
DESIGNA n VT X DESIGNA n VT X
DONICVM i VT I VSQVE n + I FACE { DONICVM i VT I VSQVE n FACE {
DESIGNA line VT "" DESIGNA line VT ""
DONICVM k VT I VSQVE n + I FACE { DONICVM k VT I VSQVE n FACE {
DESIGNA line VT line & i * k & " " DESIGNA line VT line & i * k & " "
} }
DICE(line) DICE(line)

View File

@@ -2,9 +2,9 @@
DESIGNA n VT L DESIGNA n VT L
DONICVM i VT II VSQVE n + I FACE { DONICVM i VT II VSQVE n FACE {
DESIGNA is_prime VT VERITAS DESIGNA is_prime VT VERITAS
DONICVM k VT II VSQVE i FACE { DONICVM k VT II VSQVE i - I FACE {
SI (i / k) * k EST i TVNC { SI (i / k) * k EST i TVNC {
DESIGNA is_prime VT FALSITAS DESIGNA is_prime VT FALSITAS
} }

View File

@@ -66,7 +66,7 @@
\languageline{literal}{\textbf{numeral}} \\ \languageline{literal}{\textbf{numeral}} \\
\languageline{literal}{\textbf{bool}} \\ \languageline{literal}{\textbf{bool}} \\
\languageline{literal}{\texttt{[} \textit{optional-expressions} \texttt{]}} \\ \languageline{literal}{\texttt{[} \textit{optional-expressions} \texttt{]}} \\
\languageline{literal}{\texttt{[} \textit{expression} \texttt{VSQVE} \textit{expression} \texttt{]}} \\ \languageline{literal}{\texttt{[} \textit{expression} \texttt{VSQVE} \textit{expression} \texttt{]} \textnormal{\small\ (inclusive on both ends)}} \\
\languageline{literal}{\texttt{TABVLA} \texttt{\{} \textit{optional-dict-items} \texttt{\}}} \\ \hline \languageline{literal}{\texttt{TABVLA} \texttt{\{} \textit{optional-dict-items} \texttt{\}}} \\ \hline
\languageline{optional-dict-items}{\textit{dict-items}} \\ \languageline{optional-dict-items}{\textit{dict-items}} \\

View File

@@ -284,13 +284,13 @@ assignment_tests = [
Designa(ID("x"), BinOp(ID("x"), BinOp(Numeral("II"), Numeral("III"), "SYMBOL_PLUS"), "SYMBOL_PLUS")), Designa(ID("x"), BinOp(ID("x"), BinOp(Numeral("II"), Numeral("III"), "SYMBOL_PLUS"), "SYMBOL_PLUS")),
ExpressionStatement(ID("x"))]), ExpressionStatement(ID("x"))]),
ValInt(6)), ValInt(6)),
# AVGE inside a loop (DONICVM range is exclusive of upper bound: I VSQVE III = [1, 2]) # AVGE inside a loop (DONICVM range is inclusive: I VSQVE III = [1, 2, 3])
("DESIGNA s VT NVLLVS\nDONICVM i VT I VSQVE III FACE {\ns AVGE i\n}\ns", ("DESIGNA s VT NVLLVS\nDONICVM i VT I VSQVE III FACE {\ns AVGE i\n}\ns",
Program([], [Designa(ID("s"), Nullus()), Program([], [Designa(ID("s"), Nullus()),
PerStatement(DataRangeArray(Numeral("I"), Numeral("III")), ID("i"), PerStatement(DataRangeArray(Numeral("I"), Numeral("III")), ID("i"),
[Designa(ID("s"), BinOp(ID("s"), ID("i"), "SYMBOL_PLUS"))]), [Designa(ID("s"), BinOp(ID("s"), ID("i"), "SYMBOL_PLUS"))]),
ExpressionStatement(ID("s"))]), ExpressionStatement(ID("s"))]),
ValInt(3)), ValInt(6)),
] ]
class TestAssignment(unittest.TestCase): class TestAssignment(unittest.TestCase):
@@ -470,7 +470,7 @@ control_tests = [
# DONICVM range loop # DONICVM range loop
("DONICVM i VT I VSQVE V FACE { DICE(i) }", ("DONICVM i VT I VSQVE V FACE { DICE(i) }",
Program([], [PerStatement(DataRangeArray(Numeral("I"), Numeral("V")), ID("i"), [ExpressionStatement(BuiltIn("DICE", [ID("i")]))])]), Program([], [PerStatement(DataRangeArray(Numeral("I"), Numeral("V")), ID("i"), [ExpressionStatement(BuiltIn("DICE", [ID("i")]))])]),
ValStr("IV"), "I\nII\nIII\nIV\n"), ValStr("V"), "I\nII\nIII\nIV\nV\n"),
] ]
class TestControl(unittest.TestCase): class TestControl(unittest.TestCase):
@@ -1191,10 +1191,10 @@ class TestFunctionEdge(unittest.TestCase):
# --- Loop edge cases --- # --- Loop edge cases ---
loop_edge_tests = [ loop_edge_tests = [
# range(3, 3) is empty — body never runs, program returns ValNul # [III VSQVE III] = [3] — single iteration
("DONICVM i VT III VSQVE III FACE { DICE(i) }", ("DONICVM i VT III VSQVE III FACE { DICE(i) }",
Program([], [PerStatement(DataRangeArray(Numeral("III"), Numeral("III")), ID("i"), [ExpressionStatement(BuiltIn("DICE", [ID("i")]))])]), Program([], [PerStatement(DataRangeArray(Numeral("III"), Numeral("III")), ID("i"), [ExpressionStatement(BuiltIn("DICE", [ID("i")]))])]),
ValNul(), ""), ValStr("III"), "III\n"),
# empty array — body never runs # empty array — body never runs
("PER i IN [] FACE { DICE(i) }", ("PER i IN [] FACE { DICE(i) }",
Program([], [PerStatement(DataArray([]), ID("i"), [ExpressionStatement(BuiltIn("DICE", [ID("i")]))])]), Program([], [PerStatement(DataArray([]), ID("i"), [ExpressionStatement(BuiltIn("DICE", [ID("i")]))])]),
@@ -1278,7 +1278,7 @@ loop_edge_tests = [
ExpressionStatement(ID("cnt")), ExpressionStatement(ID("cnt")),
]), ]),
ValInt(3), ""), ValInt(3), ""),
# DONICVM with CONTINVA: skip value III, count remaining # DONICVM with CONTINVA: skip value III, count remaining (I VSQVE IV = [1,2,3,4], skip 3 → 3 increments)
("DESIGNA cnt VT I\nDONICVM i VT I VSQVE IV FACE {\nSI i EST III TVNC { CONTINVA }\nDESIGNA cnt VT cnt + I\n}\ncnt", ("DESIGNA cnt VT I\nDONICVM i VT I VSQVE IV FACE {\nSI i EST III TVNC { CONTINVA }\nDESIGNA cnt VT cnt + I\n}\ncnt",
Program([], [ Program([], [
Designa(ID("cnt"), Numeral("I")), Designa(ID("cnt"), Numeral("I")),
@@ -1290,7 +1290,7 @@ loop_edge_tests = [
), ),
ExpressionStatement(ID("cnt")), ExpressionStatement(ID("cnt")),
]), ]),
ValInt(3)), ValInt(4)),
# DVM condition true from start — body never runs # DVM condition true from start — body never runs
("DESIGNA x VT I\nDVM VERITAS FACE {\nDESIGNA x VT x + I\n}\nx", ("DESIGNA x VT I\nDVM VERITAS FACE {\nDESIGNA x VT x + I\n}\nx",
Program([], [ Program([], [
@@ -1299,10 +1299,21 @@ loop_edge_tests = [
ExpressionStatement(ID("x")), ExpressionStatement(ID("x")),
]), ]),
ValInt(1), ""), ValInt(1), ""),
# single iteration: [I VSQVE II] = [1] # two iterations: [I VSQVE II] = [1, 2]
("DONICVM i VT I VSQVE II FACE { DICE(i) }", ("DONICVM i VT I VSQVE II FACE { DICE(i) }",
Program([], [PerStatement(DataRangeArray(Numeral("I"), Numeral("II")), ID("i"), [ExpressionStatement(BuiltIn("DICE", [ID("i")]))])]), Program([], [PerStatement(DataRangeArray(Numeral("I"), Numeral("II")), ID("i"), [ExpressionStatement(BuiltIn("DICE", [ID("i")]))])]),
ValStr("II"), "I\nII\n"),
# single iteration: [I VSQVE I] = [1]
("DONICVM i VT I VSQVE I FACE { DICE(i) }",
Program([], [PerStatement(DataRangeArray(Numeral("I"), Numeral("I")), ID("i"), [ExpressionStatement(BuiltIn("DICE", [ID("i")]))])]),
ValStr("I"), "I\n"), ValStr("I"), "I\n"),
# empty range: [V VSQVE I] = []
("DESIGNA x VT NVLLVS\nDONICVM i VT V VSQVE I FACE { DESIGNA x VT x + i }\nx",
Program([], [Designa(ID("x"), Nullus()),
PerStatement(DataRangeArray(Numeral("V"), Numeral("I")), ID("i"),
[Designa(ID("x"), BinOp(ID("x"), ID("i"), "SYMBOL_PLUS"))]),
ExpressionStatement(ID("x"))]),
ValNul(), ""),
] ]
class TestLoopEdge(unittest.TestCase): class TestLoopEdge(unittest.TestCase):
@@ -1427,7 +1438,7 @@ array_index_tests = [
Program([], [Designa(ID("a"), DataArray([Numeral("X"), Numeral("XX"), Numeral("XXX")])), ExpressionStatement(ArrayIndex(ID("a"), Numeral("II")))]), Program([], [Designa(ID("a"), DataArray([Numeral("X"), Numeral("XX"), Numeral("XXX")])), ExpressionStatement(ArrayIndex(ID("a"), Numeral("II")))]),
ValInt(20)), # second element ValInt(20)), # second element
# index into range array # index into range array
("[I VSQVE V][II]", Program([], [ExpressionStatement(ArrayIndex(DataRangeArray(Numeral("I"), Numeral("V")), Numeral("II")))]), ValInt(2)), # second element of [1,2,3,4] ("[I VSQVE V][II]", Program([], [ExpressionStatement(ArrayIndex(DataRangeArray(Numeral("I"), Numeral("V")), Numeral("II")))]), ValInt(2)), # second element of [1,2,3,4,5]
# expression as index # expression as index
("[I, II, III][I + I]", ("[I, II, III][I + I]",
Program([], [ExpressionStatement(ArrayIndex( Program([], [ExpressionStatement(ArrayIndex(
@@ -1596,15 +1607,15 @@ scope_tests = [
]), ]),
ValInt(100)), ValInt(100)),
# DONICVM: counter holds last range value after loop ends # DONICVM: counter holds last range value after loop ends
# [I VSQVE IV] = [1,2,3]; last value assigned by loop is III=3 # [I VSQVE IV] = [1,2,3,4]; last value assigned by loop is IV=4
("DONICVM i VT I VSQVE IV FACE { DESIGNA nop VT I }\ni", ("DONICVM i VT I VSQVE IV FACE { DESIGNA nop VT I }\ni",
Program([], [ Program([], [
PerStatement(DataRangeArray(Numeral("I"), Numeral("IV")), ID("i"), [Designa(ID("nop"), Numeral("I"))]), PerStatement(DataRangeArray(Numeral("I"), Numeral("IV")), ID("i"), [Designa(ID("nop"), Numeral("I"))]),
ExpressionStatement(ID("i")), ExpressionStatement(ID("i")),
]), ]),
ValInt(3)), ValInt(4)),
# DONICVM: reassigning counter inside body doesn't reduce the number of iterations # DONICVM: reassigning counter inside body doesn't reduce the number of iterations
# range [I VSQVE IV] evaluated once; i reset each time; cnt still increments 3 times → 4 # range [I VSQVE IV] evaluated once; i reset each time; cnt still increments 4 times → 5
("DESIGNA cnt VT I\nDONICVM i VT I VSQVE IV FACE { DESIGNA cnt VT cnt + I\nDESIGNA i VT C }\ncnt", ("DESIGNA cnt VT I\nDONICVM i VT I VSQVE IV FACE { DESIGNA cnt VT cnt + I\nDESIGNA i VT C }\ncnt",
Program([], [ Program([], [
Designa(ID("cnt"), Numeral("I")), Designa(ID("cnt"), Numeral("I")),
@@ -1614,7 +1625,7 @@ scope_tests = [
]), ]),
ExpressionStatement(ID("cnt")), ExpressionStatement(ID("cnt")),
]), ]),
ValInt(4)), ValInt(5)),
# DONICVM: ERVMPE exits loop early; counter persists at break value # DONICVM: ERVMPE exits loop early; counter persists at break value
("DONICVM i VT I VSQVE X FACE {\nSI i EST III TVNC { ERVMPE }\n}\ni", ("DONICVM i VT I VSQVE X FACE {\nSI i EST III TVNC { ERVMPE }\n}\ni",
Program([], [ Program([], [