🐐 SEMEN
This commit is contained in:
@@ -221,12 +221,14 @@ Vnlike many other programming languages with modules, the modules in `CENTVRION`
|
|||||||
### FORS
|
### FORS
|
||||||

|

|
||||||
|
|
||||||
The `FORS` module allows you to add randomness to your `CENTVRION` program. It adds 2 new built-in functions: `FORTIS_NVMERVS int int` and `FORTIS_ELECTIONIS ['a]`.
|
The `FORS` module allows you to add randomness to your `CENTVRION` program. It adds 3 new built-in functions: `FORTIS_NVMERVS int int`, `FORTIS_ELECTIONIS ['a]`, and `SEMEN int`.
|
||||||
|
|
||||||
`FORTIS_NVMERVS int int` picks a random int in the (inclusive) range of the two given ints.
|
`FORTIS_NVMERVS int int` picks a random int in the (inclusive) range of the two given ints.
|
||||||
|
|
||||||
`FORTIS_ELECTIONIS ['a]` picks a random element from the given array. `FORTIS_ELECTIONIS array` is identical to ```array[FORTIS_NVMERVS NVLLVS ((LONGITVDO array)-I)]```.
|
`FORTIS_ELECTIONIS ['a]` picks a random element from the given array. `FORTIS_ELECTIONIS array` is identical to ```array[FORTIS_NVMERVS NVLLVS ((LONGITVDO array)-I)]```.
|
||||||
|
|
||||||
|
`SEMEN int` seeds the random number generator for reproducibility.
|
||||||
|
|
||||||
### FRACTIO
|
### FRACTIO
|
||||||

|

