🐐 SENATVS
This commit is contained in:
@@ -236,6 +236,11 @@ Breaks out of the current loop (`DVM` or `PER`). Has no meaningful return value.
|
|||||||
|
|
||||||
Returns the length of `array` (element count) or `string` (character count) as an integer.
|
Returns the length of `array` (element count) or `string` (character count) as an integer.
|
||||||
|
|
||||||
|
### SENATVS
|
||||||
|
`SENATVS(bool, ...)` or `SENATVS([bool])`
|
||||||
|
|
||||||
|
Returns VERITAS if a strict majority of the arguments are VERITAS, FALSITAS otherwise. Also accepts a single array of booleans. All values must be booleans. Ties (even split) return FALSITAS.
|
||||||
|
|
||||||
## Modules
|
## Modules
|
||||||
Modules are additions to the base `CENTVRION` syntax. They add or change certain features. Modules are included in your code by having
|
Modules are additions to the base `CENTVRION` syntax. They add or change certain features. Modules are included in your code by having
|
||||||
|
|
||||||
|
|||||||
@@ -967,6 +967,16 @@ class BuiltIn(Node):
|
|||||||
for _ in range(to_remove):
|
for _ in range(to_remove):
|
||||||
arr.pop(random.randint(0, len(arr) - 1))
|
arr.pop(random.randint(0, len(arr) - 1))
|
||||||
return vtable, ValList(arr)
|
return vtable, ValList(arr)
|
||||||
|
case "SENATVS":
|
||||||
|
if len(params) == 1 and isinstance(params[0], ValList):
|
||||||
|
items = params[0].value()
|
||||||
|
else:
|
||||||
|
items = params
|
||||||
|
for p in items:
|
||||||
|
if not isinstance(p, ValBool):
|
||||||
|
raise CentvrionError("SENATVS requires boolean arguments")
|
||||||
|
true_count = sum(1 for p in items if p.value())
|
||||||
|
return vtable, ValBool(true_count > len(items) / 2)
|
||||||
case "LONGITVDO":
|
case "LONGITVDO":
|
||||||
if isinstance(params[0], (ValList, ValStr)):
|
if isinstance(params[0], (ValList, ValStr)):
|
||||||
return vtable, ValInt(len(params[0].value()))
|
return vtable, ValInt(len(params[0].value()))
|
||||||
|
|||||||
@@ -201,6 +201,14 @@ def _emit_builtin(node, ctx):
|
|||||||
lines.append(f"cent_semen({param_vars[0]});")
|
lines.append(f"cent_semen({param_vars[0]});")
|
||||||
lines.append(f"CentValue {tmp} = cent_null();")
|
lines.append(f"CentValue {tmp} = cent_null();")
|
||||||
|
|
||||||
|
case "SENATVS":
|
||||||
|
if param_vars:
|
||||||
|
arr_tmp = ctx.fresh_tmp() + "_arr"
|
||||||
|
lines.append(f"CentValue {arr_tmp}[] = {{{', '.join(param_vars)}}};")
|
||||||
|
lines.append(f"CentValue {tmp} = cent_senatus({arr_tmp}, {len(param_vars)});")
|
||||||
|
else:
|
||||||
|
lines.append(f"CentValue {tmp} = cent_senatus(NULL, 0);")
|
||||||
|
|
||||||
case "ERVMPE":
|
case "ERVMPE":
|
||||||
# break as expression (side-effecting; result is unused)
|
# break as expression (side-effecting; result is unused)
|
||||||
lines.append("break;")
|
lines.append("break;")
|
||||||
|
|||||||
@@ -533,6 +533,21 @@ CentValue cent_fortis_electionis(CentValue lst) {
|
|||||||
return lst.lval.items[rand() % lst.lval.len];
|
return lst.lval.items[rand() % lst.lval.len];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CentValue cent_senatus(CentValue *args, int n) {
|
||||||
|
/* Single array argument: unpack it */
|
||||||
|
if (n == 1 && args[0].type == CENT_LIST) {
|
||||||
|
n = args[0].lval.len;
|
||||||
|
args = args[0].lval.items;
|
||||||
|
}
|
||||||
|
int true_count = 0;
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
if (args[i].type != CENT_BOOL)
|
||||||
|
cent_type_error("'SENATVS' requires boolean arguments");
|
||||||
|
if (args[i].bval) true_count++;
|
||||||
|
}
|
||||||
|
return cent_bool(true_count * 2 > n);
|
||||||
|
}
|
||||||
|
|
||||||
CentValue cent_decimatio(CentValue lst) {
|
CentValue cent_decimatio(CentValue lst) {
|
||||||
if (lst.type != CENT_LIST)
|
if (lst.type != CENT_LIST)
|
||||||
cent_type_error("'DECIMATIO' requires a list");
|
cent_type_error("'DECIMATIO' requires a list");
|
||||||
|
|||||||
@@ -180,6 +180,7 @@ CentValue cent_fortis_electionis(CentValue lst); /* FORTIS_ELECTIONIS *
|
|||||||
CentValue cent_decimatio(CentValue lst); /* DECIMATIO */
|
CentValue cent_decimatio(CentValue lst); /* DECIMATIO */
|
||||||
void cent_semen(CentValue seed); /* SEMEN */
|
void cent_semen(CentValue seed); /* SEMEN */
|
||||||
void cent_everro(void); /* EVERRO */
|
void cent_everro(void); /* EVERRO */
|
||||||
|
CentValue cent_senatus(CentValue *args, int n); /* SENATVS */
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* Array helpers */
|
/* Array helpers */
|
||||||
|
|||||||
@@ -45,7 +45,8 @@ builtin_tokens = [("BUILTIN", i) for i in [
|
|||||||
"FORTIS_NVMERVS",
|
"FORTIS_NVMERVS",
|
||||||
"FORTIS_ELECTIONIS",
|
"FORTIS_ELECTIONIS",
|
||||||
"LONGITVDO",
|
"LONGITVDO",
|
||||||
"SEMEN"
|
"SEMEN",
|
||||||
|
"SENATVS"
|
||||||
]]
|
]]
|
||||||
|
|
||||||
data_tokens = [
|
data_tokens = [
|
||||||
|
|||||||
25
tests.py
25
tests.py
@@ -545,6 +545,28 @@ builtin_tests = [
|
|||||||
("CVM FORS\nDECIMATIO([])", Program([ModuleCall("FORS")], [ExpressionStatement(BuiltIn("DECIMATIO", [DataArray([])]))]), ValList([])),
|
("CVM FORS\nDECIMATIO([])", Program([ModuleCall("FORS")], [ExpressionStatement(BuiltIn("DECIMATIO", [DataArray([])]))]), ValList([])),
|
||||||
# DECIMATIO: seed 42, 20 elements → removes 2 (elements I and IV)
|
# DECIMATIO: seed 42, 20 elements → removes 2 (elements I and IV)
|
||||||
("CVM FORS\nSEMEN(XLII)\nDECIMATIO([I, II, III, IV, V, VI, VII, VIII, IX, X, XI, XII, XIII, XIV, XV, XVI, XVII, XVIII, XIX, XX])", Program([ModuleCall("FORS")], [ExpressionStatement(BuiltIn("SEMEN", [Numeral("XLII")])), ExpressionStatement(BuiltIn("DECIMATIO", [DataArray([Numeral("I"), Numeral("II"), Numeral("III"), Numeral("IV"), Numeral("V"), Numeral("VI"), Numeral("VII"), Numeral("VIII"), Numeral("IX"), Numeral("X"), Numeral("XI"), Numeral("XII"), Numeral("XIII"), Numeral("XIV"), Numeral("XV"), Numeral("XVI"), Numeral("XVII"), Numeral("XVIII"), Numeral("XIX"), Numeral("XX")])]))]), ValList([ValInt(2), ValInt(3), ValInt(5), ValInt(6), ValInt(7), ValInt(8), ValInt(9), ValInt(10), ValInt(11), ValInt(12), ValInt(13), ValInt(14), ValInt(15), ValInt(16), ValInt(17), ValInt(18), ValInt(19), ValInt(20)])),
|
("CVM FORS\nSEMEN(XLII)\nDECIMATIO([I, II, III, IV, V, VI, VII, VIII, IX, X, XI, XII, XIII, XIV, XV, XVI, XVII, XVIII, XIX, XX])", Program([ModuleCall("FORS")], [ExpressionStatement(BuiltIn("SEMEN", [Numeral("XLII")])), ExpressionStatement(BuiltIn("DECIMATIO", [DataArray([Numeral("I"), Numeral("II"), Numeral("III"), Numeral("IV"), Numeral("V"), Numeral("VI"), Numeral("VII"), Numeral("VIII"), Numeral("IX"), Numeral("X"), Numeral("XI"), Numeral("XII"), Numeral("XIII"), Numeral("XIV"), Numeral("XV"), Numeral("XVI"), Numeral("XVII"), Numeral("XVIII"), Numeral("XIX"), Numeral("XX")])]))]), ValList([ValInt(2), ValInt(3), ValInt(5), ValInt(6), ValInt(7), ValInt(8), ValInt(9), ValInt(10), ValInt(11), ValInt(12), ValInt(13), ValInt(14), ValInt(15), ValInt(16), ValInt(17), ValInt(18), ValInt(19), ValInt(20)])),
|
||||||
|
# SENATVS: majority true → VERITAS
|
||||||
|
("SENATVS(VERITAS, VERITAS, FALSITAS)", Program([], [ExpressionStatement(BuiltIn("SENATVS", [Bool(True), Bool(True), Bool(False)]))]), ValBool(True)),
|
||||||
|
# SENATVS: majority false → FALSITAS
|
||||||
|
("SENATVS(FALSITAS, FALSITAS, VERITAS)", Program([], [ExpressionStatement(BuiltIn("SENATVS", [Bool(False), Bool(False), Bool(True)]))]), ValBool(False)),
|
||||||
|
# SENATVS: tie → FALSITAS
|
||||||
|
("SENATVS(VERITAS, FALSITAS)", Program([], [ExpressionStatement(BuiltIn("SENATVS", [Bool(True), Bool(False)]))]), ValBool(False)),
|
||||||
|
# SENATVS: 4-arg tie → FALSITAS
|
||||||
|
("SENATVS(VERITAS, VERITAS, FALSITAS, FALSITAS)", Program([], [ExpressionStatement(BuiltIn("SENATVS", [Bool(True), Bool(True), Bool(False), Bool(False)]))]), ValBool(False)),
|
||||||
|
# SENATVS: single true → VERITAS
|
||||||
|
("SENATVS(VERITAS)", Program([], [ExpressionStatement(BuiltIn("SENATVS", [Bool(True)]))]), ValBool(True)),
|
||||||
|
# SENATVS: single false → FALSITAS
|
||||||
|
("SENATVS(FALSITAS)", Program([], [ExpressionStatement(BuiltIn("SENATVS", [Bool(False)]))]), ValBool(False)),
|
||||||
|
# SENATVS: empty → FALSITAS (vacuous)
|
||||||
|
("SENATVS()", Program([], [ExpressionStatement(BuiltIn("SENATVS", []))]), ValBool(False)),
|
||||||
|
# SENATVS: all true <20><> VERITAS
|
||||||
|
("SENATVS(VERITAS, VERITAS, VERITAS, VERITAS, VERITAS)", Program([], [ExpressionStatement(BuiltIn("SENATVS", [Bool(True), Bool(True), Bool(True), Bool(True), Bool(True)]))]), ValBool(True)),
|
||||||
|
# SENATVS: array input, majority true → VERITAS
|
||||||
|
("SENATVS([VERITAS, VERITAS, FALSITAS])", Program([], [ExpressionStatement(BuiltIn("SENATVS", [DataArray([Bool(True), Bool(True), Bool(False)])]))]), ValBool(True)),
|
||||||
|
# SENATVS: array input, majority false → FALSITAS
|
||||||
|
("SENATVS([FALSITAS, FALSITAS, VERITAS])", Program([], [ExpressionStatement(BuiltIn("SENATVS", [DataArray([Bool(False), Bool(False), Bool(True)])]))]), ValBool(False)),
|
||||||
|
# SENATVS: array input, empty → FALSITAS
|
||||||
|
("SENATVS([])", Program([], [ExpressionStatement(BuiltIn("SENATVS", [DataArray([])]))]), ValBool(False)),
|
||||||
]
|
]
|
||||||
|
|
||||||
class TestBuiltins(unittest.TestCase):
|
class TestBuiltins(unittest.TestCase):
|
||||||
@@ -588,6 +610,9 @@ error_tests = [
|
|||||||
("DECIMATIO([I, II, III])", CentvrionError), # FORS required for DECIMATIO
|
("DECIMATIO([I, II, III])", CentvrionError), # FORS required for DECIMATIO
|
||||||
("CVM FORS\nDECIMATIO(I)", CentvrionError), # DECIMATIO requires an array
|
("CVM FORS\nDECIMATIO(I)", CentvrionError), # DECIMATIO requires an array
|
||||||
("LONGITVDO(I)", CentvrionError), # LONGITVDO on non-array
|
("LONGITVDO(I)", CentvrionError), # LONGITVDO on non-array
|
||||||
|
("SENATVS(I)", CentvrionError), # SENATVS requires booleans
|
||||||
|
("SENATVS(VERITAS, I)", CentvrionError), # SENATVS mixed types
|
||||||
|
("SENATVS([I, II, III])", CentvrionError), # SENATVS array of non-bools
|
||||||
("DESIGNA x VT I\nINVOCA x ()", CentvrionError), # invoking a non-function
|
("DESIGNA x VT I\nINVOCA x ()", CentvrionError), # invoking a non-function
|
||||||
("SI I TVNC { DESIGNA r VT I }", CentvrionError), # non-bool SI condition: int
|
("SI I TVNC { DESIGNA r VT I }", CentvrionError), # non-bool SI condition: int
|
||||||
("IIIS", CentvrionError), # fraction without FRACTIO module
|
("IIIS", CentvrionError), # fraction without FRACTIO module
|
||||||
|
|||||||
Reference in New Issue
Block a user