🐐 Fixing latin

This commit is contained in:
2026-04-21 23:46:00 +02:00
parent 4f78450756
commit ebea9f942b
47 changed files with 337 additions and 337 deletions

View File

@@ -171,19 +171,19 @@ Will return `I` (1), as the conditional evaluates `x` to be true.
### Boolean expressions ### Boolean expressions
In conditionals, `EST` functions as an equality evaluation, `DISPAR` as not-equal, and `MINVS` (<) and `PLVS` (>) function as inequality evaluation. In conditionals, `EST` functions as an equality evaluation, `DISPAR` as not-equal, and `MINVS` (<) and `PLVS` (>) function as inequality evaluation.
### ALVID ### ALIVD
When using `SI`/`TVNC` statements, you can also use `ALVID` as an "else". When using `SI`/`TVNC` statements, you can also use `ALIVD` as an "else".
![ALVID](snippets/alvid.png) ![ALIVD](snippets/alivd.png)
``` ```
> I > I
``` ```
`SI` statements may follow immediately after `ALVID`. `SI` statements may follow immediately after `ALIVD`.
![ALVID SI](snippets/alvid_si.png) ![ALIVD SI](snippets/alivd_si.png)
``` ```
> II > II
@@ -218,8 +218,8 @@ The keyword `ET` can be used as a boolean "and". The keyword `AVT` can be used a
### AETERNVM loops ### AETERNVM loops
`AETERNVM FACE { ... }` is shorthand for an infinite loop — equivalent `AETERNVM FAC { ... }` is shorthand for an infinite loop — equivalent
to `DVM FALSITAS FACE { ... }` but without relying on `DVM`'s inverted to `DVM FALSITAS FAC { ... }` but without relying on `DVM`'s inverted
condition. Exit the loop with `ERVMPE` (or `REDI` from inside a function). condition. Exit the loop with `ERVMPE` (or `REDI` from inside a function).
![AETERNVM loop](snippets/aeternvm.png) ![AETERNVM loop](snippets/aeternvm.png)
@@ -248,7 +248,7 @@ Errors can be caught using `TEMPTA` (temptare = to try) and `CAPE` (capere = to
TEMPTA { TEMPTA {
DESIGNA x VT I / NVLLVS DESIGNA x VT I / NVLLVS
} CAPE error { } CAPE error {
DICE(error) DIC(error)
} }
``` ```
@@ -292,12 +292,12 @@ Anonymous functions are created with the `FVNCTIO` keyword:
Note: CENTVRION does **not** have closures. When a function is called, it receives a copy of the *caller's* scope, not the scope where it was defined. Variables from a function's definition site are only available if they also exist in the caller's scope at call time. Note: CENTVRION does **not** have closures. When a function is called, it receives a copy of the *caller's* scope, not the scope where it was defined. Variables from a function's definition site are only available if they also exist in the caller's scope at call time.
## Built-ins ## Built-ins
### DICE ### DIC
`DICE(value, ...)` `DIC(value, ...)`
Prints one or more values to stdout, space-separated, with integers rendered as Roman numerals. Returns the printed string. Prints one or more values to stdout, space-separated, with integers rendered as Roman numerals. Returns the printed string.
![DICE](snippets/dice.png) ![DIC](snippets/dic.png)
### AVDI ### AVDI
`AVDI()` `AVDI()`
@@ -361,11 +361,11 @@ Vnlike many other programming languages with modules, the modules in `CENTVRION`
### FORS ### FORS
![CVM FORS](snippets/fors.png) ![CVM FORS](snippets/fors.png)
The `FORS` module allows you to add randomness to your `CENTVRION` program. It adds 4 new built-in functions: `FORTIS_NVMERVS int int`, `FORTIS_ELECTIONIS ['a]`, `DECIMATIO ['a]`, and `SEMEN int`. The `FORS` module allows you to add randomness to your `CENTVRION` program. It adds 4 new built-in functions: `FORTVITVS_NVMERVS int int`, `FORTVITA_ELECTIO ['a]`, `DECIMATIO ['a]`, and `SEMEN int`.
`FORTIS_NVMERVS int int` picks a random int in the (inclusive) range of the two given ints. `FORTVITVS_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)]```. `FORTVITA_ELECTIO ['a]` picks a random element from the given array. `FORTVITA_ELECTIO array` is identical to ```array[FORTVITVS_NVMERVS NVLLVS ((LONGITVDO array)-I)]```.
`DECIMATIO ['a]` returns a copy of the given array with a random tenth of its elements removed. Arrays with fewer than 10 elements are returned unchanged. `DECIMATIO ['a]` returns a copy of the given array with a random tenth of its elements removed. Arrays with fewer than 10 elements are returned unchanged.

View File

@@ -935,7 +935,7 @@ class SiStatement(Node):
result = f"SI {self.test.print()} TVNC {{\n{body}\n}}" result = f"SI {self.test.print()} TVNC {{\n{body}\n}}"
if self.else_part: if self.else_part:
else_body = "\n".join(s.print() for s in self.else_part) else_body = "\n".join(s.print() for s in self.else_part)
result += f" ALVID {{\n{else_body}\n}}" result += f" ALIVD {{\n{else_body}\n}}"
return result return result
def _eval(self, vtable): def _eval(self, vtable):
@@ -972,7 +972,7 @@ class DumStatement(Node):
def print(self): def print(self):
body = "\n".join(s.print() for s in self.statements) body = "\n".join(s.print() for s in self.statements)
return f"DVM {self.test.print()} FACE {{\n{body}\n}}" return f"DVM {self.test.print()} FAC {{\n{body}\n}}"
def _eval(self, vtable): def _eval(self, vtable):
last_val = ValNul() last_val = ValNul()
@@ -1016,7 +1016,7 @@ class PerStatement(Node):
def print(self): def print(self):
body = "\n".join(s.print() for s in self.statements) body = "\n".join(s.print() for s in self.statements)
return f"PER {self.variable_name.print()} IN {self.data_list.print()} FACE {{\n{body}\n}}" return f"PER {self.variable_name.print()} IN {self.data_list.print()} FAC {{\n{body}\n}}"
def _eval(self, vtable): def _eval(self, vtable):
vtable, array = self.data_list.eval(vtable) vtable, array = self.data_list.eval(vtable)
@@ -1158,7 +1158,7 @@ class BuiltIn(Node):
raise CentvrionError(f"Invalid numeral input: {raw!r}") raise CentvrionError(f"Invalid numeral input: {raw!r}")
case "AVDI": case "AVDI":
return vtable, ValStr(input()) return vtable, ValStr(input())
case "DICE": case "DIC":
print_string = ' '.join( print_string = ' '.join(
make_string(i, magnvm, svbnvlla) for i in params make_string(i, magnvm, svbnvlla) for i in params
) )
@@ -1167,23 +1167,23 @@ class BuiltIn(Node):
case "ERVMPE": case "ERVMPE":
vtable["#break"] = True vtable["#break"] = True
return vtable, ValNul() return vtable, ValNul()
case "FORTIS_NVMERVS": case "FORTVITVS_NVMERVS":
if "FORS" not in vtable["#modules"]: if "FORS" not in vtable["#modules"]:
raise CentvrionError("Cannot use 'FORTIS_NVMERVS' without module 'FORS'") raise CentvrionError("Cannot use 'FORTVITVS_NVMERVS' without module 'FORS'")
a, b = params[0].value(), params[1].value() a, b = params[0].value(), params[1].value()
if not isinstance(a, int) or not isinstance(b, int): if not isinstance(a, int) or not isinstance(b, int):
raise CentvrionError("FORTIS_NVMERVS requires two numbers") raise CentvrionError("FORTVITVS_NVMERVS requires two numbers")
if a > b: if a > b:
raise CentvrionError(f"FORTIS_NVMERVS: first argument ({a}) must be ≤ second ({b})") raise CentvrionError(f"FORTVITVS_NVMERVS: first argument ({a}) must be ≤ second ({b})")
return vtable, ValInt(random.randint(a, b)) return vtable, ValInt(random.randint(a, b))
case "FORTIS_ELECTIONIS": case "FORTVITA_ELECTIO":
if "FORS" not in vtable["#modules"]: if "FORS" not in vtable["#modules"]:
raise CentvrionError("Cannot use 'FORTIS_ELECTIONIS' without module 'FORS'") raise CentvrionError("Cannot use 'FORTVITA_ELECTIO' without module 'FORS'")
if not isinstance(params[0], ValList): if not isinstance(params[0], ValList):
raise CentvrionError("FORTIS_ELECTIONIS requires an array") raise CentvrionError("FORTVITA_ELECTIO requires an array")
lst = params[0].value() lst = params[0].value()
if len(lst) == 0: if len(lst) == 0:
raise CentvrionError("FORTIS_ELECTIONIS: cannot select from an empty array") raise CentvrionError("FORTVITA_ELECTIO: 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": case "SEMEN":
if "FORS" not in vtable["#modules"]: if "FORS" not in vtable["#modules"]:
@@ -1222,7 +1222,7 @@ class BuiltIn(Node):
raise CentvrionError("CLAVES requires a dict") raise CentvrionError("CLAVES requires a dict")
keys = [ValStr(k) if isinstance(k, str) else ValInt(k) for k in params[0].value().keys()] keys = [ValStr(k) if isinstance(k, str) else ValInt(k) for k in params[0].value().keys()]
return vtable, ValList(keys) return vtable, ValList(keys)
case "EVERRO": case "EVERRE":
print("\033[2J\033[H", end="", flush=True) print("\033[2J\033[H", end="", flush=True)
return vtable, ValNul() return vtable, ValNul()
case "ORDINA": case "ORDINA":

View File

@@ -188,12 +188,12 @@ def _emit_builtin(node, ctx):
tmp = ctx.fresh_tmp() tmp = ctx.fresh_tmp()
match node.builtin: match node.builtin:
case "DICE": case "DIC":
if not param_vars: if not param_vars:
lines.append('cent_dice(cent_str(""));') lines.append('cent_dic(cent_str(""));')
lines.append(f'CentValue {tmp} = cent_str("");') lines.append(f'CentValue {tmp} = cent_str("");')
elif len(param_vars) == 1: elif len(param_vars) == 1:
lines.append(f"cent_dice({param_vars[0]});") lines.append(f"cent_dic({param_vars[0]});")
lines.append(f"CentValue {tmp} = {param_vars[0]};") lines.append(f"CentValue {tmp} = {param_vars[0]};")
else: else:
acc = param_vars[0] acc = param_vars[0]
@@ -203,7 +203,7 @@ def _emit_builtin(node, ctx):
lines.append(f'CentValue {space_tmp} = cent_concat({acc}, cent_str(" "));') lines.append(f'CentValue {space_tmp} = cent_concat({acc}, cent_str(" "));')
lines.append(f"CentValue {joined_tmp} = cent_concat({space_tmp}, {pv});") lines.append(f"CentValue {joined_tmp} = cent_concat({space_tmp}, {pv});")
acc = joined_tmp acc = joined_tmp
lines.append(f"cent_dice({acc});") lines.append(f"cent_dic({acc});")
lines.append(f"CentValue {tmp} = {acc};") lines.append(f"CentValue {tmp} = {acc};")
case "AVDI": case "AVDI":
@@ -215,19 +215,19 @@ def _emit_builtin(node, ctx):
case "LONGITVDO": case "LONGITVDO":
lines.append(f"CentValue {tmp} = cent_longitudo({param_vars[0]});") lines.append(f"CentValue {tmp} = cent_longitudo({param_vars[0]});")
case "FORTIS_NVMERVS": case "FORTVITVS_NVMERVS":
if not ctx.has_module("FORS"): if not ctx.has_module("FORS"):
lines.append('cent_runtime_error("FORS module required for FORTIS_NVMERVS");') lines.append('cent_runtime_error("FORS module required for FORTVITVS_NVMERVS");')
lines.append(f"CentValue {tmp} = cent_null();") lines.append(f"CentValue {tmp} = cent_null();")
else: else:
lines.append(f"CentValue {tmp} = cent_fortis_numerus({param_vars[0]}, {param_vars[1]});") lines.append(f"CentValue {tmp} = cent_fortuitus_numerus({param_vars[0]}, {param_vars[1]});")
case "FORTIS_ELECTIONIS": case "FORTVITA_ELECTIO":
if not ctx.has_module("FORS"): if not ctx.has_module("FORS"):
lines.append('cent_runtime_error("FORS module required for FORTIS_ELECTIONIS");') lines.append('cent_runtime_error("FORS module required for FORTVITA_ELECTIO");')
lines.append(f"CentValue {tmp} = cent_null();") lines.append(f"CentValue {tmp} = cent_null();")
else: else:
lines.append(f"CentValue {tmp} = cent_fortis_electionis({param_vars[0]});") lines.append(f"CentValue {tmp} = cent_fortuita_electionis({param_vars[0]});")
case "DECIMATIO": case "DECIMATIO":
if not ctx.has_module("FORS"): if not ctx.has_module("FORS"):
@@ -263,8 +263,8 @@ def _emit_builtin(node, ctx):
case "ORDINA": case "ORDINA":
lines.append(f"CentValue {tmp} = cent_ordina({param_vars[0]});") lines.append(f"CentValue {tmp} = cent_ordina({param_vars[0]});")
case "EVERRO": case "EVERRE":
lines.append("cent_everro();") lines.append("cent_everre();")
lines.append(f"CentValue {tmp} = cent_null();") lines.append(f"CentValue {tmp} = cent_null();")
case "TYPVS": case "TYPVS":

View File

@@ -521,13 +521,13 @@ CentValue cent_or(CentValue a, CentValue b) {
/* Builtin functions */ /* Builtin functions */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
void cent_dice(CentValue v) { void cent_dic(CentValue v) {
char *s = cent_make_string(v); char *s = cent_make_string(v);
fputs(s, stdout); fputs(s, stdout);
fputc('\n', stdout); fputc('\n', stdout);
} }
void cent_everro(void) { void cent_everre(void) {
fputs("\033[2J\033[H", stdout); fputs("\033[2J\033[H", stdout);
fflush(stdout); fflush(stdout);
} }
@@ -622,20 +622,20 @@ void cent_adivnge(CentValue path, CentValue content) {
fclose(f); fclose(f);
} }
CentValue cent_fortis_numerus(CentValue lo, CentValue hi) { CentValue cent_fortuitus_numerus(CentValue lo, CentValue hi) {
if (lo.type != CENT_INT || hi.type != CENT_INT) if (lo.type != CENT_INT || hi.type != CENT_INT)
cent_type_error("'FORTIS_NVMERVS' requires two integers"); cent_type_error("'FORTVITVS_NVMERVS' requires two integers");
long range = hi.ival - lo.ival + 1; long range = hi.ival - lo.ival + 1;
if (range <= 0) if (range <= 0)
cent_runtime_error("'FORTIS_NVMERVS' requires lo <= hi"); cent_runtime_error("'FORTVITVS_NVMERVS' requires lo <= hi");
return cent_int(lo.ival + rand() % range); return cent_int(lo.ival + rand() % range);
} }
CentValue cent_fortis_electionis(CentValue lst) { CentValue cent_fortuita_electionis(CentValue lst) {
if (lst.type != CENT_LIST) if (lst.type != CENT_LIST)
cent_type_error("'FORTIS_ELECTIONIS' requires a list"); cent_type_error("'FORTVITA_ELECTIO' requires a list");
if (lst.lval.len == 0) if (lst.lval.len == 0)
cent_runtime_error("'FORTIS_ELECTIONIS' requires a non-empty list"); cent_runtime_error("'FORTVITA_ELECTIO' requires a non-empty list");
return lst.lval.items[rand() % lst.lval.len]; return lst.lval.items[rand() % lst.lval.len];
} }

View File

@@ -216,15 +216,15 @@ CentValue cent_or (CentValue a, CentValue b); /* AVT → BOOL */
/* Builtin functions */ /* Builtin functions */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
void cent_dice(CentValue v); /* DICE */ void cent_dic(CentValue v); /* DIC */
CentValue cent_avdi(void); /* AVDI */ CentValue cent_avdi(void); /* AVDI */
CentValue cent_avdi_numerus(void); /* AVDI_NVMERVS */ 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_fortuitus_numerus(CentValue lo, CentValue hi); /* FORTVITVS_NVMERVS */
CentValue cent_fortis_electionis(CentValue lst); /* FORTIS_ELECTIONIS */ CentValue cent_fortuita_electionis(CentValue lst); /* FORTVITA_ELECTIO */
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_everre(void); /* EVERRE */
CentValue cent_senatus(CentValue *args, int n); /* SENATVS */ CentValue cent_senatus(CentValue *args, int n); /* SENATVS */
CentValue cent_typvs(CentValue v); /* TYPVS */ CentValue cent_typvs(CentValue v); /* TYPVS */
void cent_dormi(CentValue n); /* DORMI */ void cent_dormi(CentValue n); /* DORMI */

View File

@@ -4,7 +4,7 @@ valid_characters = '|'.join(list("abcdefghiklmnopqrstvxyz_"))
keyword_tokens = [("KEYWORD_"+i, i) for i in [ keyword_tokens = [("KEYWORD_"+i, i) for i in [
"AETERNVM", "AETERNVM",
"ALVID", "ALIVD",
"AVGE", "AVGE",
"CAPE", "CAPE",
"AVT", "AVT",
@@ -17,7 +17,7 @@ keyword_tokens = [("KEYWORD_"+i, i) for i in [
"ERVMPE", "ERVMPE",
"EST", "EST",
"ET", "ET",
"FACE", "FAC",
"FALSITAS", "FALSITAS",
"FVNCTIO", "FVNCTIO",
"INVOCA", "INVOCA",
@@ -45,11 +45,11 @@ builtin_tokens = [("BUILTIN", i) for i in [
"AVDI", "AVDI",
"CLAVES", "CLAVES",
"DECIMATIO", "DECIMATIO",
"DICE", "DIC",
"DORMI", "DORMI",
"EVERRO", "EVERRE",
"FORTIS_NVMERVS", "FORTVITVS_NVMERVS",
"FORTIS_ELECTIONIS", "FORTVITA_ELECTIO",
"LONGITVDO", "LONGITVDO",
"ORDINA", "ORDINA",
"SEMEN", "SEMEN",

View File

@@ -183,24 +183,24 @@ class Parser():
else: else:
return ast_nodes.SiStatement(tokens[1], tokens[4], None) return ast_nodes.SiStatement(tokens[1], tokens[4], None)
@self.pg.production('aluid_statement : KEYWORD_ALVID si_statement') @self.pg.production('aluid_statement : KEYWORD_ALIVD si_statement')
def aluid_si(tokens): def aluid_si(tokens):
return [tokens[1]] return [tokens[1]]
@self.pg.production('aluid_statement : KEYWORD_ALVID SYMBOL_LCURL statements SYMBOL_RCURL') @self.pg.production('aluid_statement : KEYWORD_ALIVD SYMBOL_LCURL statements SYMBOL_RCURL')
def aluid(tokens): def aluid(tokens):
return tokens[2] return tokens[2]
@self.pg.production('dum_statement : KEYWORD_DVM expression KEYWORD_FACE SYMBOL_LCURL statements SYMBOL_RCURL') @self.pg.production('dum_statement : KEYWORD_DVM expression KEYWORD_FAC SYMBOL_LCURL statements SYMBOL_RCURL')
def dum(tokens): def dum(tokens):
return ast_nodes.DumStatement(tokens[1], tokens[4]) return ast_nodes.DumStatement(tokens[1], tokens[4])
# AETERNVM is sugar for `DVM FALSITAS` — same AST, no observable difference. # AETERNVM is sugar for `DVM FALSITAS` — same AST, no observable difference.
@self.pg.production('dum_statement : KEYWORD_AETERNVM KEYWORD_FACE SYMBOL_LCURL statements SYMBOL_RCURL') @self.pg.production('dum_statement : KEYWORD_AETERNVM KEYWORD_FAC SYMBOL_LCURL statements SYMBOL_RCURL')
def aeternvm(tokens): def aeternvm(tokens):
return ast_nodes.DumStatement(ast_nodes.Bool(False), tokens[3]) return ast_nodes.DumStatement(ast_nodes.Bool(False), tokens[3])
@self.pg.production('per_statement : KEYWORD_PER id KEYWORD_IN expression KEYWORD_FACE SYMBOL_LCURL statements SYMBOL_RCURL') @self.pg.production('per_statement : KEYWORD_PER id KEYWORD_IN expression KEYWORD_FAC SYMBOL_LCURL statements SYMBOL_RCURL')
def per(tokens): def per(tokens):
return ast_nodes.PerStatement(tokens[3], tokens[1], tokens[6]) return ast_nodes.PerStatement(tokens[3], tokens[1], tokens[6])
@@ -208,7 +208,7 @@ class Parser():
def tempta(tokens): def tempta(tokens):
return ast_nodes.TemptaStatement(tokens[2], tokens[5], tokens[7]) return ast_nodes.TemptaStatement(tokens[2], tokens[5], tokens[7])
@self.pg.production('donicum_statement : KEYWORD_DONICVM id KEYWORD_VT expression KEYWORD_VSQVE expression KEYWORD_FACE SYMBOL_LCURL statements SYMBOL_RCURL') @self.pg.production('donicum_statement : KEYWORD_DONICVM id KEYWORD_VT expression KEYWORD_VSQVE expression KEYWORD_FAC SYMBOL_LCURL statements SYMBOL_RCURL')
def donicum(tokens): def donicum(tokens):
range_array = ast_nodes.DataRangeArray(tokens[3], tokens[5]) range_array = ast_nodes.DataRangeArray(tokens[3], tokens[5])
return ast_nodes.PerStatement(range_array, tokens[1], tokens[8]) return ast_nodes.PerStatement(range_array, tokens[1], tokens[8])

View File

@@ -4,12 +4,12 @@ DESIGNA array VT [II,XVIII,XV,IX,XIV,XIV,I,VII,VIII,VI]
DESIGNA max VT NVLLVS DESIGNA max VT NVLLVS
DESIGNA svm VT NVLLVS DESIGNA svm VT NVLLVS
PER x IN array FACE { PER x IN array FAC {
DESIGNA svm VT svm + x DESIGNA svm VT svm + x
SI x PLVS max TVNC { SI x PLVS max TVNC {
DESIGNA max VT x DESIGNA max VT x
} }
} }
DICE("Sum:", svm) DIC("Sum:", svm)
DICE("Max:", max) DIC("Max:", max)

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 - I FACE { DONICVM i VT I VSQVE n - I FAC {
DONICVM k VT I VSQVE n - i FACE { DONICVM k VT I VSQVE n - i FAC {
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]
@@ -13,6 +13,6 @@ DONICVM i VT I VSQVE n - I FACE {
} }
} }
PER x IN arr FACE { PER x IN arr FAC {
DICE(x) DIC(x)
} }

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 VI FACE { DONICVM r VT I VSQVE VI FAC {
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 VI FACE { DONICVM r VT I VSQVE VI FAC {
DONICVM c VT I VSQVE IV FACE { DONICVM c VT I VSQVE IV FAC {
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 III FACE { DONICVM r VT I VSQVE III FAC {
DONICVM c VT I VSQVE VII FACE { DONICVM c VT I VSQVE VII FAC {
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 III FACE { DONICVM r VT I VSQVE III FAC {
DONICVM c VT I VSQVE IV FACE { DONICVM c VT I VSQVE IV FAC {
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 III FACE { DONICVM r VT I VSQVE III FAC {
DONICVM c VT IV VSQVE VII FACE { DONICVM c VT IV VSQVE VII FAC {
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)
@@ -52,23 +52,23 @@ DEFINI est_victor(b, player) VT {
} }
DEFINI print_board(b) VT { DEFINI print_board(b) VT {
DICE("+---+---+---+---+---+---+---+") DIC("+---+---+---+---+---+---+---+")
DONICVM r VT I VSQVE VI FACE { DONICVM r VT I VSQVE VI FAC {
DESIGNA line VT "| " DESIGNA line VT "| "
DONICVM c VT I VSQVE VII FACE { DONICVM c VT I VSQVE VII FAC {
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 | "
} ALVID SI cell EST II TVNC { } ALIVD SI cell EST II TVNC {
DESIGNA line VT line & "O | " DESIGNA line VT line & "O | "
} ALVID { } ALIVD {
DESIGNA line VT line & ". | " DESIGNA line VT line & ". | "
} }
} }
DICE(line) DIC(line)
} }
DICE("+---+---+---+---+---+---+---+") DIC("+---+---+---+---+---+---+---+")
DICE(" I II III IV V VI VII") DIC(" I II III IV V VI VII")
REDI(NVLLVS) REDI(NVLLVS)
} }
@@ -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 VI FACE { DONICVM r VT I VSQVE VI FAC {
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 VI FACE { DONICVM r VT I VSQVE VI FAC {
DONICVM c VT I VSQVE IV FACE { DONICVM c VT I VSQVE IV FAC {
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 III FACE { DONICVM r VT I VSQVE III FAC {
DONICVM c VT I VSQVE VII FACE { DONICVM c VT I VSQVE VII FAC {
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 III FACE { DONICVM r VT I VSQVE III FAC {
DONICVM c VT I VSQVE IV FACE { DONICVM c VT I VSQVE IV FAC {
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 III FACE { DONICVM r VT I VSQVE III FAC {
DONICVM c VT IV VSQVE VII FACE { DONICVM c VT IV VSQVE VII FAC {
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])
} }
@@ -146,7 +146,7 @@ DEFINI minimax(b, depth, alpha, beta, maxi) VT {
SI INVOCA est_victor(b, I) TVNC { SI INVOCA est_victor(b, I) TVNC {
REDI(NVLLVS - M - depth) REDI(NVLLVS - M - depth)
} }
} ALVID { } ALIVD {
SI INVOCA est_victor(b, II) TVNC { SI INVOCA est_victor(b, II) TVNC {
REDI(M + depth) REDI(M + depth)
} }
@@ -157,7 +157,7 @@ DEFINI minimax(b, depth, alpha, beta, maxi) VT {
DESIGNA col_order VT [IV, III, V, II, VI, I, VII] DESIGNA col_order VT [IV, III, V, II, VI, I, VII]
SI maxi TVNC { SI maxi TVNC {
DESIGNA best VT NVLLVS - M - VII DESIGNA best VT NVLLVS - M - VII
PER c IN col_order FACE { PER c IN col_order FAC {
DESIGNA linea VT INVOCA find_slot(b, c) DESIGNA linea VT INVOCA find_slot(b, c)
SI NON (linea EST NVLLVS) TVNC { SI NON (linea EST NVLLVS) TVNC {
DESIGNA b[(linea - I) * VII + c] VT II DESIGNA b[(linea - I) * VII + c] VT II
@@ -175,9 +175,9 @@ DEFINI minimax(b, depth, alpha, beta, maxi) VT {
} }
} }
REDI(best) REDI(best)
} ALVID { } ALIVD {
DESIGNA best VT M + VII DESIGNA best VT M + VII
PER c IN col_order FACE { PER c IN col_order FAC {
DESIGNA linea VT INVOCA find_slot(b, c) DESIGNA linea VT INVOCA find_slot(b, c)
SI NON (linea EST NVLLVS) TVNC { SI NON (linea EST NVLLVS) TVNC {
DESIGNA b[(linea - I) * VII + c] VT I DESIGNA b[(linea - I) * VII + c] VT I
@@ -203,7 +203,7 @@ DEFINI ai_move(b) VT {
DESIGNA col_order VT [IV, III, V, II, VI, I, VII] DESIGNA col_order VT [IV, III, V, II, VI, I, VII]
DESIGNA best_score VT NVLLVS - M - VII DESIGNA best_score VT NVLLVS - M - VII
DESIGNA best_col VT IV DESIGNA best_col VT IV
PER c IN col_order FACE { PER c IN col_order FAC {
DESIGNA linea VT INVOCA find_slot(b, c) DESIGNA linea VT INVOCA find_slot(b, c)
SI NON (linea EST NVLLVS) TVNC { SI NON (linea EST NVLLVS) TVNC {
DESIGNA b[(linea - I) * VII + c] VT II DESIGNA b[(linea - I) * VII + c] VT II
@@ -220,63 +220,63 @@ DEFINI ai_move(b) VT {
// --- Board setup --- // --- Board setup ---
DESIGNA board VT [I VSQVE XLII] DESIGNA board VT [I VSQVE XLII]
DONICVM i VT I VSQVE XLII FACE { DONICVM i VT I VSQVE XLII FAC {
DESIGNA board[i] VT NVLLVS DESIGNA board[i] VT NVLLVS
} }
DESIGNA moves VT NVLLVS DESIGNA moves VT NVLLVS
DESIGNA game_over VT FALSITAS DESIGNA game_over VT FALSITAS
DICE("=== CONNECT IV ===") DIC("=== CONNECT IV ===")
DICE("You are X. AI is O.") DIC("You are X. AI is O.")
DICE("Enter column as Roman numeral (I-VII).") DIC("Enter column as Roman numeral (I-VII).")
DICE("") DIC("")
DVM game_over FACE { DVM game_over FAC {
EVERRO() EVERRE()
INVOCA print_board(board) INVOCA print_board(board)
DICE("Your move:") DIC("Your move:")
DESIGNA col VT AVDI_NVMERVS() DESIGNA col VT AVDI_NVMERVS()
SI col PLVS VII TVNC { SI col PLVS VII TVNC {
DICE("Invalid column! Enter I through VII.") DIC("Invalid column! Enter I through VII.")
CONTINVA CONTINVA
} }
DESIGNA linea VT INVOCA find_slot(board, col) DESIGNA linea VT INVOCA find_slot(board, col)
SI linea EST NVLLVS TVNC { SI linea EST NVLLVS TVNC {
DICE("Column full! Try another.") DIC("Column full! Try another.")
CONTINVA CONTINVA
} }
DESIGNA board[(linea - I) * VII + col] VT I DESIGNA board[(linea - I) * VII + col] VT I
DESIGNA moves VT moves + I DESIGNA moves VT moves + I
SI INVOCA est_victor(board, I) TVNC { SI INVOCA est_victor(board, I) TVNC {
INVOCA print_board(board) INVOCA print_board(board)
DICE("You win!") DIC("You win!")
DESIGNA game_over VT VERITAS DESIGNA game_over VT VERITAS
CONTINVA CONTINVA
} }
SI moves EST XLII TVNC { SI moves EST XLII TVNC {
INVOCA print_board(board) INVOCA print_board(board)
DICE("Draw!") DIC("Draw!")
DESIGNA game_over VT VERITAS DESIGNA game_over VT VERITAS
CONTINVA CONTINVA
} }
DICE("AI is thinking...") DIC("AI is thinking...")
DESIGNA col VT INVOCA ai_move(board) DESIGNA col VT INVOCA ai_move(board)
DESIGNA linea VT INVOCA find_slot(board, col) DESIGNA linea VT INVOCA find_slot(board, col)
DICE("AI plays column " & col & ".") DIC("AI plays column " & col & ".")
DESIGNA board[(linea - I) * VII + col] VT II DESIGNA board[(linea - I) * VII + col] VT II
DESIGNA moves VT moves + I DESIGNA moves VT moves + I
SI INVOCA est_victor(board, II) TVNC { SI INVOCA est_victor(board, II) TVNC {
INVOCA print_board(board) INVOCA print_board(board)
DICE("AI wins!") DIC("AI wins!")
DESIGNA game_over VT VERITAS DESIGNA game_over VT VERITAS
CONTINVA CONTINVA
} }
SI moves EST XLII TVNC { SI moves EST XLII TVNC {
INVOCA print_board(board) INVOCA print_board(board)
DICE("Draw!") DIC("Draw!")
DESIGNA game_over VT VERITAS DESIGNA game_over VT VERITAS
} }
} }

View File

@@ -1,9 +1,9 @@
// Counts down from 10 // Counts down from 10
DESIGNA conta VT X DESIGNA conta VT X
DVM conta MINVS I FACE { DVM conta MINVS I FAC {
DICE(conta) DIC(conta)
DESIGNA conta VT conta - I DESIGNA conta VT conta - I
} }
DICE("Blast off!") DIC("Blast off!")

View File

@@ -4,9 +4,9 @@ CVM MAGNVM
DEFINI fact(n) VT { DEFINI fact(n) VT {
SI n MINVS I TVNC { SI n MINVS I TVNC {
REDI(I) REDI(I)
} ALVID { } ALIVD {
REDI(n * INVOCA fact(n - I)) REDI(n * INVOCA fact(n - I))
} }
} }
DICE(INVOCA fact(AVDI_NVMERVS())) DIC(INVOCA fact(AVDI_NVMERVS()))

View File

@@ -1,16 +1,16 @@
// A number guessing game // A number guessing game
CVM FORS CVM FORS
DESIGNA correct VT FORTIS_NVMERVS(I,C) DESIGNA correct VT FORTVITVS_NVMERVS(I,C)
DESIGNA gvess VT NVLLVS DESIGNA gvess VT NVLLVS
DVM correct EST gvess FACE { DVM correct EST gvess FAC {
DESIGNA gvess VT AVDI_NVMERVS() DESIGNA gvess VT AVDI_NVMERVS()
SI gvess MINVS correct TVNC { SI gvess MINVS correct TVNC {
DICE("Too low!") DIC("Too low!")
} ALVID SI gvess PLVS correct TVNC { } ALIVD SI gvess PLVS correct TVNC {
DICE("Too high!") DIC("Too high!")
} }
} }
DICE("You guessed correctly!") DIC("You guessed correctly!")

View File

@@ -1,10 +1,10 @@
// 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 FACE { DONICVM i VT I VSQVE n FAC {
DESIGNA line VT "" DESIGNA line VT ""
DONICVM k VT I VSQVE n FACE { DONICVM k VT I VSQVE n FAC {
DESIGNA line VT line & i * k & " " DESIGNA line VT line & i * k & " "
} }
DICE(line) DIC(line)
} }

View File

@@ -2,16 +2,16 @@
CVM FORS CVM FORS
DESIGNA choices VT ["PETRA", "CHARTA", "FORFEX"] DESIGNA choices VT ["PETRA", "CHARTA", "FORFEX"]
DESIGNA compvter VT FORTIS_ELECTIONIS(choices) DESIGNA compvter VT FORTVITA_ELECTIO(choices)
DICE("Choose: PETRA (rock), CHARTA (paper), or FORFEX (scissors)") DIC("Choose: PETRA (rock), CHARTA (paper), or FORFEX (scissors)")
DESIGNA player VT AVDI() DESIGNA player VT AVDI()
DICE("Computer chose:", compvter) DIC("Computer chose:", compvter)
SI player EST compvter TVNC { SI player EST compvter TVNC {
DICE("Draw!") DIC("Draw!")
} ALVID SI (player EST "PETRA" ET compvter EST "FORFEX") AVT (player EST "CHARTA" ET compvter EST "PETRA") AVT (player EST "FORFEX" ET compvter EST "CHARTA") TVNC { } ALIVD SI (player EST "PETRA" ET compvter EST "FORFEX") AVT (player EST "CHARTA" ET compvter EST "PETRA") AVT (player EST "FORFEX" ET compvter EST "CHARTA") TVNC {
DICE("You win!") DIC("You win!")
} ALVID { } ALIVD {
DICE("Computer wins!") DIC("Computer wins!")
} }

View File

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

View File

@@ -35,10 +35,10 @@
\languageline{statement}{\textbf{id} \texttt{MINVE} \textit{expression}} \\ \languageline{statement}{\textbf{id} \texttt{MINVE} \textit{expression}} \\
\languageline{statement}{\texttt{DEFINI} \textbf{id} \texttt{(} \textit{optional-ids} \texttt{)} \texttt{VT} \textit{scope}} \\ \languageline{statement}{\texttt{DEFINI} \textbf{id} \texttt{(} \textit{optional-ids} \texttt{)} \texttt{VT} \textit{scope}} \\
\languageline{statement}{\textit{if-statement}} \\ \languageline{statement}{\textit{if-statement}} \\
\languageline{statement}{\texttt{DVM} \textit{expression} \texttt{FACE} \textit{scope}} \\ \languageline{statement}{\texttt{DVM} \textit{expression} \texttt{FAC} \textit{scope}} \\
\languageline{statement}{\texttt{AETERNVM} \texttt{FACE} \textit{scope}} \\ \languageline{statement}{\texttt{AETERNVM} \texttt{FAC} \textit{scope}} \\
\languageline{statement}{\texttt{PER} \textbf{id} \texttt{IN} \textit{expression} \texttt{FACE} \textit{scope}} \\ \languageline{statement}{\texttt{PER} \textbf{id} \texttt{IN} \textit{expression} \texttt{FAC} \textit{scope}} \\
\languageline{statement}{\texttt{DONICVM} \textbf{id} \texttt{VT} \textit{expression} \texttt{VSQVE} \textit{expression} \texttt{FACE} \textit{scope}} \\ \languageline{statement}{\texttt{DONICVM} \textbf{id} \texttt{VT} \textit{expression} \texttt{VSQVE} \textit{expression} \texttt{FAC} \textit{scope}} \\
\languageline{statement}{\texttt{REDI(} \textit{optional-expressions} \texttt{)}} \\ \languageline{statement}{\texttt{REDI(} \textit{optional-expressions} \texttt{)}} \\
\languageline{statement}{\texttt{ERVMPE}} \\ \languageline{statement}{\texttt{ERVMPE}} \\
\languageline{statement}{\texttt{CONTINVA}} \\ \languageline{statement}{\texttt{CONTINVA}} \\
@@ -49,8 +49,8 @@
\languageline{if-statement}{\texttt{SI} \textit{expression} \texttt{TVNC} \textit{scope}} \\ \languageline{if-statement}{\texttt{SI} \textit{expression} \texttt{TVNC} \textit{scope}} \\
\languageline{if-statement}{\texttt{SI} \textit{expression} \texttt{TVNC} \textit{scope} \textit{optional-newline} \textit{else-statement}} \\ \hline \languageline{if-statement}{\texttt{SI} \textit{expression} \texttt{TVNC} \textit{scope} \textit{optional-newline} \textit{else-statement}} \\ \hline
\languageline{else-statement}{\texttt{ALVID} \textit{scope}} \\ \languageline{else-statement}{\texttt{ALIVD} \textit{scope}} \\
\languageline{else-statement}{\texttt{ALVID} \textit{if-statement}} \\ \hline \languageline{else-statement}{\texttt{ALIVD} \textit{if-statement}} \\ \hline
\languageline{scope}{\textit{optional-newline} \texttt{\{} \textbf{newline} \textit{statements} \texttt{\}}} \\ \hline \hline \languageline{scope}{\textit{optional-newline} \texttt{\{} \textbf{newline} \textit{statements} \texttt{\}}} \\ \hline \hline

View File

@@ -1,8 +1,8 @@
DESIGNA x VT NVLLVS DESIGNA x VT NVLLVS
AETERNVM FACE { AETERNVM FAC {
DESIGNA x VT x+I DESIGNA x VT x+I
SI x EST X TVNC { SI x EST X TVNC {
ERVMPE ERVMPE
} }
} }
DICE(x) DIC(x)

View File

@@ -1,6 +1,6 @@
DESIGNA x VT VERITAS DESIGNA x VT VERITAS
SI x TVNC { SI x TVNC {
DICE(I) DIC(I)
} ALVID { } ALIVD {
DICE(NVLLVS) DIC(NVLLVS)
} }

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

8
snippets/alivd_si.cent Normal file
View File

@@ -0,0 +1,8 @@
DESIGNA x VT II
SI x EST I TVNC {
DIC(I)
} ALIVD SI x EST II TVNC {
DIC(II)
} ALIVD {
DIC(III)
}

View File

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

@@ -1,8 +0,0 @@
DESIGNA x VT II
SI x EST I TVNC {
DICE(I)
} ALVID SI x EST II TVNC {
DICE(II)
} ALVID {
DICE(III)
}

View File

@@ -1,2 +1,2 @@
DESIGNA x VT [I, II, III] DESIGNA x VT [I, II, III]
DICE(x[I]) DIC(x[I])

View File

@@ -1,2 +1,2 @@
DESIGNA x VT [X, XX, XXX, XL, L] DESIGNA x VT [X, XX, XXX, XL, L]
DICE(x[II VSQVE IV]) DIC(x[II VSQVE IV])

View File

@@ -1,9 +1,9 @@
DESIGNA x VT VERITAS DESIGNA x VT VERITAS
DESIGNA y VT FALSITAS DESIGNA y VT FALSITAS
SI x ET y TVNC { SI x ET y TVNC {
DICE(I) DIC(I)
} ALVID SI x AVT y TVNC { } ALIVD SI x AVT y TVNC {
DICE(II) DIC(II)
} ALVID { } ALIVD {
DICE(III) DIC(III)
} }

View File

@@ -1,3 +1,3 @@
DESIGNA x VT V DESIGNA x VT V
x AVGE III x AVGE III
DICE(x) DIC(x)

2
snippets/dic.cent Normal file
View File

@@ -0,0 +1,2 @@
DIC("Hello, world!")
DIC(I, II, III)

View File

Before

Width:  |  Height:  |  Size: 9.6 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

View File

@@ -1,2 +0,0 @@
DICE("Hello, world!")
DICE(I, II, III)

View File

@@ -1,3 +1,3 @@
DICE(d["nomen"]) DIC(d["nomen"])
DESIGNA d["aetas"] VT XXVI DESIGNA d["aetas"] VT XXVI
DESIGNA d["novus"] VT I DESIGNA d["novus"] VT I

View File

@@ -1,3 +1,3 @@
PER k IN d FACE { PER k IN d FAC {
DICE(k) DIC(k)
} }

View File

@@ -1,5 +1,5 @@
DESIGNA x VT NVLLVS DESIGNA x VT NVLLVS
DONICVM y VT NVLLVS VSQVE X FACE { DONICVM y VT NVLLVS VSQVE X FAC {
DESIGNA x VT x + y DESIGNA x VT x + y
} }
DICE(x) DIC(x)

View File

@@ -1,5 +1,5 @@
DESIGNA x VT NVLLVS DESIGNA x VT NVLLVS
DVM x PLVS X FACE { DVM x PLVS X FAC {
DESIGNA x VT x+I DESIGNA x VT x+I
} }
DICE(x) DIC(x)

View File

@@ -1,9 +1,9 @@
DEFINI fib(x) VT { DEFINI fib(x) VT {
SI x EST NVLLVS TVNC { SI x EST NVLLVS TVNC {
REDI(NVLLVS) REDI(NVLLVS)
} ALVID SI x EST I TVNC { } ALIVD SI x EST I TVNC {
REDI(I) REDI(I)
} ALVID { } ALIVD {
REDI(INVOCA fib(x-II) + INVOCA fib(x-I)) REDI(INVOCA fib(x-II) + INVOCA fib(x-I))
} }
} }

View File

@@ -2,4 +2,4 @@ DEFINI sqvare(x) VT {
REDI(x*x) REDI(x*x)
} }
DICE(INVOCA sqvare(XI)) DIC(INVOCA sqvare(XI))

View File

@@ -6,4 +6,4 @@ DESIGNA dbl VT FVNCTIO (n) VT {
REDI (n * II) REDI (n * II)
} }
DICE(INVOCA apply (dbl, VII)) DIC(INVOCA apply (dbl, VII))

View File

@@ -1,15 +1,15 @@
CVM FORS CVM FORS
DESIGNA correct VT FORTIS_NVMERVS(I,C) DESIGNA correct VT FORTVITVS_NVMERVS(I,C)
DESIGNA gvess VT NVLLVS DESIGNA gvess VT NVLLVS
DVM correct EST gvess FACE { DVM correct EST gvess FAC {
DESIGNA gvess VT AVDI_NVMERVS() DESIGNA gvess VT AVDI_NVMERVS()
SI gvess MINVS correct TVNC { SI gvess MINVS correct TVNC {
DICE("Too low!") DIC("Too low!")
} ALVID SI gvess PLVS correct TVNC { } ALIVD SI gvess PLVS correct TVNC {
DICE("Too high!") DIC("Too high!")
} }
} }
DICE("You guessed correctly!") DIC("You guessed correctly!")

View File

@@ -1,2 +1,2 @@
DESIGNA x VT "Hello World!" DESIGNA x VT "Hello World!"
DICE(x) DIC(x)

View File

@@ -1,11 +1,11 @@
// Immediately invoked // Immediately invoked
DICE(INVOCA FVNCTIO (x) VT { REDI (x + I) } (V)) DIC(INVOCA FVNCTIO (x) VT { REDI (x + I) } (V))
// From an array // From an array
DESIGNA fns VT [FVNCTIO (x) VT { REDI (x + I) }] DESIGNA fns VT [FVNCTIO (x) VT { REDI (x + I) }]
DICE(INVOCA fns[I] (V)) DIC(INVOCA fns[I] (V))
// Passing a named function as an argument // Passing a named function as an argument
DEFINI apply (f, x) VT { REDI (INVOCA f (x)) } DEFINI apply (f, x) VT { REDI (INVOCA f (x)) }
DEFINI sqr (x) VT { REDI (x * x) } DEFINI sqr (x) VT { REDI (x * x) }
DICE(INVOCA apply (sqr, IV)) DIC(INVOCA apply (sqr, IV))

View File

@@ -1,4 +1,4 @@
DESIGNA x VT [I, II, III, IV, V] DESIGNA x VT [I, II, III, IV, V]
PER y IN x FACE { PER y IN x FAC {
DICE(y) DIC(y)
} }

View File

@@ -1,7 +1,7 @@
DESIGNA x VT VERITAS DESIGNA x VT VERITAS
SI x TVNC { SI x TVNC {
DICE(I) DIC(I)
REDI(NVLLVS) REDI(NVLLVS)
} }
DICE(NVLLVS) DIC(NVLLVS)

View File

@@ -1,4 +1,4 @@
DESIGNA nomen VT "Marcus" DESIGNA nomen VT "Marcus"
DICE("Salve, {nomen}!") DIC("Salve, {nomen}!")
DICE("Sum: {III + IV}") DIC("Sum: {III + IV}")
DICE("{nomen} has {V} cats") DIC("{nomen} has {V} cats")

View File

@@ -70,7 +70,7 @@ contexts:
scope: constant.language.centvrion scope: constant.language.centvrion
builtins: builtins:
- match: '\b(ADIVNGE|AVDI_NVMERVS|AVDI|CLAVES|DECIMATIO|DICE|EVERRO|FORTIS_NVMERVS|FORTIS_ELECTIONIS|LEGE|LONGITVDO|ORDINA|SCRIBE|SEMEN|SENATVS)\b' - match: '\b(ADIVNGE|AVDI_NVMERVS|AVDI|CLAVES|DECIMATIO|DIC|EVERRE|FORTVITVS_NVMERVS|FORTVITA_ELECTIO|LEGE|LONGITVDO|ORDINA|SCRIBE|SEMEN|SENATVS)\b'
scope: support.function.builtin.centvrion scope: support.function.builtin.centvrion
modules: modules:
@@ -78,7 +78,7 @@ contexts:
scope: support.class.module.centvrion scope: support.class.module.centvrion
keywords: keywords:
- match: '\b(AETERNVM|ALVID|AVGE|AVT|CAPE|CONTINVA|DEFINI|DESIGNA|DISPAR|DONICVM|DVM|ERVMPE|EST|ET|FACE|FVNCTIO|INVOCA|IN|MINVE|MINVS|NON|PER|PLVS|REDI|RELIQVVM|SI|TABVLA|TEMPTA|TVNC|VSQVE|VT|CVM)\b' - match: '\b(AETERNVM|ALIVD|AVGE|AVT|CAPE|CONTINVA|DEFINI|DESIGNA|DISPAR|DONICVM|DVM|ERVMPE|EST|ET|FAC|FVNCTIO|INVOCA|IN|MINVE|MINVS|NON|PER|PLVS|REDI|RELIQVVM|SI|TABVLA|TEMPTA|TVNC|VSQVE|VT|CVM)\b'
scope: keyword.control.centvrion scope: keyword.control.centvrion
operators: operators:

264
tests.py
View File

@@ -110,17 +110,17 @@ def run_test(self, source, target_nodes, target_value, target_output="", input_l
# --- Output --- # --- Output ---
output_tests = [ output_tests = [
("DICE(\"hello\")", Program([], [ExpressionStatement(BuiltIn("DICE", [String("hello")]))]), ValStr("hello"), "hello\n"), ("DIC(\"hello\")", Program([], [ExpressionStatement(BuiltIn("DIC", [String("hello")]))]), ValStr("hello"), "hello\n"),
("DICE(\"world\")", Program([], [ExpressionStatement(BuiltIn("DICE", [String("world")]))]), ValStr("world"), "world\n"), ("DIC(\"world\")", Program([], [ExpressionStatement(BuiltIn("DIC", [String("world")]))]), ValStr("world"), "world\n"),
("DICE(III)", Program([], [ExpressionStatement(BuiltIn("DICE", [Numeral("III")]))]), ValStr("III"), "III\n"), ("DIC(III)", Program([], [ExpressionStatement(BuiltIn("DIC", [Numeral("III")]))]), ValStr("III"), "III\n"),
("DICE(X)", Program([], [ExpressionStatement(BuiltIn("DICE", [Numeral("X")]))]), ValStr("X"), "X\n"), ("DIC(X)", Program([], [ExpressionStatement(BuiltIn("DIC", [Numeral("X")]))]), ValStr("X"), "X\n"),
("DICE(MMXXV)", Program([], [ExpressionStatement(BuiltIn("DICE", [Numeral("MMXXV")]))]), ValStr("MMXXV"), "MMXXV\n"), ("DIC(MMXXV)", Program([], [ExpressionStatement(BuiltIn("DIC", [Numeral("MMXXV")]))]), ValStr("MMXXV"), "MMXXV\n"),
("DICE('hello')", Program([], [ExpressionStatement(BuiltIn("DICE", [String("hello")]))]), ValStr("hello"), "hello\n"), ("DIC('hello')", Program([], [ExpressionStatement(BuiltIn("DIC", [String("hello")]))]), ValStr("hello"), "hello\n"),
("DICE('world')", Program([], [ExpressionStatement(BuiltIn("DICE", [String("world")]))]), ValStr("world"), "world\n"), ("DIC('world')", Program([], [ExpressionStatement(BuiltIn("DIC", [String("world")]))]), ValStr("world"), "world\n"),
("DICE(\"a\", \"b\")", Program([], [ExpressionStatement(BuiltIn("DICE", [String("a"), String("b")]))]), ValStr("a b"), "a b\n"), ("DIC(\"a\", \"b\")", Program([], [ExpressionStatement(BuiltIn("DIC", [String("a"), String("b")]))]), ValStr("a b"), "a b\n"),
("DICE(\"line one\")\nDICE(\"line two\")", Program([], [ExpressionStatement(BuiltIn("DICE", [String("line one")])), ExpressionStatement(BuiltIn("DICE", [String("line two")]))]), ValStr("line two"), "line one\nline two\n"), ("DIC(\"line one\")\nDIC(\"line two\")", Program([], [ExpressionStatement(BuiltIn("DIC", [String("line one")])), ExpressionStatement(BuiltIn("DIC", [String("line two")]))]), ValStr("line two"), "line one\nline two\n"),
("DICE(DICE(II))", Program([], [ExpressionStatement(BuiltIn("DICE", [BuiltIn("DICE", [Numeral("II")])]))]), ValStr("II"), "II\nII\n"), ("DIC(DIC(II))", Program([], [ExpressionStatement(BuiltIn("DIC", [BuiltIn("DIC", [Numeral("II")])]))]), ValStr("II"), "II\nII\n"),
("EVERRO()", Program([], [ExpressionStatement(BuiltIn("EVERRO", []))]), ValNul(), "\033[2J\033[H"), ("EVERRE()", Program([], [ExpressionStatement(BuiltIn("EVERRE", []))]), ValNul(), "\033[2J\033[H"),
] ]
class TestOutput(unittest.TestCase): class TestOutput(unittest.TestCase):
@@ -285,7 +285,7 @@ assignment_tests = [
ExpressionStatement(ID("x"))]), ExpressionStatement(ID("x"))]),
ValInt(6)), ValInt(6)),
# AVGE inside a loop (DONICVM range is inclusive: I VSQVE III = [1, 2, 3]) # 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 FAC {\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"))]),
@@ -332,12 +332,12 @@ destructuring_tests = [
), ),
# destructure into individual use # destructure into individual use
( (
"DEFINI pair (a, b) VT { REDI (a, b) }\nDESIGNA x, y VT INVOCA pair (V, II)\nDICE(x)\nDICE(y)", "DEFINI pair (a, b) VT { REDI (a, b) }\nDESIGNA x, y VT INVOCA pair (V, II)\nDIC(x)\nDIC(y)",
Program([], [ Program([], [
Defini(ID("pair"), [ID("a"), ID("b")], [Redi([ID("a"), ID("b")])]), Defini(ID("pair"), [ID("a"), ID("b")], [Redi([ID("a"), ID("b")])]),
DesignaDestructure([ID("x"), ID("y")], Invoca(ID("pair"), [Numeral("V"), Numeral("II")])), DesignaDestructure([ID("x"), ID("y")], Invoca(ID("pair"), [Numeral("V"), Numeral("II")])),
ExpressionStatement(BuiltIn("DICE", [ID("x")])), ExpressionStatement(BuiltIn("DIC", [ID("x")])),
ExpressionStatement(BuiltIn("DICE", [ID("y")])), ExpressionStatement(BuiltIn("DIC", [ID("y")])),
]), ]),
ValStr("II"), ValStr("II"),
"V\nII\n", "V\nII\n",
@@ -353,41 +353,41 @@ class TestDestructuring(unittest.TestCase):
# --- Control flow --- # --- Control flow ---
control_tests = [ control_tests = [
# SI without ALVID — true branch # SI without ALIVD — true branch
("SI VERITAS TVNC { DESIGNA r VT I }\nr", ("SI VERITAS TVNC { DESIGNA r VT I }\nr",
Program([], [SiStatement(Bool(True), [Designa(ID("r"), Numeral("I"))], None), ExpressionStatement(ID("r"))]), Program([], [SiStatement(Bool(True), [Designa(ID("r"), Numeral("I"))], None), ExpressionStatement(ID("r"))]),
ValInt(1)), ValInt(1)),
# SI without ALVID — false branch # SI without ALIVD — false branch
("SI FALSITAS TVNC { DESIGNA r VT I }", ("SI FALSITAS TVNC { DESIGNA r VT I }",
Program([], [SiStatement(Bool(False), [Designa(ID("r"), Numeral("I"))], None)]), Program([], [SiStatement(Bool(False), [Designa(ID("r"), Numeral("I"))], None)]),
ValNul()), ValNul()),
# SI with ALVID — true branch # SI with ALIVD — true branch
("SI VERITAS TVNC { DESIGNA r VT I } ALVID { DESIGNA r VT II }\nr", ("SI VERITAS TVNC { DESIGNA r VT I } ALIVD { DESIGNA r VT II }\nr",
Program([], [SiStatement(Bool(True), [Designa(ID("r"), Numeral("I"))], [Designa(ID("r"), Numeral("II"))]), ExpressionStatement(ID("r"))]), Program([], [SiStatement(Bool(True), [Designa(ID("r"), Numeral("I"))], [Designa(ID("r"), Numeral("II"))]), ExpressionStatement(ID("r"))]),
ValInt(1)), ValInt(1)),
# SI with ALVID — false branch # SI with ALIVD — false branch
("SI FALSITAS TVNC { DESIGNA r VT I } ALVID { DESIGNA r VT II }\nr", ("SI FALSITAS TVNC { DESIGNA r VT I } ALIVD { DESIGNA r VT II }\nr",
Program([], [SiStatement(Bool(False), [Designa(ID("r"), Numeral("I"))], [Designa(ID("r"), Numeral("II"))]), ExpressionStatement(ID("r"))]), Program([], [SiStatement(Bool(False), [Designa(ID("r"), Numeral("I"))], [Designa(ID("r"), Numeral("II"))]), ExpressionStatement(ID("r"))]),
ValInt(2)), ValInt(2)),
# SI with comparison — equal # SI with comparison — equal
("SI I EST I TVNC { DESIGNA r VT I } ALVID { DESIGNA r VT II }\nr", ("SI I EST I TVNC { DESIGNA r VT I } ALIVD { DESIGNA r VT II }\nr",
Program([], [SiStatement(BinOp(Numeral("I"), Numeral("I"), "KEYWORD_EST"), [Designa(ID("r"), Numeral("I"))], [Designa(ID("r"), Numeral("II"))]), ExpressionStatement(ID("r"))]), Program([], [SiStatement(BinOp(Numeral("I"), Numeral("I"), "KEYWORD_EST"), [Designa(ID("r"), Numeral("I"))], [Designa(ID("r"), Numeral("II"))]), ExpressionStatement(ID("r"))]),
ValInt(1)), ValInt(1)),
# SI with comparison — unequal # SI with comparison — unequal
("SI I EST II TVNC { DESIGNA r VT I } ALVID { DESIGNA r VT II }\nr", ("SI I EST II TVNC { DESIGNA r VT I } ALIVD { DESIGNA r VT II }\nr",
Program([], [SiStatement(BinOp(Numeral("I"), Numeral("II"), "KEYWORD_EST"), [Designa(ID("r"), Numeral("I"))], [Designa(ID("r"), Numeral("II"))]), ExpressionStatement(ID("r"))]), Program([], [SiStatement(BinOp(Numeral("I"), Numeral("II"), "KEYWORD_EST"), [Designa(ID("r"), Numeral("I"))], [Designa(ID("r"), Numeral("II"))]), ExpressionStatement(ID("r"))]),
ValInt(2)), ValInt(2)),
# SI MINVS # SI MINVS
("SI I MINVS II TVNC { DESIGNA r VT I } ALVID { DESIGNA r VT II }\nr", ("SI I MINVS II TVNC { DESIGNA r VT I } ALIVD { DESIGNA r VT II }\nr",
Program([], [SiStatement(BinOp(Numeral("I"), Numeral("II"), "KEYWORD_MINVS"), [Designa(ID("r"), Numeral("I"))], [Designa(ID("r"), Numeral("II"))]), ExpressionStatement(ID("r"))]), Program([], [SiStatement(BinOp(Numeral("I"), Numeral("II"), "KEYWORD_MINVS"), [Designa(ID("r"), Numeral("I"))], [Designa(ID("r"), Numeral("II"))]), ExpressionStatement(ID("r"))]),
ValInt(1)), ValInt(1)),
# SI PLVS # SI PLVS
("SI II PLVS I TVNC { DESIGNA r VT I } ALVID { DESIGNA r VT II }\nr", ("SI II PLVS I TVNC { DESIGNA r VT I } ALIVD { DESIGNA r VT II }\nr",
Program([], [SiStatement(BinOp(Numeral("II"), Numeral("I"), "KEYWORD_PLVS"), [Designa(ID("r"), Numeral("I"))], [Designa(ID("r"), Numeral("II"))]), ExpressionStatement(ID("r"))]), Program([], [SiStatement(BinOp(Numeral("II"), Numeral("I"), "KEYWORD_PLVS"), [Designa(ID("r"), Numeral("I"))], [Designa(ID("r"), Numeral("II"))]), ExpressionStatement(ID("r"))]),
ValInt(1)), ValInt(1)),
# ALVID SI chain # ALIVD SI chain
( (
"SI I EST II TVNC { DESIGNA r VT I } ALVID SI I EST I TVNC { DESIGNA r VT II } ALVID { DESIGNA r VT III }\nr", "SI I EST II TVNC { DESIGNA r VT I } ALIVD SI I EST I TVNC { DESIGNA r VT II } ALIVD { DESIGNA r VT III }\nr",
Program([], [ Program([], [
SiStatement( SiStatement(
BinOp(Numeral("I"), Numeral("II"), "KEYWORD_EST"), BinOp(Numeral("I"), Numeral("II"), "KEYWORD_EST"),
@@ -404,7 +404,7 @@ control_tests = [
), ),
# DVM (while not): loops until condition is true # DVM (while not): loops until condition is true
( (
"DESIGNA x VT I\nDVM x EST III FACE {\nDESIGNA x VT x + I\n}\nx", "DESIGNA x VT I\nDVM x EST III FAC {\nDESIGNA x VT x + I\n}\nx",
Program([], [ Program([], [
Designa(ID("x"), Numeral("I")), Designa(ID("x"), Numeral("I")),
DumStatement(BinOp(ID("x"), Numeral("III"), "KEYWORD_EST"), [Designa(ID("x"), BinOp(ID("x"), Numeral("I"), "SYMBOL_PLUS"))]), DumStatement(BinOp(ID("x"), Numeral("III"), "KEYWORD_EST"), [Designa(ID("x"), BinOp(ID("x"), Numeral("I"), "SYMBOL_PLUS"))]),
@@ -412,22 +412,22 @@ control_tests = [
]), ]),
ValInt(3), ValInt(3),
), ),
# DVM with ERVMPE — loop body prints (testing DICE + ERVMPE together) # DVM with ERVMPE — loop body prints (testing DIC + ERVMPE together)
("DESIGNA x VT I\nDVM FALSITAS FACE {\nDICE(x)\nERVMPE\n}", ("DESIGNA x VT I\nDVM FALSITAS FAC {\nDIC(x)\nERVMPE\n}",
Program([], [ Program([], [
Designa(ID("x"), Numeral("I")), Designa(ID("x"), Numeral("I")),
DumStatement(Bool(False), [ExpressionStatement(BuiltIn("DICE", [ID("x")])), Erumpe()]), DumStatement(Bool(False), [ExpressionStatement(BuiltIn("DIC", [ID("x")])), Erumpe()]),
]), ]),
ValStr("I"), "I\n"), ValStr("I"), "I\n"),
# AETERNVM is sugar for DVM FALSITAS — must produce the same AST. # AETERNVM is sugar for DVM FALSITAS — must produce the same AST.
("DESIGNA x VT I\nAETERNVM FACE {\nDICE(x)\nERVMPE\n}", ("DESIGNA x VT I\nAETERNVM FAC {\nDIC(x)\nERVMPE\n}",
Program([], [ Program([], [
Designa(ID("x"), Numeral("I")), Designa(ID("x"), Numeral("I")),
DumStatement(Bool(False), [ExpressionStatement(BuiltIn("DICE", [ID("x")])), Erumpe()]), DumStatement(Bool(False), [ExpressionStatement(BuiltIn("DIC", [ID("x")])), Erumpe()]),
]), ]),
ValStr("I"), "I\n"), ValStr("I"), "I\n"),
# AETERNVM with counter + ERVMPE on condition # AETERNVM with counter + ERVMPE on condition
("DESIGNA x VT I\nAETERNVM FACE {\nSI x EST III TVNC { ERVMPE }\nDESIGNA x VT x + I\n}\nx", ("DESIGNA x VT I\nAETERNVM FAC {\nSI x EST III TVNC { ERVMPE }\nDESIGNA x VT x + I\n}\nx",
Program([], [ Program([], [
Designa(ID("x"), Numeral("I")), Designa(ID("x"), Numeral("I")),
DumStatement(Bool(False), [ DumStatement(Bool(False), [
@@ -440,20 +440,20 @@ control_tests = [
# AETERNVM with CONTINVA — skip printing III; ERVMPE after V. # AETERNVM with CONTINVA — skip printing III; ERVMPE after V.
# Return value is ValNul because the iteration that triggers ERVMPE runs # Return value is ValNul because the iteration that triggers ERVMPE runs
# Designa first (resetting last_val); we test on output, which is the point. # Designa first (resetting last_val); we test on output, which is the point.
("DESIGNA x VT NVLLVS\nAETERNVM FACE {\nDESIGNA x VT x + I\nSI x PLVS V TVNC { ERVMPE }\nSI x EST III TVNC { CONTINVA }\nDICE(x)\n}", ("DESIGNA x VT NVLLVS\nAETERNVM FAC {\nDESIGNA x VT x + I\nSI x PLVS V TVNC { ERVMPE }\nSI x EST III TVNC { CONTINVA }\nDIC(x)\n}",
Program([], [ Program([], [
Designa(ID("x"), Nullus()), Designa(ID("x"), Nullus()),
DumStatement(Bool(False), [ DumStatement(Bool(False), [
Designa(ID("x"), BinOp(ID("x"), Numeral("I"), "SYMBOL_PLUS")), Designa(ID("x"), BinOp(ID("x"), Numeral("I"), "SYMBOL_PLUS")),
SiStatement(BinOp(ID("x"), Numeral("V"), "KEYWORD_PLVS"), [Erumpe()], None), SiStatement(BinOp(ID("x"), Numeral("V"), "KEYWORD_PLVS"), [Erumpe()], None),
SiStatement(BinOp(ID("x"), Numeral("III"), "KEYWORD_EST"), [Continva()], None), SiStatement(BinOp(ID("x"), Numeral("III"), "KEYWORD_EST"), [Continva()], None),
ExpressionStatement(BuiltIn("DICE", [ID("x")])), ExpressionStatement(BuiltIn("DIC", [ID("x")])),
]), ]),
]), ]),
ValNul(), "I\nII\nIV\nV\n"), ValNul(), "I\nII\nIV\nV\n"),
# REDI inside AETERNVM (inside DEFINI) — exits both loop and function # REDI inside AETERNVM (inside DEFINI) — exits both loop and function
( (
"DEFINI f () VT {\nDESIGNA x VT I\nAETERNVM FACE {\nREDI (x)\n}\n}\nINVOCA f ()", "DEFINI f () VT {\nDESIGNA x VT I\nAETERNVM FAC {\nREDI (x)\n}\n}\nINVOCA f ()",
Program([], [ Program([], [
Defini(ID("f"), [], [ Defini(ID("f"), [], [
Designa(ID("x"), Numeral("I")), Designa(ID("x"), Numeral("I")),
@@ -464,12 +464,12 @@ control_tests = [
ValInt(1), ValInt(1),
), ),
# PER foreach # PER foreach
("PER i IN [I, II, III] FACE { DICE(i) }", ("PER i IN [I, II, III] FAC { DIC(i) }",
Program([], [PerStatement(DataArray([Numeral("I"), Numeral("II"), Numeral("III")]), ID("i"), [ExpressionStatement(BuiltIn("DICE", [ID("i")]))])]), Program([], [PerStatement(DataArray([Numeral("I"), Numeral("II"), Numeral("III")]), ID("i"), [ExpressionStatement(BuiltIn("DIC", [ID("i")]))])]),
ValStr("III"), "I\nII\nIII\n"), ValStr("III"), "I\nII\nIII\n"),
# DONICVM range loop # DONICVM range loop
("DONICVM i VT I VSQVE V FACE { DICE(i) }", ("DONICVM i VT I VSQVE V FAC { DIC(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("DIC", [ID("i")]))])]),
ValStr("V"), "I\nII\nIII\nIV\nV\n"), ValStr("V"), "I\nII\nIII\nIV\nV\n"),
] ]
@@ -500,7 +500,7 @@ function_tests = [
), ),
# Fibonacci: fib(n<3)=1, fib(n)=fib(n-1)+fib(n-2) # Fibonacci: fib(n<3)=1, fib(n)=fib(n-1)+fib(n-2)
( (
"DEFINI fib (n) VT {\nSI n MINVS III TVNC { REDI (I) } ALVID { REDI (INVOCA fib (n - I) + INVOCA fib (n - II)) }\n}\nINVOCA fib (VII)", "DEFINI fib (n) VT {\nSI n MINVS III TVNC { REDI (I) } ALIVD { REDI (INVOCA fib (n - I) + INVOCA fib (n - II)) }\n}\nINVOCA fib (VII)",
Program([], [ Program([], [
Defini(ID("fib"), [ID("n")], [ Defini(ID("fib"), [ID("n")], [
SiStatement( SiStatement(
@@ -530,14 +530,14 @@ class TestFunctions(unittest.TestCase):
builtin_tests = [ builtin_tests = [
("AVDI_NVMERVS()", Program([], [ExpressionStatement(BuiltIn("AVDI_NVMERVS", []))]), ValInt(3), "", ["III"]), ("AVDI_NVMERVS()", Program([], [ExpressionStatement(BuiltIn("AVDI_NVMERVS", []))]), ValInt(3), "", ["III"]),
("AVDI_NVMERVS()", Program([], [ExpressionStatement(BuiltIn("AVDI_NVMERVS", []))]), ValInt(10), "", ["X"]), ("AVDI_NVMERVS()", Program([], [ExpressionStatement(BuiltIn("AVDI_NVMERVS", []))]), ValInt(10), "", ["X"]),
("CVM FORS\nFORTIS_NVMERVS(I, X)", Program([ModuleCall("FORS")], [ExpressionStatement(BuiltIn("FORTIS_NVMERVS", [Numeral("I"), Numeral("X")]))]), ValInt(3)), ("CVM FORS\nFORTVITVS_NVMERVS(I, X)", Program([ModuleCall("FORS")], [ExpressionStatement(BuiltIn("FORTVITVS_NVMERVS", [Numeral("I"), Numeral("X")]))]), ValInt(3)),
("AVDI()", Program([], [ExpressionStatement(BuiltIn("AVDI", []))]), ValStr("hello"), "", ["hello"]), ("AVDI()", Program([], [ExpressionStatement(BuiltIn("AVDI", []))]), ValStr("hello"), "", ["hello"]),
("LONGITVDO([I, II, III])", Program([], [ExpressionStatement(BuiltIn("LONGITVDO", [DataArray([Numeral("I"), Numeral("II"), Numeral("III")])]))]), ValInt(3)), ("LONGITVDO([I, II, III])", Program([], [ExpressionStatement(BuiltIn("LONGITVDO", [DataArray([Numeral("I"), Numeral("II"), Numeral("III")])]))]), ValInt(3)),
("LONGITVDO([])", Program([], [ExpressionStatement(BuiltIn("LONGITVDO", [DataArray([])]))]), ValInt(0)), ("LONGITVDO([])", Program([], [ExpressionStatement(BuiltIn("LONGITVDO", [DataArray([])]))]), ValInt(0)),
('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\nFORTVITA_ELECTIO([I, II, III])", Program([ModuleCall("FORS")], [ExpressionStatement(BuiltIn("FORTVITA_ELECTIO", [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)), ("CVM FORS\nSEMEN(XLII)\nFORTVITVS_NVMERVS(I, C)", Program([ModuleCall("FORS")], [ExpressionStatement(BuiltIn("SEMEN", [Numeral("XLII")])), ExpressionStatement(BuiltIn("FORTVITVS_NVMERVS", [Numeral("I"), Numeral("C")]))]), ValInt(82)),
# DECIMATIO: seed 42, 10 elements → removes 1 (element II) # DECIMATIO: seed 42, 10 elements → removes 1 (element II)
("CVM FORS\nSEMEN(XLII)\nDECIMATIO([I, II, III, IV, V, VI, VII, VIII, IX, X])", 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")])]))]), ValList([ValInt(1), ValInt(3), ValInt(4), ValInt(5), ValInt(6), ValInt(7), ValInt(8), ValInt(9), ValInt(10)])), ("CVM FORS\nSEMEN(XLII)\nDECIMATIO([I, II, III, IV, V, VI, VII, VIII, IX, X])", 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")])]))]), ValList([ValInt(1), ValInt(3), ValInt(4), ValInt(5), ValInt(6), ValInt(7), ValInt(8), ValInt(9), ValInt(10)])),
# DECIMATIO: seed 1, 3 elements → 3//10=0, nothing removed # DECIMATIO: seed 1, 3 elements → 3//10=0, nothing removed
@@ -621,9 +621,9 @@ error_tests = [
("INVOCA f ()", CentvrionError), # undefined function ("INVOCA f ()", CentvrionError), # undefined function
("DESIGNA VT III", SyntaxError), # parse error: missing id after DESIGNA ("DESIGNA VT III", SyntaxError), # parse error: missing id after DESIGNA
("DESIGNA x III", SyntaxError), # parse error: missing VT ("DESIGNA x III", SyntaxError), # parse error: missing VT
("DICE(M + M + M + M)", CentvrionError), # output > 3999 without MAGNVM ("DIC(M + M + M + M)", CentvrionError), # output > 3999 without MAGNVM
("IIII", CentvrionError), # invalid Roman numeral in source ("IIII", CentvrionError), # invalid Roman numeral in source
("FORTIS_NVMERVS(I, X)", CentvrionError), # requires FORS module ("FORTVITVS_NVMERVS(I, X)", CentvrionError), # requires FORS module
("DEFINI f (x) VT { REDI(x) }\nINVOCA f (I, II)", CentvrionError), # too many args ("DEFINI f (x) VT { REDI(x) }\nINVOCA f (I, II)", CentvrionError), # too many args
("DEFINI f (x, y) VT { REDI(x) }\nINVOCA f (I)", CentvrionError), # too few args ("DEFINI f (x, y) VT { REDI(x) }\nINVOCA f (I)", CentvrionError), # too few args
("DEFINI f () VT { REDI(I) }\nINVOCA f (I)", CentvrionError), # args to zero-param function ("DEFINI f () VT { REDI(I) }\nINVOCA f (I)", CentvrionError), # args to zero-param function
@@ -646,10 +646,10 @@ error_tests = [
("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 ("SEMEN(I)", CentvrionError), # requires FORS module
('CVM FORS\nSEMEN("abc")', CentvrionError), # SEMEN requires integer seed ('CVM FORS\nSEMEN("abc")', CentvrionError), # SEMEN requires integer seed
("FORTIS_ELECTIONIS([])", CentvrionError), # FORS required for FORTIS_ELECTIONIS ("FORTVITA_ELECTIO([])", CentvrionError), # FORS required for FORTVITA_ELECTIO
("CVM FORS\nFORTIS_ELECTIONIS([])", CentvrionError), # FORTIS_ELECTIONIS on empty array ("CVM FORS\nFORTVITA_ELECTIO([])", CentvrionError), # FORTVITA_ELECTIO on empty array
("CVM FORS\nFORTIS_NVMERVS(X, I)", CentvrionError), # FORTIS_NVMERVS a > b ("CVM FORS\nFORTVITVS_NVMERVS(X, I)", CentvrionError), # FORTVITVS_NVMERVS a > b
("PER i IN I FACE { DICE(i) }", CentvrionError), # PER over non-array ("PER i IN I FAC { DIC(i) }", CentvrionError), # PER over non-array
("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
@@ -670,7 +670,7 @@ error_tests = [
("DESIGNA z VT I - I\nSI z TVNC { DESIGNA r VT I }", CentvrionError), # non-bool SI condition: zero int ("DESIGNA z VT I - I\nSI z TVNC { DESIGNA r VT I }", CentvrionError), # non-bool SI condition: zero int
("SI [I] TVNC { DESIGNA r VT I }", CentvrionError), # non-bool SI condition: non-empty list ("SI [I] TVNC { DESIGNA r VT I }", CentvrionError), # non-bool SI condition: non-empty list
("SI [] TVNC { DESIGNA r VT I }", CentvrionError), # non-bool SI condition: empty list ("SI [] TVNC { DESIGNA r VT I }", CentvrionError), # non-bool SI condition: empty list
("DESIGNA x VT I\nDVM x FACE {\nDESIGNA x VT x + I\n}", CentvrionError), # non-bool DVM condition: int ("DESIGNA x VT I\nDVM x FAC {\nDESIGNA x VT x + I\n}", CentvrionError), # non-bool DVM condition: int
("NON I", CentvrionError), # NON on integer ("NON I", CentvrionError), # NON on integer
("DESIGNA z VT I - I\nNON z", CentvrionError), # NON on zero integer ("DESIGNA z VT I - I\nNON z", CentvrionError), # NON on zero integer
('NON "hello"', CentvrionError), # NON on string ('NON "hello"', CentvrionError), # NON on string
@@ -752,7 +752,7 @@ repr_tests = [
("dum", DumStatement(Bool(False), [ExpressionStatement(Erumpe())]), "Dum(\n Bool(False),\n statements([\n ExpressionStatement(\n Erumpe()\n )\n ])\n)"), ("dum", DumStatement(Bool(False), [ExpressionStatement(Erumpe())]), "Dum(\n Bool(False),\n statements([\n ExpressionStatement(\n Erumpe()\n )\n ])\n)"),
("per", PerStatement(DataArray([Numeral("I")]), ID("i"), [ExpressionStatement(Erumpe())]), "Per(\n Array([\n Numeral(I)\n ]),\n ID(i),\n statements([\n ExpressionStatement(\n Erumpe()\n )\n ])\n)"), ("per", PerStatement(DataArray([Numeral("I")]), ID("i"), [ExpressionStatement(Erumpe())]), "Per(\n Array([\n Numeral(I)\n ]),\n ID(i),\n statements([\n ExpressionStatement(\n Erumpe()\n )\n ])\n)"),
("invoca", Invoca(ID("f"), [Numeral("I")]), "Invoca(\n ID(f),\n parameters([\n Numeral(I)\n ])\n)"), ("invoca", Invoca(ID("f"), [Numeral("I")]), "Invoca(\n ID(f),\n parameters([\n Numeral(I)\n ])\n)"),
("builtin", BuiltIn("DICE", [String("hi")]), "Builtin(\n DICE,\n parameters([\n String(hi)\n ])\n)"), ("builtin", BuiltIn("DIC", [String("hi")]), "Builtin(\n DIC,\n parameters([\n String(hi)\n ])\n)"),
("defini", Defini(ID("f"), [ID("n")], [ExpressionStatement(Redi([Numeral("I")]))]), "Defini(\n ID(f),\n parameters([\n ID(n)\n ]),\n statements([\n ExpressionStatement(\n Redi([\n Numeral(I)\n ])\n )\n ])\n)"), ("defini", Defini(ID("f"), [ID("n")], [ExpressionStatement(Redi([Numeral("I")]))]), "Defini(\n ID(f),\n parameters([\n ID(n)\n ]),\n statements([\n ExpressionStatement(\n Redi([\n Numeral(I)\n ])\n )\n ])\n)"),
("program_no_modules", Program([], [ExpressionStatement(Numeral("I"))]), "modules([]),\nstatements([\n ExpressionStatement(\n Numeral(I)\n )\n])"), ("program_no_modules", Program([], [ExpressionStatement(Numeral("I"))]), "modules([]),\nstatements([\n ExpressionStatement(\n Numeral(I)\n )\n])"),
("program_with_module", Program([ModuleCall("FORS")], [ExpressionStatement(Numeral("I"))]), "modules([\n FORS\n]),\nstatements([\n ExpressionStatement(\n Numeral(I)\n )\n])"), ("program_with_module", Program([ModuleCall("FORS")], [ExpressionStatement(Numeral("I"))]), "modules([\n FORS\n]),\nstatements([\n ExpressionStatement(\n Numeral(I)\n )\n])"),
@@ -857,23 +857,23 @@ class TestMakeString(unittest.TestCase):
) )
# --- DICE with non-integer types --- # --- DIC with non-integer types ---
dice_type_tests = [ dic_type_tests = [
("DICE(VERITAS)", Program([], [ExpressionStatement(BuiltIn("DICE", [Bool(True)]))]), ValStr("VERITAS"), "VERITAS\n"), ("DIC(VERITAS)", Program([], [ExpressionStatement(BuiltIn("DIC", [Bool(True)]))]), ValStr("VERITAS"), "VERITAS\n"),
("DICE(FALSITAS)", Program([], [ExpressionStatement(BuiltIn("DICE", [Bool(False)]))]), ValStr("FALSITAS"), "FALSITAS\n"), ("DIC(FALSITAS)", Program([], [ExpressionStatement(BuiltIn("DIC", [Bool(False)]))]), ValStr("FALSITAS"), "FALSITAS\n"),
("DICE(NVLLVS)", Program([], [ExpressionStatement(BuiltIn("DICE", [Nullus()]))]), ValStr("NVLLVS"), "NVLLVS\n"), ("DIC(NVLLVS)", Program([], [ExpressionStatement(BuiltIn("DIC", [Nullus()]))]), ValStr("NVLLVS"), "NVLLVS\n"),
('DICE([I, II])', Program([], [ExpressionStatement(BuiltIn("DICE", [DataArray([Numeral("I"), Numeral("II")])]))]), ValStr("[I II]"), "[I II]\n"), ('DIC([I, II])', Program([], [ExpressionStatement(BuiltIn("DIC", [DataArray([Numeral("I"), Numeral("II")])]))]), ValStr("[I II]"), "[I II]\n"),
('DICE("")', Program([], [ExpressionStatement(BuiltIn("DICE", [String("")]))]), ValStr(""), "\n"), ('DIC("")', Program([], [ExpressionStatement(BuiltIn("DIC", [String("")]))]), ValStr(""), "\n"),
# arithmetic result printed as numeral # arithmetic result printed as numeral
("DICE(II + III)", Program([], [ExpressionStatement(BuiltIn("DICE", [BinOp(Numeral("II"), Numeral("III"), "SYMBOL_PLUS")]))]), ValStr("V"), "V\n"), ("DIC(II + III)", Program([], [ExpressionStatement(BuiltIn("DIC", [BinOp(Numeral("II"), Numeral("III"), "SYMBOL_PLUS")]))]), ValStr("V"), "V\n"),
# multiple args of mixed types # multiple args of mixed types
('DICE("x", VERITAS)', Program([], [ExpressionStatement(BuiltIn("DICE", [String("x"), Bool(True)]))]), ValStr("x VERITAS"), "x VERITAS\n"), ('DIC("x", VERITAS)', Program([], [ExpressionStatement(BuiltIn("DIC", [String("x"), Bool(True)]))]), ValStr("x VERITAS"), "x VERITAS\n"),
] ]
class TestDiceTypes(unittest.TestCase): class TestDicTypes(unittest.TestCase):
@parameterized.expand(dice_type_tests) @parameterized.expand(dic_type_tests)
def test_dice_types(self, source, nodes, value, output): def test_dic_types(self, source, nodes, value, output):
run_test(self, source, nodes, value, output) run_test(self, source, nodes, value, output)
@@ -882,7 +882,7 @@ class TestDiceTypes(unittest.TestCase):
dvm_bool_condition_tests = [ dvm_bool_condition_tests = [
# DVM exits when condition becomes true (boolean comparison) # DVM exits when condition becomes true (boolean comparison)
( (
"DESIGNA x VT I\nDVM x PLVS III FACE {\nDESIGNA x VT x + I\n}\nx", "DESIGNA x VT I\nDVM x PLVS III FAC {\nDESIGNA x VT x + I\n}\nx",
Program([], [ Program([], [
Designa(ID("x"), Numeral("I")), Designa(ID("x"), Numeral("I")),
DumStatement(BinOp(ID("x"), Numeral("III"), "KEYWORD_PLVS"), [Designa(ID("x"), BinOp(ID("x"), Numeral("I"), "SYMBOL_PLUS"))]), DumStatement(BinOp(ID("x"), Numeral("III"), "KEYWORD_PLVS"), [Designa(ID("x"), BinOp(ID("x"), Numeral("I"), "SYMBOL_PLUS"))]),
@@ -1019,11 +1019,11 @@ interpolation_tests = [
('"hello world"', ('"hello world"',
Program([], [ExpressionStatement(String("hello world"))]), Program([], [ExpressionStatement(String("hello world"))]),
ValStr("hello world")), ValStr("hello world")),
# interpolation in DICE output # interpolation in DIC output
('DESIGNA name VT "Roma"\nDICE("Salve, {name}!")', ('DESIGNA name VT "Roma"\nDIC("Salve, {name}!")',
Program([], [ Program([], [
Designa(ID("name"), String("Roma")), Designa(ID("name"), String("Roma")),
ExpressionStatement(BuiltIn("DICE", [InterpolatedString([String("Salve, "), ID("name"), String("!")])])) ExpressionStatement(BuiltIn("DIC", [InterpolatedString([String("Salve, "), ID("name"), String("!")])]))
]), ValStr("Salve, Roma!"), "Salve, Roma!\n"), ]), ValStr("Salve, Roma!"), "Salve, Roma!\n"),
] ]
@@ -1043,7 +1043,7 @@ comparison_tests = [
("SI III PLVS II TVNC { DESIGNA r VT I }\nr", ("SI III PLVS II TVNC { DESIGNA r VT I }\nr",
Program([], [SiStatement(BinOp(Numeral("III"), Numeral("II"), "KEYWORD_PLVS"), [Designa(ID("r"), Numeral("I"))], None), ExpressionStatement(ID("r"))]), Program([], [SiStatement(BinOp(Numeral("III"), Numeral("II"), "KEYWORD_PLVS"), [Designa(ID("r"), Numeral("I"))], None), ExpressionStatement(ID("r"))]),
ValInt(1)), ValInt(1)),
("SI II PLVS III TVNC { DESIGNA r VT I } ALVID { DESIGNA r VT II }\nr", ("SI II PLVS III TVNC { DESIGNA r VT I } ALIVD { DESIGNA r VT II }\nr",
Program([], [SiStatement(BinOp(Numeral("II"), Numeral("III"), "KEYWORD_PLVS"), [Designa(ID("r"), Numeral("I"))], [Designa(ID("r"), Numeral("II"))]), ExpressionStatement(ID("r"))]), Program([], [SiStatement(BinOp(Numeral("II"), Numeral("III"), "KEYWORD_PLVS"), [Designa(ID("r"), Numeral("I"))], [Designa(ID("r"), Numeral("II"))]), ExpressionStatement(ID("r"))]),
ValInt(2)), ValInt(2)),
# result of comparison is ValBool # result of comparison is ValBool
@@ -1153,7 +1153,7 @@ function_edge_tests = [
), ),
# REDI inside DVM exits loop and function # REDI inside DVM exits loop and function
( (
"DEFINI f () VT {\nDESIGNA x VT I\nDVM FALSITAS FACE {\nREDI (x)\n}\n}\nINVOCA f ()", "DEFINI f () VT {\nDESIGNA x VT I\nDVM FALSITAS FAC {\nREDI (x)\n}\n}\nINVOCA f ()",
Program([],[ Program([],[
Defini(ID("f"), [], [ Defini(ID("f"), [], [
Designa(ID("x"), Numeral("I")), Designa(ID("x"), Numeral("I")),
@@ -1165,7 +1165,7 @@ function_edge_tests = [
), ),
# REDI inside PER exits loop and function # REDI inside PER exits loop and function
( (
"DEFINI f () VT {\nPER x IN [I, II, III] FACE {\nSI x EST II TVNC {\nREDI (x)\n}\n}\n}\nINVOCA f ()", "DEFINI f () VT {\nPER x IN [I, II, III] FAC {\nSI x EST II TVNC {\nREDI (x)\n}\n}\n}\nINVOCA f ()",
Program([],[ Program([],[
Defini(ID("f"), [], [ Defini(ID("f"), [], [
PerStatement(DataArray([Numeral("I"), Numeral("II"), Numeral("III")]), ID("x"), [ PerStatement(DataArray([Numeral("I"), Numeral("II"), Numeral("III")]), ID("x"), [
@@ -1180,7 +1180,7 @@ function_edge_tests = [
), ),
# REDI inside nested loops exits all loops and function # REDI inside nested loops exits all loops and function
( (
"DEFINI f () VT {\nDESIGNA x VT I\nDVM FALSITAS FACE {\nDVM FALSITAS FACE {\nREDI (x)\n}\n}\n}\nINVOCA f ()", "DEFINI f () VT {\nDESIGNA x VT I\nDVM FALSITAS FAC {\nDVM FALSITAS FAC {\nREDI (x)\n}\n}\n}\nINVOCA f ()",
Program([],[ Program([],[
Defini(ID("f"), [], [ Defini(ID("f"), [], [
Designa(ID("x"), Numeral("I")), Designa(ID("x"), Numeral("I")),
@@ -1206,15 +1206,15 @@ class TestFunctionEdge(unittest.TestCase):
loop_edge_tests = [ loop_edge_tests = [
# [III VSQVE III] = [3] — single iteration # [III VSQVE III] = [3] — single iteration
("DONICVM i VT III VSQVE III FACE { DICE(i) }", ("DONICVM i VT III VSQVE III FAC { DIC(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("DIC", [ID("i")]))])]),
ValStr("III"), "III\n"), ValStr("III"), "III\n"),
# empty array — body never runs # empty array — body never runs
("PER i IN [] FACE { DICE(i) }", ("PER i IN [] FAC { DIC(i) }",
Program([], [PerStatement(DataArray([]), ID("i"), [ExpressionStatement(BuiltIn("DICE", [ID("i")]))])]), Program([], [PerStatement(DataArray([]), ID("i"), [ExpressionStatement(BuiltIn("DIC", [ID("i")]))])]),
ValNul(), ""), ValNul(), ""),
# PER breaks on element 2 — last assigned i is 2 # PER breaks on element 2 — last assigned i is 2
("PER i IN [I, II, III] FACE { SI i EST II TVNC { ERVMPE } }\ni", ("PER i IN [I, II, III] FAC { SI i EST II TVNC { ERVMPE } }\ni",
Program([], [ Program([], [
PerStatement( PerStatement(
DataArray([Numeral("I"), Numeral("II"), Numeral("III")]), DataArray([Numeral("I"), Numeral("II"), Numeral("III")]),
@@ -1225,7 +1225,7 @@ loop_edge_tests = [
]), ]),
ValInt(2), ""), ValInt(2), ""),
# nested DVM: inner always breaks; outer runs until btr==3 # nested DVM: inner always breaks; outer runs until btr==3
("DESIGNA btr VT I\nDVM btr EST III FACE {\nDVM FALSITAS FACE {\nERVMPE\n}\nDESIGNA btr VT btr + I\n}\nbtr", ("DESIGNA btr VT I\nDVM btr EST III FAC {\nDVM FALSITAS FAC {\nERVMPE\n}\nDESIGNA btr VT btr + I\n}\nbtr",
Program([], [ Program([], [
Designa(ID("btr"), Numeral("I")), Designa(ID("btr"), Numeral("I")),
DumStatement( DumStatement(
@@ -1237,7 +1237,7 @@ loop_edge_tests = [
ValInt(3), ""), ValInt(3), ""),
# nested PER: inner always breaks on first element; outer completes both iterations # nested PER: inner always breaks on first element; outer completes both iterations
# cnt starts at 1, increments twice → 3 # cnt starts at 1, increments twice → 3
("DESIGNA cnt VT I\nPER i IN [I, II] FACE {\nPER k IN [I, II] FACE {\nERVMPE\n}\nDESIGNA cnt VT cnt + I\n}\ncnt", ("DESIGNA cnt VT I\nPER i IN [I, II] FAC {\nPER k IN [I, II] FAC {\nERVMPE\n}\nDESIGNA cnt VT cnt + I\n}\ncnt",
Program([], [ Program([], [
Designa(ID("cnt"), Numeral("I")), Designa(ID("cnt"), Numeral("I")),
PerStatement( PerStatement(
@@ -1251,7 +1251,7 @@ loop_edge_tests = [
ValInt(3), ""), ValInt(3), ""),
# PER with CONTINVA: skip odd numbers, sum evens # PER with CONTINVA: skip odd numbers, sum evens
# [I,II,III,IV] → skip I and III; cnt increments on II and IV → cnt = III # [I,II,III,IV] → skip I and III; cnt increments on II and IV → cnt = III
("DESIGNA cnt VT I\nPER i IN [I, II, III, IV] FACE {\nSI i EST I AVT i EST III TVNC { CONTINVA }\nDESIGNA cnt VT cnt + I\n}\ncnt", ("DESIGNA cnt VT I\nPER i IN [I, II, III, IV] FAC {\nSI i EST I AVT i EST III TVNC { CONTINVA }\nDESIGNA cnt VT cnt + I\n}\ncnt",
Program([], [ Program([], [
Designa(ID("cnt"), Numeral("I")), Designa(ID("cnt"), Numeral("I")),
PerStatement( PerStatement(
@@ -1264,22 +1264,22 @@ loop_edge_tests = [
]), ]),
ValInt(3), ""), ValInt(3), ""),
# DVM with CONTINVA: skip body when x is II, increment regardless # DVM with CONTINVA: skip body when x is II, increment regardless
# x goes 1→2→3; on x=2 we continue (no DICE); DICE fires for x=1 and x=3 # x goes 1→2→3; on x=2 we continue (no DIC); DIC fires for x=1 and x=3
("DESIGNA x VT I\nDVM x EST IV FACE {\nSI x EST II TVNC { DESIGNA x VT x + I\nCONTINVA }\nDICE(x)\nDESIGNA x VT x + I\n}\nx", ("DESIGNA x VT I\nDVM x EST IV FAC {\nSI x EST II TVNC { DESIGNA x VT x + I\nCONTINVA }\nDIC(x)\nDESIGNA x VT x + I\n}\nx",
Program([], [ Program([], [
Designa(ID("x"), Numeral("I")), Designa(ID("x"), Numeral("I")),
DumStatement( DumStatement(
BinOp(ID("x"), Numeral("IV"), "KEYWORD_EST"), BinOp(ID("x"), Numeral("IV"), "KEYWORD_EST"),
[SiStatement(BinOp(ID("x"), Numeral("II"), "KEYWORD_EST"), [SiStatement(BinOp(ID("x"), Numeral("II"), "KEYWORD_EST"),
[Designa(ID("x"), BinOp(ID("x"), Numeral("I"), "SYMBOL_PLUS")), Continva()], None), [Designa(ID("x"), BinOp(ID("x"), Numeral("I"), "SYMBOL_PLUS")), Continva()], None),
ExpressionStatement(BuiltIn("DICE", [ID("x")])), ExpressionStatement(BuiltIn("DIC", [ID("x")])),
Designa(ID("x"), BinOp(ID("x"), Numeral("I"), "SYMBOL_PLUS"))], Designa(ID("x"), BinOp(ID("x"), Numeral("I"), "SYMBOL_PLUS"))],
), ),
ExpressionStatement(ID("x")), ExpressionStatement(ID("x")),
]), ]),
ValInt(4), "I\nIII\n"), ValInt(4), "I\nIII\n"),
# nested PER: CONTINVA in inner only skips rest of inner body; outer still increments # nested PER: CONTINVA in inner only skips rest of inner body; outer still increments
("DESIGNA cnt VT I\nPER i IN [I, II] FACE {\nPER k IN [I, II] FACE {\nCONTINVA\nDESIGNA cnt VT cnt + I\n}\nDESIGNA cnt VT cnt + I\n}\ncnt", ("DESIGNA cnt VT I\nPER i IN [I, II] FAC {\nPER k IN [I, II] FAC {\nCONTINVA\nDESIGNA cnt VT cnt + I\n}\nDESIGNA cnt VT cnt + I\n}\ncnt",
Program([], [ Program([], [
Designa(ID("cnt"), Numeral("I")), Designa(ID("cnt"), Numeral("I")),
PerStatement( PerStatement(
@@ -1293,7 +1293,7 @@ loop_edge_tests = [
]), ]),
ValInt(3), ""), ValInt(3), ""),
# DONICVM with CONTINVA: skip value III, count remaining (I VSQVE IV = [1,2,3,4], skip 3 → 3 increments) # 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 FAC {\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")),
PerStatement( PerStatement(
@@ -1306,7 +1306,7 @@ loop_edge_tests = [
]), ]),
ValInt(4)), 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 FAC {\nDESIGNA x VT x + I\n}\nx",
Program([], [ Program([], [
Designa(ID("x"), Numeral("I")), Designa(ID("x"), Numeral("I")),
DumStatement(Bool(True), [Designa(ID("x"), BinOp(ID("x"), Numeral("I"), "SYMBOL_PLUS"))]), DumStatement(Bool(True), [Designa(ID("x"), BinOp(ID("x"), Numeral("I"), "SYMBOL_PLUS"))]),
@@ -1314,15 +1314,15 @@ loop_edge_tests = [
]), ]),
ValInt(1), ""), ValInt(1), ""),
# two iterations: [I VSQVE II] = [1, 2] # two iterations: [I VSQVE II] = [1, 2]
("DONICVM i VT I VSQVE II FACE { DICE(i) }", ("DONICVM i VT I VSQVE II FAC { DIC(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("DIC", [ID("i")]))])]),
ValStr("II"), "I\nII\n"), ValStr("II"), "I\nII\n"),
# single iteration: [I VSQVE I] = [1] # single iteration: [I VSQVE I] = [1]
("DONICVM i VT I VSQVE I FACE { DICE(i) }", ("DONICVM i VT I VSQVE I FAC { DIC(i) }",
Program([], [PerStatement(DataRangeArray(Numeral("I"), Numeral("I")), ID("i"), [ExpressionStatement(BuiltIn("DICE", [ID("i")]))])]), Program([], [PerStatement(DataRangeArray(Numeral("I"), Numeral("I")), ID("i"), [ExpressionStatement(BuiltIn("DIC", [ID("i")]))])]),
ValStr("I"), "I\n"), ValStr("I"), "I\n"),
# empty range: [V VSQVE I] = [] # empty range: [V VSQVE I] = []
("DESIGNA x VT NVLLVS\nDONICVM i VT V VSQVE I FACE { DESIGNA x VT x + i }\nx", ("DESIGNA x VT NVLLVS\nDONICVM i VT V VSQVE I FAC { DESIGNA x VT x + i }\nx",
Program([], [Designa(ID("x"), Nullus()), Program([], [Designa(ID("x"), Nullus()),
PerStatement(DataRangeArray(Numeral("V"), Numeral("I")), ID("i"), PerStatement(DataRangeArray(Numeral("V"), Numeral("I")), ID("i"),
[Designa(ID("x"), BinOp(ID("x"), ID("i"), "SYMBOL_PLUS"))]), [Designa(ID("x"), BinOp(ID("x"), ID("i"), "SYMBOL_PLUS"))]),
@@ -1387,16 +1387,16 @@ class TestValues(unittest.TestCase):
magnvm_tests = [ magnvm_tests = [
# M+M+M+M = 4000; MAGNVM allows display as "MV_" # M+M+M+M = 4000; MAGNVM allows display as "MV_"
("CVM MAGNVM\nDICE(M + M + M + M)", ("CVM MAGNVM\nDIC(M + M + M + M)",
Program([ModuleCall("MAGNVM")], [ExpressionStatement(BuiltIn("DICE", [BinOp(BinOp(BinOp(Numeral("M"), Numeral("M"), "SYMBOL_PLUS"), Numeral("M"), "SYMBOL_PLUS"), Numeral("M"), "SYMBOL_PLUS")]))]), Program([ModuleCall("MAGNVM")], [ExpressionStatement(BuiltIn("DIC", [BinOp(BinOp(BinOp(Numeral("M"), Numeral("M"), "SYMBOL_PLUS"), Numeral("M"), "SYMBOL_PLUS"), Numeral("M"), "SYMBOL_PLUS")]))]),
ValStr("MV_"), "MV_\n"), ValStr("MV_"), "MV_\n"),
# I_ = 1000 with MAGNVM (same value as M, but written with thousands operator) # I_ = 1000 with MAGNVM (same value as M, but written with thousands operator)
("CVM MAGNVM\nI_", ("CVM MAGNVM\nI_",
Program([ModuleCall("MAGNVM")], [ExpressionStatement(Numeral("I_"))]), Program([ModuleCall("MAGNVM")], [ExpressionStatement(Numeral("I_"))]),
ValInt(1000), ""), ValInt(1000), ""),
# I_ + I_ = 2000; displayed as MM with MAGNVM # I_ + I_ = 2000; displayed as MM with MAGNVM
("CVM MAGNVM\nDICE(I_ + I_)", ("CVM MAGNVM\nDIC(I_ + I_)",
Program([ModuleCall("MAGNVM")], [ExpressionStatement(BuiltIn("DICE", [BinOp(Numeral("I_"), Numeral("I_"), "SYMBOL_PLUS")]))]), Program([ModuleCall("MAGNVM")], [ExpressionStatement(BuiltIn("DIC", [BinOp(Numeral("I_"), Numeral("I_"), "SYMBOL_PLUS")]))]),
ValStr("MM"), "MM\n"), ValStr("MM"), "MM\n"),
] ]
@@ -1425,10 +1425,10 @@ et_avt_tests = [
Program([], [ExpressionStatement(BinOp(BinOp(Numeral("I"), Numeral("II"), "KEYWORD_EST"), BinOp(Numeral("II"), Numeral("II"), "KEYWORD_EST"), "KEYWORD_AVT"))]), Program([], [ExpressionStatement(BinOp(BinOp(Numeral("I"), Numeral("II"), "KEYWORD_EST"), BinOp(Numeral("II"), Numeral("II"), "KEYWORD_EST"), "KEYWORD_AVT"))]),
ValBool(True)), ValBool(True)),
# used as SI condition # used as SI condition
("SI VERITAS ET VERITAS TVNC { DESIGNA r VT I } ALVID { DESIGNA r VT II }\nr", ("SI VERITAS ET VERITAS TVNC { DESIGNA r VT I } ALIVD { DESIGNA r VT II }\nr",
Program([], [SiStatement(BinOp(Bool(True), Bool(True), "KEYWORD_ET"), [Designa(ID("r"), Numeral("I"))], [Designa(ID("r"), Numeral("II"))]), ExpressionStatement(ID("r"))]), Program([], [SiStatement(BinOp(Bool(True), Bool(True), "KEYWORD_ET"), [Designa(ID("r"), Numeral("I"))], [Designa(ID("r"), Numeral("II"))]), ExpressionStatement(ID("r"))]),
ValInt(1)), ValInt(1)),
("SI FALSITAS AVT FALSITAS TVNC { DESIGNA r VT I } ALVID { DESIGNA r VT II }\nr", ("SI FALSITAS AVT FALSITAS TVNC { DESIGNA r VT I } ALIVD { DESIGNA r VT II }\nr",
Program([], [SiStatement(BinOp(Bool(False), Bool(False), "KEYWORD_AVT"), [Designa(ID("r"), Numeral("I"))], [Designa(ID("r"), Numeral("II"))]), ExpressionStatement(ID("r"))]), Program([], [SiStatement(BinOp(Bool(False), Bool(False), "KEYWORD_AVT"), [Designa(ID("r"), Numeral("I"))], [Designa(ID("r"), Numeral("II"))]), ExpressionStatement(ID("r"))]),
ValInt(2)), ValInt(2)),
] ]
@@ -1674,13 +1674,13 @@ class TestStringSlice(unittest.TestCase):
comment_tests = [ comment_tests = [
# trailing line comment # trailing line comment
('DICE("hello") // this is ignored', Program([], [ExpressionStatement(BuiltIn("DICE", [String("hello")]))]), ValStr("hello"), "hello\n"), ('DIC("hello") // this is ignored', Program([], [ExpressionStatement(BuiltIn("DIC", [String("hello")]))]), ValStr("hello"), "hello\n"),
# line comment on its own line before code # line comment on its own line before code
('// ignored\nDICE("hi")', Program([], [ExpressionStatement(BuiltIn("DICE", [String("hi")]))]), ValStr("hi"), "hi\n"), ('// ignored\nDIC("hi")', Program([], [ExpressionStatement(BuiltIn("DIC", [String("hi")]))]), ValStr("hi"), "hi\n"),
# inline block comment # inline block comment
('DICE(/* ignored */ "hi")', Program([], [ExpressionStatement(BuiltIn("DICE", [String("hi")]))]), ValStr("hi"), "hi\n"), ('DIC(/* ignored */ "hi")', Program([], [ExpressionStatement(BuiltIn("DIC", [String("hi")]))]), ValStr("hi"), "hi\n"),
# block comment spanning multiple lines # block comment spanning multiple lines
('/* line one\nline two */\nDICE("hi")', Program([], [ExpressionStatement(BuiltIn("DICE", [String("hi")]))]), ValStr("hi"), "hi\n"), ('/* line one\nline two */\nDIC("hi")', Program([], [ExpressionStatement(BuiltIn("DIC", [String("hi")]))]), ValStr("hi"), "hi\n"),
# block comment mid-expression # block comment mid-expression
("II /* ignored */ + III", Program([], [ExpressionStatement(BinOp(Numeral("II"), Numeral("III"), "SYMBOL_PLUS"))]), ValInt(5)), ("II /* ignored */ + III", Program([], [ExpressionStatement(BinOp(Numeral("II"), Numeral("III"), "SYMBOL_PLUS"))]), ValInt(5)),
# line comment after expression (no output) # line comment after expression (no output)
@@ -1688,7 +1688,7 @@ comment_tests = [
# division still works (/ token not confused with //) # division still works (/ token not confused with //)
("X / II", Program([], [ExpressionStatement(BinOp(Numeral("X"), Numeral("II"), "SYMBOL_DIVIDE"))]), ValInt(5)), ("X / II", Program([], [ExpressionStatement(BinOp(Numeral("X"), Numeral("II"), "SYMBOL_DIVIDE"))]), ValInt(5)),
# multiple line comments # multiple line comments
('// first\n// second\nDICE("ok")', Program([], [ExpressionStatement(BuiltIn("DICE", [String("ok")]))]), ValStr("ok"), "ok\n"), ('// first\n// second\nDIC("ok")', Program([], [ExpressionStatement(BuiltIn("DIC", [String("ok")]))]), ValStr("ok"), "ok\n"),
# comment-only line between two statements # comment-only line between two statements
('DESIGNA x VT I\n// set y\nDESIGNA y VT II\nx + y', ('DESIGNA x VT I\n// set y\nDESIGNA y VT II\nx + y',
Program([], [Designa(ID("x"), Numeral("I")), Designa(ID("y"), Numeral("II")), ExpressionStatement(BinOp(ID("x"), ID("y"), "SYMBOL_PLUS"))]), Program([], [Designa(ID("x"), Numeral("I")), Designa(ID("y"), Numeral("II")), ExpressionStatement(BinOp(ID("x"), ID("y"), "SYMBOL_PLUS"))]),
@@ -1716,13 +1716,13 @@ scope_tests = [
("SI VERITAS TVNC { DESIGNA r VT X }\nr", ("SI VERITAS TVNC { DESIGNA r VT X }\nr",
Program([], [SiStatement(Bool(True), [Designa(ID("r"), Numeral("X"))], None), ExpressionStatement(ID("r"))]), Program([], [SiStatement(Bool(True), [Designa(ID("r"), Numeral("X"))], None), ExpressionStatement(ID("r"))]),
ValInt(10)), ValInt(10)),
# SI: variable assigned in ALVID branch persists in outer scope # SI: variable assigned in ALIVD branch persists in outer scope
("SI FALSITAS TVNC { DESIGNA r VT X } ALVID { DESIGNA r VT V }\nr", ("SI FALSITAS TVNC { DESIGNA r VT X } ALIVD { DESIGNA r VT V }\nr",
Program([], [SiStatement(Bool(False), [Designa(ID("r"), Numeral("X"))], [Designa(ID("r"), Numeral("V"))]), ExpressionStatement(ID("r"))]), Program([], [SiStatement(Bool(False), [Designa(ID("r"), Numeral("X"))], [Designa(ID("r"), Numeral("V"))]), ExpressionStatement(ID("r"))]),
ValInt(5)), ValInt(5)),
# DVM: variable assigned in body persists after loop exits # DVM: variable assigned in body persists after loop exits
# x goes 1→2→3→4→5; r tracks x each iteration; loop exits when x==5 # x goes 1→2→3→4→5; r tracks x each iteration; loop exits when x==5
("DESIGNA x VT I\nDVM x EST V FACE { DESIGNA x VT x + I\nDESIGNA r VT x }\nr", ("DESIGNA x VT I\nDVM x EST V FAC { DESIGNA x VT x + I\nDESIGNA r VT x }\nr",
Program([], [ Program([], [
Designa(ID("x"), Numeral("I")), Designa(ID("x"), Numeral("I")),
DumStatement(BinOp(ID("x"), Numeral("V"), "KEYWORD_EST"), [ DumStatement(BinOp(ID("x"), Numeral("V"), "KEYWORD_EST"), [
@@ -1733,7 +1733,7 @@ scope_tests = [
]), ]),
ValInt(5)), ValInt(5)),
# PER: loop variable holds last array element after loop (no ERVMPE) # PER: loop variable holds last array element after loop (no ERVMPE)
("PER i IN [I, II, III] FACE { DESIGNA nop VT I }\ni", ("PER i IN [I, II, III] FAC { DESIGNA nop VT I }\ni",
Program([], [ Program([], [
PerStatement(DataArray([Numeral("I"), Numeral("II"), Numeral("III")]), ID("i"), [Designa(ID("nop"), Numeral("I"))]), PerStatement(DataArray([Numeral("I"), Numeral("II"), Numeral("III")]), ID("i"), [Designa(ID("nop"), Numeral("I"))]),
ExpressionStatement(ID("i")), ExpressionStatement(ID("i")),
@@ -1741,7 +1741,7 @@ scope_tests = [
ValInt(3)), ValInt(3)),
# PER: reassigning loop var in body doesn't prevent remaining iterations from running # PER: reassigning loop var in body doesn't prevent remaining iterations from running
# cnt increments once per iteration (all 3); C=100 doesn't replace next element assignment # cnt increments once per iteration (all 3); C=100 doesn't replace next element assignment
("DESIGNA cnt VT I\nPER i IN [I, II, III] FACE { DESIGNA i VT C\nDESIGNA cnt VT cnt + I }\ncnt", ("DESIGNA cnt VT I\nPER i IN [I, II, III] FAC { DESIGNA i VT C\nDESIGNA cnt VT cnt + I }\ncnt",
Program([], [ Program([], [
Designa(ID("cnt"), Numeral("I")), Designa(ID("cnt"), Numeral("I")),
PerStatement(DataArray([Numeral("I"), Numeral("II"), Numeral("III")]), ID("i"), [ PerStatement(DataArray([Numeral("I"), Numeral("II"), Numeral("III")]), ID("i"), [
@@ -1753,7 +1753,7 @@ scope_tests = [
ValInt(4)), ValInt(4)),
# PER: loop var after loop reflects the last body assignment, not the last array element # PER: loop var after loop reflects the last body assignment, not the last array element
# body sets i=C=100 on every iteration; after loop ends, i stays at 100 # body sets i=C=100 on every iteration; after loop ends, i stays at 100
("PER i IN [I, II, III] FACE { DESIGNA i VT C }\ni", ("PER i IN [I, II, III] FAC { DESIGNA i VT C }\ni",
Program([], [ Program([], [
PerStatement(DataArray([Numeral("I"), Numeral("II"), Numeral("III")]), ID("i"), [Designa(ID("i"), Numeral("C"))]), PerStatement(DataArray([Numeral("I"), Numeral("II"), Numeral("III")]), ID("i"), [Designa(ID("i"), Numeral("C"))]),
ExpressionStatement(ID("i")), ExpressionStatement(ID("i")),
@@ -1761,7 +1761,7 @@ 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,4]; last value assigned by loop is IV=4 # [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 FAC { 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")),
@@ -1769,7 +1769,7 @@ scope_tests = [
ValInt(4)), 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 4 times → 5 # 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 FAC { DESIGNA cnt VT cnt + I\nDESIGNA i VT C }\ncnt",
Program([], [ Program([], [
Designa(ID("cnt"), Numeral("I")), Designa(ID("cnt"), Numeral("I")),
PerStatement(DataRangeArray(Numeral("I"), Numeral("IV")), ID("i"), [ PerStatement(DataRangeArray(Numeral("I"), Numeral("IV")), ID("i"), [
@@ -1780,7 +1780,7 @@ scope_tests = [
]), ]),
ValInt(5)), 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 FAC {\nSI i EST III TVNC { ERVMPE }\n}\ni",
Program([], [ Program([], [
PerStatement(DataRangeArray(Numeral("I"), Numeral("X")), ID("i"), [ PerStatement(DataRangeArray(Numeral("I"), Numeral("X")), ID("i"), [
SiStatement(BinOp(ID("i"), Numeral("III"), "KEYWORD_EST"), [Erumpe()], None), SiStatement(BinOp(ID("i"), Numeral("III"), "KEYWORD_EST"), [Erumpe()], None),
@@ -1956,9 +1956,9 @@ fractio_tests = [
ValFrac(Fraction(0)) ValFrac(Fraction(0))
), ),
# String concatenation with fraction # String concatenation with fraction
("CVM FRACTIO\nDICE(IIIS & \"!\")", ("CVM FRACTIO\nDIC(IIIS & \"!\")",
Program([ModuleCall("FRACTIO")], [ Program([ModuleCall("FRACTIO")], [
ExpressionStatement(BuiltIn("DICE", [BinOp(Fractio("IIIS"), String("!"), "SYMBOL_AMPERSAND")])) ExpressionStatement(BuiltIn("DIC", [BinOp(Fractio("IIIS"), String("!"), "SYMBOL_AMPERSAND")]))
]), ]),
ValStr("IIIS!"), "IIIS!\n" ValStr("IIIS!"), "IIIS!\n"
), ),
@@ -2216,7 +2216,7 @@ class TestDictBuiltins(unittest.TestCase):
dict_iteration_tests = [ dict_iteration_tests = [
# PER iterates over keys # PER iterates over keys
('DESIGNA r VT ""\nPER k IN TABVLA {"a" VT I, "b" VT II} FACE {\nDESIGNA r VT r & k\n}\nr', ('DESIGNA r VT ""\nPER k IN TABVLA {"a" VT I, "b" VT II} FAC {\nDESIGNA r VT r & k\n}\nr',
Program([], [ Program([], [
Designa(ID("r"), String("")), Designa(ID("r"), String("")),
PerStatement( PerStatement(
@@ -2236,17 +2236,17 @@ class TestDictIteration(unittest.TestCase):
dict_display_tests = [ dict_display_tests = [
# DICE on dict # DIC on dict
('DICE(TABVLA {"a" VT I})', ('DIC(TABVLA {"a" VT I})',
Program([], [ExpressionStatement(BuiltIn("DICE", [DataDict([(String("a"), Numeral("I"))])]))]), Program([], [ExpressionStatement(BuiltIn("DIC", [DataDict([(String("a"), Numeral("I"))])]))]),
ValStr("{a VT I}"), "{a VT I}\n"), ValStr("{a VT I}"), "{a VT I}\n"),
# DICE on multi-entry dict # DIC on multi-entry dict
('DICE(TABVLA {"a" VT I, "b" VT II})', ('DIC(TABVLA {"a" VT I, "b" VT II})',
Program([], [ExpressionStatement(BuiltIn("DICE", [DataDict([(String("a"), Numeral("I")), (String("b"), Numeral("II"))])]))]), Program([], [ExpressionStatement(BuiltIn("DIC", [DataDict([(String("a"), Numeral("I")), (String("b"), Numeral("II"))])]))]),
ValStr("{a VT I, b VT II}"), "{a VT I, b VT II}\n"), ValStr("{a VT I, b VT II}"), "{a VT I, b VT II}\n"),
# DICE on empty dict # DIC on empty dict
('DICE(TABVLA {})', ('DIC(TABVLA {})',
Program([], [ExpressionStatement(BuiltIn("DICE", [DataDict([])]))]), Program([], [ExpressionStatement(BuiltIn("DIC", [DataDict([])]))]),
ValStr("{}"), "{}\n"), ValStr("{}"), "{}\n"),
] ]
@@ -2348,12 +2348,12 @@ fvnctio_tests = [
]), ]),
ValInt(6), ValInt(6),
), ),
# DICE on a function value # DIC on a function value
( (
"DESIGNA f VT FVNCTIO (x) VT { REDI (x) }\nDICE(f)", "DESIGNA f VT FVNCTIO (x) VT { REDI (x) }\nDIC(f)",
Program([], [ Program([], [
Designa(ID("f"), Fvnctio([ID("x")], [Redi([ID("x")])])), Designa(ID("f"), Fvnctio([ID("x")], [Redi([ID("x")])])),
ExpressionStatement(BuiltIn("DICE", [ID("f")])), ExpressionStatement(BuiltIn("DIC", [ID("f")])),
]), ]),
ValStr("FVNCTIO"), ValStr("FVNCTIO"),
"FVNCTIO\n", "FVNCTIO\n",
@@ -2531,7 +2531,7 @@ class TestScripta(unittest.TestCase):
with tempfile.NamedTemporaryFile(suffix=".txt", delete=False) as f: with tempfile.NamedTemporaryFile(suffix=".txt", delete=False) as f:
path = f.name path = f.name
try: try:
source = f'CVM SCRIPTA\nSCRIBE("{path}", "SALVE MVNDE")\nDICE(LEGE("{path}"))' source = f'CVM SCRIPTA\nSCRIBE("{path}", "SALVE MVNDE")\nDIC(LEGE("{path}"))'
program = self._run_scripta(source) program = self._run_scripta(source)
captured = StringIO() captured = StringIO()
with patch("sys.stdout", captured): with patch("sys.stdout", captured):
@@ -2547,7 +2547,7 @@ class TestScripta(unittest.TestCase):
with tempfile.NamedTemporaryFile(suffix=".txt", delete=False) as f: with tempfile.NamedTemporaryFile(suffix=".txt", delete=False) as f:
path = f.name path = f.name
try: try:
source = f'CVM SCRIPTA\nSCRIBE("{path}", "SALVE MVNDE")\nDICE(LEGE("{path}"))' source = f'CVM SCRIPTA\nSCRIBE("{path}", "SALVE MVNDE")\nDIC(LEGE("{path}"))'
program = self._run_scripta(source) program = self._run_scripta(source)
output = self._compile_and_run(program) output = self._compile_and_run(program)
self.assertEqual(output, "SALVE MVNDE\n") self.assertEqual(output, "SALVE MVNDE\n")
@@ -2561,7 +2561,7 @@ class TestScripta(unittest.TestCase):
with tempfile.NamedTemporaryFile(suffix=".txt", delete=False) as f: with tempfile.NamedTemporaryFile(suffix=".txt", delete=False) as f:
path = f.name path = f.name
try: try:
source = f'CVM SCRIPTA\nSCRIBE("{path}", "SALVE")\nADIVNGE("{path}", " MVNDE")\nDICE(LEGE("{path}"))' source = f'CVM SCRIPTA\nSCRIBE("{path}", "SALVE")\nADIVNGE("{path}", " MVNDE")\nDIC(LEGE("{path}"))'
program = self._run_scripta(source) program = self._run_scripta(source)
captured = StringIO() captured = StringIO()
with patch("sys.stdout", captured): with patch("sys.stdout", captured):
@@ -2575,7 +2575,7 @@ class TestScripta(unittest.TestCase):
with tempfile.NamedTemporaryFile(suffix=".txt", delete=False) as f: with tempfile.NamedTemporaryFile(suffix=".txt", delete=False) as f:
path = f.name path = f.name
try: try:
source = f'CVM SCRIPTA\nSCRIBE("{path}", "SALVE")\nADIVNGE("{path}", " MVNDE")\nDICE(LEGE("{path}"))' source = f'CVM SCRIPTA\nSCRIBE("{path}", "SALVE")\nADIVNGE("{path}", " MVNDE")\nDIC(LEGE("{path}"))'
program = self._run_scripta(source) program = self._run_scripta(source)
output = self._compile_and_run(program) output = self._compile_and_run(program)
self.assertEqual(output, "SALVE MVNDE\n") self.assertEqual(output, "SALVE MVNDE\n")
@@ -2722,7 +2722,7 @@ tempta_tests = [
), ),
# ERVMPE inside catch block (inside a loop) # ERVMPE inside catch block (inside a loop)
( (
"DESIGNA r VT NVLLVS\nDVM r EST I FACE {\nTEMPTA {\nDESIGNA x VT I / NVLLVS\n} CAPE e {\nDESIGNA r VT I\nERVMPE\n}\n}\nr", "DESIGNA r VT NVLLVS\nDVM r EST I FAC {\nTEMPTA {\nDESIGNA x VT I / NVLLVS\n} CAPE e {\nDESIGNA r VT I\nERVMPE\n}\n}\nr",
Program([], [ Program([], [
Designa(ID("r"), Nullus()), Designa(ID("r"), Nullus()),
DumStatement( DumStatement(

View File

@@ -8,9 +8,9 @@ VSCode extension for [CENTVRION](https://github.com/NikolajDanger/centvrion) —
Provides syntax highlighting for `.cent` files, covering: Provides syntax highlighting for `.cent` files, covering:
- **Keywords** — `SI`, `TVNC`, `ALVID`, `DVM`, `FACE`, `PER`, `IN`, `DEFINI`, `VT`, `DESIGNA`, `REDI`, `ERVMPE`, `INVOCA`, and more - **Keywords** — `SI`, `TVNC`, `ALIVD`, `DVM`, `FAC`, `PER`, `IN`, `DEFINI`, `VT`, `DESIGNA`, `REDI`, `ERVMPE`, `INVOCA`, and more
- **Operators** — `EST` (equality), `MINVS` (less than), `PLVS` (greater than), `ET` (and), `AVT` (or), arithmetic (`+`, `-`, `*`, `/`) - **Operators** — `EST` (equality), `MINVS` (less than), `PLVS` (greater than), `ET` (and), `AVT` (or), arithmetic (`+`, `-`, `*`, `/`)
- **Built-in functions** — `DICE` (print), `AVDI` (input), `AVDI_NVMERVS`, `FORTIS_NVMERVS`, `FORTIS_ELECTIONIS`, `LONGITVDO` - **Built-in functions** — `DIC` (print), `AVDI` (input), `AVDI_NVMERVS`, `FORTVITVS_NVMERVS`, `FORTVITA_ELECTIO`, `LONGITVDO`
- **Literals** — Roman numeral constants (e.g. `XIV`, `MMXXIV`), booleans (`VERITAS`, `FALSITAS`), null (`NVLLVS`) - **Literals** — Roman numeral constants (e.g. `XIV`, `MMXXIV`), booleans (`VERITAS`, `FALSITAS`), null (`NVLLVS`)
- **Strings** — single and double quoted, with escape sequences - **Strings** — single and double quoted, with escape sequences
- **Variables** — lowercase Latin identifiers - **Variables** — lowercase Latin identifiers

View File

@@ -45,7 +45,7 @@
"patterns": [ "patterns": [
{ {
"name": "keyword.control.cent", "name": "keyword.control.cent",
"match": "\\b(AETERNVM|ALVID|AVT|CONTINVA|CVM|DEFINI|DESIGNA|DONICVM|DVM|ERVMPE|ET|FACE|FVNCTIO|IN|INVOCA|NON|PER|REDI|SI|TVNC|VSQVE|VT)\\b" "match": "\\b(AETERNVM|ALIVD|AVT|CONTINVA|CVM|DEFINI|DESIGNA|DONICVM|DVM|ERVMPE|ET|FAC|FVNCTIO|IN|INVOCA|NON|PER|REDI|SI|TVNC|VSQVE|VT)\\b"
}, },
{ {
"name": "keyword.operator.comparison.cent", "name": "keyword.operator.comparison.cent",
@@ -65,7 +65,7 @@
"patterns": [ "patterns": [
{ {
"name": "support.function.builtin.cent", "name": "support.function.builtin.cent",
"match": "\\b(AVDI_NVMERVS|AVDI|DECIMATIO|DICE|EVERRO|FORTIS_NVMERVS|FORTIS_ELECTIONIS|LONGITVDO|SEMEN)\\b" "match": "\\b(AVDI_NVMERVS|AVDI|DECIMATIO|DIC|EVERRE|FORTVITVS_NVMERVS|FORTVITA_ELECTIO|LONGITVDO|SEMEN)\\b"
} }
] ]
}, },