|
||||||
|
|
||||||
|
|||||||
@@ -920,6 +920,14 @@ class BuiltIn(Node):
|
|||||||
if len(lst) == 0:
|
if len(lst) == 0:
|
||||||
raise CentvrionError("FORTIS_ELECTIONIS: cannot select from an empty array")
|
raise CentvrionError("FORTIS_ELECTIONIS: cannot select from an empty array")
|
||||||
return vtable, lst[random.randint(0, len(lst) - 1)]
|
return vtable, lst[random.randint(0, len(lst) - 1)]
|
||||||
|
case "SEMEN":
|
||||||
|
if "FORS" not in vtable["#modules"]:
|
||||||
|
raise CentvrionError("Cannot use 'SEMEN' without module 'FORS'")
|
||||||
|
seed = params[0].value()
|
||||||
|
if not isinstance(seed, int):
|
||||||
|
raise CentvrionError("SEMEN requires an integer seed")
|
||||||
|
random.seed(seed)
|
||||||
|
return vtable, ValNul()
|
||||||
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()))
|
||||||
|
|||||||
@@ -186,6 +186,14 @@ def _emit_builtin(node, ctx):
|
|||||||
else:
|
else:
|
||||||
lines.append(f"CentValue {tmp} = cent_fortis_electionis({param_vars[0]});")
|
lines.append(f"CentValue {tmp} = cent_fortis_electionis({param_vars[0]});")
|
||||||
|
|
||||||
|
case "SEMEN":
|
||||||
|
if not ctx.has_module("FORS"):
|
||||||
|
lines.append('cent_runtime_error("FORS module required for SEMEN");')
|
||||||
|
lines.append(f"CentValue {tmp} = cent_null();")
|
||||||
|
else:
|
||||||
|
lines.append(f"cent_semen({param_vars[0]});")
|
||||||
|
lines.append(f"CentValue {tmp} = cent_null();")
|
||||||
|
|
||||||
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,12 @@ CentValue cent_fortis_electionis(CentValue lst) {
|
|||||||
return lst.lval.items[rand() % lst.lval.len];
|
return lst.lval.items[rand() % lst.lval.len];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cent_semen(CentValue seed) {
|
||||||
|
if (seed.type != CENT_INT)
|
||||||
|
cent_type_error("'SEMEN' requires an integer seed");
|
||||||
|
srand((unsigned)seed.ival);
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* Array helpers */
|
/* Array helpers */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
|
|||||||
@@ -177,6 +177,7 @@ CentValue cent_avdi_numerus(void); /* AVDI_NVMERVS */
|
|||||||
CentValue cent_longitudo(CentValue v); /* LONGITVDO */
|
CentValue cent_longitudo(CentValue v); /* LONGITVDO */
|
||||||
CentValue cent_fortis_numerus(CentValue lo, CentValue hi); /* FORTIS_NVMERVS */
|
CentValue cent_fortis_numerus(CentValue lo, CentValue hi); /* FORTIS_NVMERVS */
|
||||||
CentValue cent_fortis_electionis(CentValue lst); /* FORTIS_ELECTIONIS */
|
CentValue cent_fortis_electionis(CentValue lst); /* FORTIS_ELECTIONIS */
|
||||||
|
void cent_semen(CentValue seed); /* SEMEN */
|
||||||
void cent_everro(void); /* EVERRO */
|
void cent_everro(void); /* EVERRO */
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
|
|||||||
@@ -41,7 +41,8 @@ builtin_tokens = [("BUILTIN", i) for i in [
|
|||||||
"EVERRO",
|
"EVERRO",
|
||||||
"FORTIS_NVMERVS",
|
"FORTIS_NVMERVS",
|
||||||
"FORTIS_ELECTIONIS",
|
"FORTIS_ELECTIONIS",
|
||||||
"LONGITVDO"
|
"LONGITVDO",
|
||||||
|
"SEMEN"
|
||||||
]]
|
]]
|
||||||
|
|
||||||
data_tokens = [
|
data_tokens = [
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ contexts:
|
|||||||
scope: constant.language.centvrion
|
scope: constant.language.centvrion
|
||||||
|
|
||||||
builtins:
|
builtins:
|
||||||
- match: '\b(AVDI_NVMERVS|AVDI|DICE|FORTIS_NVMERVS|FORTIS_ELECTIONIS|LONGITVDO)\b'
|
- match: '\b(AVDI_NVMERVS|AVDI|DICE|FORTIS_NVMERVS|FORTIS_ELECTIONIS|LONGITVDO|SEMEN)\b'
|
||||||
scope: support.function.builtin.centvrion
|
scope: support.function.builtin.centvrion
|
||||||
|
|
||||||
modules:
|
modules:
|
||||||
|
|||||||
3
tests.py
3
tests.py
@@ -460,6 +460,7 @@ builtin_tests = [
|
|||||||
('LONGITVDO("salve")', Program([], [ExpressionStatement(BuiltIn("LONGITVDO", [String("salve")]))]), ValInt(5)),
|
('LONGITVDO("salve")', Program([], [ExpressionStatement(BuiltIn("LONGITVDO", [String("salve")]))]), ValInt(5)),
|
||||||
('LONGITVDO("")', Program([], [ExpressionStatement(BuiltIn("LONGITVDO", [String("")]))]), ValInt(0)),
|
('LONGITVDO("")', Program([], [ExpressionStatement(BuiltIn("LONGITVDO", [String("")]))]), ValInt(0)),
|
||||||
("CVM FORS\nFORTIS_ELECTIONIS([I, II, III])", Program([ModuleCall("FORS")], [ExpressionStatement(BuiltIn("FORTIS_ELECTIONIS", [DataArray([Numeral("I"), Numeral("II"), Numeral("III")])]))]), ValInt(1)),
|
("CVM FORS\nFORTIS_ELECTIONIS([I, II, III])", Program([ModuleCall("FORS")], [ExpressionStatement(BuiltIn("FORTIS_ELECTIONIS", [DataArray([Numeral("I"), Numeral("II"), Numeral("III")])]))]), ValInt(1)),
|
||||||
|
("CVM FORS\nSEMEN(XLII)\nFORTIS_NVMERVS(I, C)", Program([ModuleCall("FORS")], [ExpressionStatement(BuiltIn("SEMEN", [Numeral("XLII")])), ExpressionStatement(BuiltIn("FORTIS_NVMERVS", [Numeral("I"), Numeral("C")]))]), ValInt(82)),
|
||||||
]
|
]
|
||||||
|
|
||||||
class TestBuiltins(unittest.TestCase):
|
class TestBuiltins(unittest.TestCase):
|
||||||
@@ -494,6 +495,8 @@ error_tests = [
|
|||||||
("\"hello\" MINVS \"world\"", CentvrionError), # comparison with strings
|
("\"hello\" MINVS \"world\"", CentvrionError), # comparison with strings
|
||||||
("I[I]", CentvrionError), # indexing a non-array
|
("I[I]", CentvrionError), # indexing a non-array
|
||||||
("DESIGNA x VT I\nDESIGNA x[I] VT II", CentvrionError), # index-assign to non-array
|
("DESIGNA x VT I\nDESIGNA x[I] VT II", CentvrionError), # index-assign to non-array
|
||||||
|
("SEMEN(I)", CentvrionError), # requires FORS module
|
||||||
|
('CVM FORS\nSEMEN("abc")', CentvrionError), # SEMEN requires integer seed
|
||||||
("FORTIS_ELECTIONIS([])", CentvrionError), # FORS required for FORTIS_ELECTIONIS
|
("FORTIS_ELECTIONIS([])", CentvrionError), # FORS required for FORTIS_ELECTIONIS
|
||||||
("CVM FORS\nFORTIS_ELECTIONIS([])", CentvrionError), # FORTIS_ELECTIONIS on empty array
|
("CVM FORS\nFORTIS_ELECTIONIS([])", CentvrionError), # FORTIS_ELECTIONIS on empty array
|
||||||
("CVM FORS\nFORTIS_NVMERVS(X, I)", CentvrionError), # FORTIS_NVMERVS a > b
|
("CVM FORS\nFORTIS_NVMERVS(X, I)", CentvrionError), # FORTIS_NVMERVS a > b
|
||||||
|
|||||||
Reference in New Issue
Block a user