🐐 VSQVE change
This commit is contained in:
@@ -105,10 +105,14 @@ Arrays are defined using square brackets (`[]`) and commas (`,`):
|
||||
|
||||

|
||||
|
||||
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:
|
||||
|
||||

|
||||
|
||||
```
|
||||
> [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:
|
||||
|
||||

|
||||
@@ -178,7 +182,7 @@ The keyword `ET` can be used as a boolean "and". The keyword `AVT` can be used a
|
||||

|
||||
|
||||
```
|
||||
> XLV
|
||||
> LV
|
||||
```
|
||||
|
||||
### DVM loops
|
||||
|
||||
@@ -280,7 +280,7 @@ class DataRangeArray(Node):
|
||||
raise CentvrionError("Range bounds must be numbers")
|
||||
from_int = from_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):
|
||||
|
||||
@@ -135,10 +135,10 @@ def emit_expr(node, ctx):
|
||||
hi_lines, hi_var = emit_expr(node.to_value, ctx)
|
||||
tmp = 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 + [
|
||||
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}));",
|
||||
"}",
|
||||
]
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
DESIGNA arr VT [V, III, VIII, I, IX, II, VII, IV, VI, X]
|
||||
DESIGNA n VT LONGITVDO(arr)
|
||||
|
||||
DONICVM i VT I VSQVE n FACE {
|
||||
DONICVM k VT I VSQVE n - i + I FACE {
|
||||
DONICVM i VT I VSQVE n - I FACE {
|
||||
DONICVM k VT I VSQVE n - i FACE {
|
||||
SI arr[k] PLVS arr[k + I] TVNC {
|
||||
DESIGNA temp VT arr[k]
|
||||
DESIGNA arr[k] VT arr[k + I]
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Returns the bottommost empty row in col, or NVLLVS if full
|
||||
DEFINI find_slot(b, col) VT {
|
||||
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 {
|
||||
DESIGNA ans VT r
|
||||
}
|
||||
@@ -16,32 +16,32 @@ DEFINI find_slot(b, col) VT {
|
||||
|
||||
// Returns VERITAS if player has four in a row
|
||||
DEFINI est_victor(b, player) VT {
|
||||
DONICVM r VT I VSQVE VII FACE {
|
||||
DONICVM c VT I VSQVE V FACE {
|
||||
DONICVM r VT I VSQVE VI FACE {
|
||||
DONICVM c VT I VSQVE IV FACE {
|
||||
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 {
|
||||
REDI(VERITAS)
|
||||
}
|
||||
}
|
||||
}
|
||||
DONICVM r VT I VSQVE IV FACE {
|
||||
DONICVM c VT I VSQVE VIII FACE {
|
||||
DONICVM r VT I VSQVE III FACE {
|
||||
DONICVM c VT I VSQVE VII FACE {
|
||||
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 {
|
||||
REDI(VERITAS)
|
||||
}
|
||||
}
|
||||
}
|
||||
DONICVM r VT I VSQVE IV FACE {
|
||||
DONICVM c VT I VSQVE V FACE {
|
||||
DONICVM r VT I VSQVE III FACE {
|
||||
DONICVM c VT I VSQVE IV FACE {
|
||||
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 {
|
||||
REDI(VERITAS)
|
||||
}
|
||||
}
|
||||
}
|
||||
DONICVM r VT I VSQVE IV FACE {
|
||||
DONICVM c VT IV VSQVE VIII FACE {
|
||||
DONICVM r VT I VSQVE III FACE {
|
||||
DONICVM c VT IV VSQVE VII FACE {
|
||||
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 {
|
||||
REDI(VERITAS)
|
||||
@@ -53,9 +53,9 @@ DEFINI est_victor(b, player) VT {
|
||||
|
||||
DEFINI print_board(b) VT {
|
||||
DICE("+---+---+---+---+---+---+---+")
|
||||
DONICVM r VT I VSQVE VII FACE {
|
||||
DONICVM r VT I VSQVE VI FACE {
|
||||
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]
|
||||
SI cell EST I TVNC {
|
||||
DESIGNA line VT line & "X | "
|
||||
@@ -101,35 +101,35 @@ DEFINI score_fenestram(a, b, c, d) VT {
|
||||
DEFINI aestima(b) VT {
|
||||
DESIGNA score VT NVLLVS
|
||||
// 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 {
|
||||
DESIGNA score VT score + I
|
||||
}
|
||||
}
|
||||
// Horizontal windows (6 rows x 4 starting columns = 24)
|
||||
DONICVM r VT I VSQVE VII FACE {
|
||||
DONICVM c VT I VSQVE V FACE {
|
||||
DONICVM r VT I VSQVE VI FACE {
|
||||
DONICVM c VT I VSQVE IV FACE {
|
||||
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])
|
||||
}
|
||||
}
|
||||
// Vertical windows (3 starting rows x 7 columns = 21)
|
||||
DONICVM r VT I VSQVE IV FACE {
|
||||
DONICVM c VT I VSQVE VIII FACE {
|
||||
DONICVM r VT I VSQVE III FACE {
|
||||
DONICVM c VT I VSQVE VII FACE {
|
||||
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])
|
||||
}
|
||||
}
|
||||
// Diagonal up-right windows (3 starting rows x 4 starting columns = 12)
|
||||
DONICVM r VT I VSQVE IV FACE {
|
||||
DONICVM c VT I VSQVE V FACE {
|
||||
DONICVM r VT I VSQVE III FACE {
|
||||
DONICVM c VT I VSQVE IV FACE {
|
||||
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])
|
||||
}
|
||||
}
|
||||
// Diagonal up-left windows (3 starting rows x 4 starting columns = 12)
|
||||
DONICVM r VT I VSQVE IV FACE {
|
||||
DONICVM c VT IV VSQVE VIII FACE {
|
||||
DONICVM r VT I VSQVE III FACE {
|
||||
DONICVM c VT IV VSQVE VII FACE {
|
||||
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])
|
||||
}
|
||||
@@ -219,8 +219,8 @@ DEFINI ai_move(b) VT {
|
||||
}
|
||||
|
||||
// --- Board setup ---
|
||||
DESIGNA board VT [I VSQVE XLIII]
|
||||
DONICVM i VT I VSQVE XLIII FACE {
|
||||
DESIGNA board VT [I VSQVE XLII]
|
||||
DONICVM i VT I VSQVE XLII FACE {
|
||||
DESIGNA board[i] VT NVLLVS
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// Prints an X×X multiplication table
|
||||
DESIGNA n VT X
|
||||
|
||||
DONICVM i VT I VSQVE n + I FACE {
|
||||
DONICVM i VT I VSQVE n FACE {
|
||||
DESIGNA line VT ""
|
||||
DONICVM k VT I VSQVE n + I FACE {
|
||||
DONICVM k VT I VSQVE n FACE {
|
||||
DESIGNA line VT line & i * k & " "
|
||||
}
|
||||
DICE(line)
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
DESIGNA n VT L
|
||||
|
||||
DONICVM i VT II VSQVE n + I FACE {
|
||||
DONICVM i VT II VSQVE n FACE {
|
||||
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 {
|
||||
DESIGNA is_prime VT FALSITAS
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
\languageline{literal}{\textbf{numeral}} \\
|
||||
\languageline{literal}{\textbf{bool}} \\
|
||||
\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{optional-dict-items}{\textit{dict-items}} \\
|
||||
|
||||
37
tests.py
37
tests.py
@@ -284,13 +284,13 @@ assignment_tests = [
|
||||
Designa(ID("x"), BinOp(ID("x"), BinOp(Numeral("II"), Numeral("III"), "SYMBOL_PLUS"), "SYMBOL_PLUS")),
|
||||
ExpressionStatement(ID("x"))]),
|
||||
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",
|
||||
Program([], [Designa(ID("s"), Nullus()),
|
||||
PerStatement(DataRangeArray(Numeral("I"), Numeral("III")), ID("i"),
|
||||
[Designa(ID("s"), BinOp(ID("s"), ID("i"), "SYMBOL_PLUS"))]),
|
||||
ExpressionStatement(ID("s"))]),
|
||||
ValInt(3)),
|
||||
ValInt(6)),
|
||||
]
|
||||
|
||||
class TestAssignment(unittest.TestCase):
|
||||
@@ -470,7 +470,7 @@ control_tests = [
|
||||
# DONICVM range loop
|
||||
("DONICVM i VT I VSQVE V FACE { DICE(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):
|
||||
@@ -1191,10 +1191,10 @@ class TestFunctionEdge(unittest.TestCase):
|
||||
# --- Loop edge cases ---
|
||||
|
||||
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) }",
|
||||
Program([], [PerStatement(DataRangeArray(Numeral("III"), Numeral("III")), ID("i"), [ExpressionStatement(BuiltIn("DICE", [ID("i")]))])]),
|
||||
ValNul(), ""),
|
||||
ValStr("III"), "III\n"),
|
||||
# empty array — body never runs
|
||||
("PER i IN [] FACE { DICE(i) }",
|
||||
Program([], [PerStatement(DataArray([]), ID("i"), [ExpressionStatement(BuiltIn("DICE", [ID("i")]))])]),
|
||||
@@ -1278,7 +1278,7 @@ loop_edge_tests = [
|
||||
ExpressionStatement(ID("cnt")),
|
||||
]),
|
||||
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",
|
||||
Program([], [
|
||||
Designa(ID("cnt"), Numeral("I")),
|
||||
@@ -1290,7 +1290,7 @@ loop_edge_tests = [
|
||||
),
|
||||
ExpressionStatement(ID("cnt")),
|
||||
]),
|
||||
ValInt(3)),
|
||||
ValInt(4)),
|
||||
# DVM condition true from start — body never runs
|
||||
("DESIGNA x VT I\nDVM VERITAS FACE {\nDESIGNA x VT x + I\n}\nx",
|
||||
Program([], [
|
||||
@@ -1299,10 +1299,21 @@ loop_edge_tests = [
|
||||
ExpressionStatement(ID("x")),
|
||||
]),
|
||||
ValInt(1), ""),
|
||||
# single iteration: [I VSQVE II] = [1]
|
||||
# two iterations: [I VSQVE II] = [1, 2]
|
||||
("DONICVM i VT I VSQVE II FACE { DICE(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"),
|
||||
# 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):
|
||||
@@ -1427,7 +1438,7 @@ array_index_tests = [
|
||||
Program([], [Designa(ID("a"), DataArray([Numeral("X"), Numeral("XX"), Numeral("XXX")])), ExpressionStatement(ArrayIndex(ID("a"), Numeral("II")))]),
|
||||
ValInt(20)), # second element
|
||||
# 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
|
||||
("[I, II, III][I + I]",
|
||||
Program([], [ExpressionStatement(ArrayIndex(
|
||||
@@ -1596,15 +1607,15 @@ scope_tests = [
|
||||
]),
|
||||
ValInt(100)),
|
||||
# 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",
|
||||
Program([], [
|
||||
PerStatement(DataRangeArray(Numeral("I"), Numeral("IV")), ID("i"), [Designa(ID("nop"), Numeral("I"))]),
|
||||
ExpressionStatement(ID("i")),
|
||||
]),
|
||||
ValInt(3)),
|
||||
ValInt(4)),
|
||||
# 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",
|
||||
Program([], [
|
||||
Designa(ID("cnt"), Numeral("I")),
|
||||
@@ -1614,7 +1625,7 @@ scope_tests = [
|
||||
]),
|
||||
ExpressionStatement(ID("cnt")),
|
||||
]),
|
||||
ValInt(4)),
|
||||
ValInt(5)),
|
||||
# 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",
|
||||
Program([], [
|
||||
|
||||
Reference in New Issue
Block a user