Compare commits

...

2 Commits

Author SHA1 Message Date
ebea9f942b 🐐 Fixing latin 2026-04-21 23:46:00 +02:00
4f78450756 🐐 Snippets 2026-04-21 23:24:09 +02:00
59 changed files with 355 additions and 355 deletions

View File

@@ -171,19 +171,19 @@ Will return `I` (1), as the conditional evaluates `x` to be true.
### Boolean expressions
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
```
`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
@@ -218,8 +218,8 @@ The keyword `ET` can be used as a boolean "and". The keyword `AVT` can be used a
### AETERNVM loops
`AETERNVM FACE { ... }` is shorthand for an infinite loop — equivalent
to `DVM FALSITAS FACE { ... }` but without relying on `DVM`'s inverted
`AETERNVM FAC { ... }` is shorthand for an infinite loop — equivalent
to `DVM FALSITAS FAC { ... }` but without relying on `DVM`'s inverted
condition. Exit the loop with `ERVMPE` (or `REDI` from inside a function).
![AETERNVM loop](snippets/aeternvm.png)
@@ -248,7 +248,7 @@ Errors can be caught using `TEMPTA` (temptare = to try) and `CAPE` (capere = to
TEMPTA {
DESIGNA x VT I / NVLLVS
} 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.
## Built-ins
### DICE
`DICE(value, ...)`
### DIC
`DIC(value, ...)`
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()`
@@ -361,11 +361,11 @@ Vnlike many other programming languages with modules, the modules in `CENTVRION`
### FORS
![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.

View File

@@ -935,7 +935,7 @@ class SiStatement(Node):
result = f"SI {self.test.print()} TVNC {{\n{body}\n}}"
if 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
def _eval(self, vtable):
@@ -972,7 +972,7 @@ class DumStatement(Node):
def print(self):
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):
last_val = ValNul()
@@ -1016,7 +1016,7 @@ class PerStatement(Node):
def print(self):
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):
vtable, array = self.data_list.eval(vtable)
@@ -1158,7 +1158,7 @@ class BuiltIn(Node):
raise CentvrionError(f"Invalid numeral input: {raw!r}")
case "AVDI":
return vtable, ValStr(input())
case "DICE":
case "DIC":
print_string = ' '.join(
make_string(i, magnvm, svbnvlla) for i in params
)
@@ -1167,23 +1167,23 @@ class BuiltIn(Node):
case "ERVMPE":
vtable["#break"] = True
return vtable, ValNul()
case "FORTIS_NVMERVS":
case "FORTVITVS_NVMERVS":
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()
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:
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))
case "FORTIS_ELECTIONIS":
case "FORTVITA_ELECTIO":
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):
raise CentvrionError("FORTIS_ELECTIONIS requires an array")
raise CentvrionError("FORTVITA_ELECTIO requires an array")
lst = params[0].value()
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)]
case "SEMEN":
if "FORS" not in vtable["#modules"]:
@@ -1222,7 +1222,7 @@ class BuiltIn(Node):
raise CentvrionError("CLAVES requires a dict")
keys = [ValStr(k) if isinstance(k, str) else ValInt(k) for k in params[0].value().keys()]
return vtable, ValList(keys)
case "EVERRO":
case "EVERRE":
print("\033[2J\033[H", end="", flush=True)
return vtable, ValNul()
case "ORDINA":

View File

@@ -188,12 +188,12 @@ def _emit_builtin(node, ctx):
tmp = ctx.fresh_tmp()
match node.builtin:
case "DICE":
case "DIC":
if not param_vars:
lines.append('cent_dice(cent_str(""));')
lines.append('cent_dic(cent_str(""));')
lines.append(f'CentValue {tmp} = cent_str("");')
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]};")
else:
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 {joined_tmp} = cent_concat({space_tmp}, {pv});")
acc = joined_tmp
lines.append(f"cent_dice({acc});")
lines.append(f"cent_dic({acc});")
lines.append(f"CentValue {tmp} = {acc};")
case "AVDI":
@@ -215,19 +215,19 @@ def _emit_builtin(node, ctx):
case "LONGITVDO":
lines.append(f"CentValue {tmp} = cent_longitudo({param_vars[0]});")
case "FORTIS_NVMERVS":
case "FORTVITVS_NVMERVS":
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();")
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"):
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();")
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":
if not ctx.has_module("FORS"):
@@ -263,8 +263,8 @@ def _emit_builtin(node, ctx):
case "ORDINA":
lines.append(f"CentValue {tmp} = cent_ordina({param_vars[0]});")
case "EVERRO":
lines.append("cent_everro();")
case "EVERRE":
lines.append("cent_everre();")
lines.append(f"CentValue {tmp} = cent_null();")
case "TYPVS":

View File

@@ -521,13 +521,13 @@ CentValue cent_or(CentValue a, CentValue b) {
/* Builtin functions */
/* ------------------------------------------------------------------ */
void cent_dice(CentValue v) {
void cent_dic(CentValue v) {
char *s = cent_make_string(v);
fputs(s, stdout);
fputc('\n', stdout);
}
void cent_everro(void) {
void cent_everre(void) {
fputs("\033[2J\033[H", stdout);
fflush(stdout);
}
@@ -622,20 +622,20 @@ void cent_adivnge(CentValue path, CentValue content) {
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)
cent_type_error("'FORTIS_NVMERVS' requires two integers");
cent_type_error("'FORTVITVS_NVMERVS' requires two integers");
long range = hi.ival - lo.ival + 1;
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);
}
CentValue cent_fortis_electionis(CentValue lst) {
CentValue cent_fortuita_electionis(CentValue lst) {
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)
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];
}

View File

@@ -216,15 +216,15 @@ CentValue cent_or (CentValue a, CentValue b); /* AVT → BOOL */
/* Builtin functions */
/* ------------------------------------------------------------------ */
void cent_dice(CentValue v); /* DICE */
void cent_dic(CentValue v); /* DIC */
CentValue cent_avdi(void); /* AVDI */
CentValue cent_avdi_numerus(void); /* AVDI_NVMERVS */
CentValue cent_longitudo(CentValue v); /* LONGITVDO */
CentValue cent_fortis_numerus(CentValue lo, CentValue hi); /* FORTIS_NVMERVS */
CentValue cent_fortis_electionis(CentValue lst); /* FORTIS_ELECTIONIS */
CentValue cent_fortuitus_numerus(CentValue lo, CentValue hi); /* FORTVITVS_NVMERVS */
CentValue cent_fortuita_electionis(CentValue lst); /* FORTVITA_ELECTIO */
CentValue cent_decimatio(CentValue lst); /* DECIMATIO */
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_typvs(CentValue v); /* TYPVS */
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 [
"AETERNVM",
"ALVID",
"ALIVD",
"AVGE",
"CAPE",
"AVT",
@@ -17,7 +17,7 @@ keyword_tokens = [("KEYWORD_"+i, i) for i in [
"ERVMPE",
"EST",
"ET",
"FACE",
"FAC",
"FALSITAS",
"FVNCTIO",
"INVOCA",
@@ -45,11 +45,11 @@ builtin_tokens = [("BUILTIN", i) for i in [
"AVDI",
"CLAVES",
"DECIMATIO",
"DICE",
"DIC",
"DORMI",
"EVERRO",
"FORTIS_NVMERVS",
"FORTIS_ELECTIONIS",
"EVERRE",
"FORTVITVS_NVMERVS",
"FORTVITA_ELECTIO",
"LONGITVDO",
"ORDINA",
"SEMEN",

View File

@@ -183,24 +183,24 @@ class Parser():
else:
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):
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):
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):
return ast_nodes.DumStatement(tokens[1], tokens[4])
# 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):
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):
return ast_nodes.PerStatement(tokens[3], tokens[1], tokens[6])
@@ -208,7 +208,7 @@ class Parser():
def tempta(tokens):
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):
range_array = ast_nodes.DataRangeArray(tokens[3], tokens[5])
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 svm VT NVLLVS
PER x IN array FACE {
PER x IN array FAC {
DESIGNA svm VT svm + x
SI x PLVS max TVNC {
DESIGNA max VT x
}
}
DICE("Sum:", svm)
DICE("Max:", max)
DIC("Sum:", svm)
DIC("Max:", max)

View File

@@ -3,8 +3,8 @@
DESIGNA arr VT [V, III, VIII, I, IX, II, VII, IV, VI, X]
DESIGNA n VT LONGITVDO(arr)
DONICVM i VT I VSQVE n - I FACE {
DONICVM k VT I VSQVE n - i FACE {
DONICVM i VT I VSQVE n - I FAC {
DONICVM k VT I VSQVE n - i FAC {
SI arr[k] PLVS arr[k + I] TVNC {
DESIGNA temp VT arr[k]
DESIGNA arr[k] VT arr[k + I]
@@ -13,6 +13,6 @@ DONICVM i VT I VSQVE n - I FACE {
}
}
PER x IN arr FACE {
DICE(x)
PER x IN arr FAC {
DIC(x)
}

View File

@@ -6,7 +6,7 @@
// Returns the bottommost empty row in col, or NVLLVS if full
DEFINI find_slot(b, col) VT {
DESIGNA ans VT NVLLVS
DONICVM r VT I VSQVE VI FACE {
DONICVM r VT I VSQVE VI FAC {
SI b[(r - I) * VII + col] EST NVLLVS TVNC {
DESIGNA ans VT r
}
@@ -16,32 +16,32 @@ DEFINI find_slot(b, col) VT {
// Returns VERITAS if player has four in a row
DEFINI est_victor(b, player) VT {
DONICVM r VT I VSQVE VI FACE {
DONICVM c VT I VSQVE IV FACE {
DONICVM r VT I VSQVE VI FAC {
DONICVM c VT I VSQVE IV FAC {
DESIGNA idx VT (r - I) * VII + c
SI b[idx] EST player ET b[idx + I] EST player ET b[idx + II] EST player ET b[idx + III] EST player TVNC {
REDI(VERITAS)
}
}
}
DONICVM r VT I VSQVE III FACE {
DONICVM c VT I VSQVE VII FACE {
DONICVM r VT I VSQVE III FAC {
DONICVM c VT I VSQVE VII FAC {
DESIGNA idx VT (r - I) * VII + c
SI b[idx] EST player ET b[idx + VII] EST player ET b[idx + XIV] EST player ET b[idx + XXI] EST player TVNC {
REDI(VERITAS)
}
}
}
DONICVM r VT I VSQVE III FACE {
DONICVM c VT I VSQVE IV FACE {
DONICVM r VT I VSQVE III FAC {
DONICVM c VT I VSQVE IV FAC {
DESIGNA idx VT (r - I) * VII + c
SI b[idx] EST player ET b[idx + VIII] EST player ET b[idx + XVI] EST player ET b[idx + XXIV] EST player TVNC {
REDI(VERITAS)
}
}
}
DONICVM r VT I VSQVE III FACE {
DONICVM c VT IV VSQVE VII FACE {
DONICVM r VT I VSQVE III FAC {
DONICVM c VT IV VSQVE VII FAC {
DESIGNA idx VT (r - I) * VII + c
SI b[idx] EST player ET b[idx + VI] EST player ET b[idx + XII] EST player ET b[idx + XVIII] EST player TVNC {
REDI(VERITAS)
@@ -52,23 +52,23 @@ DEFINI est_victor(b, player) VT {
}
DEFINI print_board(b) VT {
DICE("+---+---+---+---+---+---+---+")
DONICVM r VT I VSQVE VI FACE {
DIC("+---+---+---+---+---+---+---+")
DONICVM r VT I VSQVE VI FAC {
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]
SI cell EST I TVNC {
DESIGNA line VT line & "X | "
} ALVID SI cell EST II TVNC {
} ALIVD SI cell EST II TVNC {
DESIGNA line VT line & "O | "
} ALVID {
} ALIVD {
DESIGNA line VT line & ". | "
}
}
DICE(line)
DIC(line)
}
DICE("+---+---+---+---+---+---+---+")
DICE(" I II III IV V VI VII")
DIC("+---+---+---+---+---+---+---+")
DIC(" I II III IV V VI VII")
REDI(NVLLVS)
}
@@ -101,35 +101,35 @@ DEFINI score_fenestram(a, b, c, d) VT {
DEFINI aestima(b) VT {
DESIGNA score VT NVLLVS
// Center column preference: each AI piece in column IV is worth +1
DONICVM r VT I VSQVE VI FACE {
DONICVM r VT I VSQVE VI FAC {
SI b[(r - I) * VII + IV] EST II TVNC {
DESIGNA score VT score + I
}
}
// Horizontal windows (6 rows x 4 starting columns = 24)
DONICVM r VT I VSQVE VI FACE {
DONICVM c VT I VSQVE IV FACE {
DONICVM r VT I VSQVE VI FAC {
DONICVM c VT I VSQVE IV FAC {
DESIGNA idx VT (r - I) * VII + c
DESIGNA score VT score + INVOCA score_fenestram(b[idx], b[idx + I], b[idx + II], b[idx + III])
}
}
// Vertical windows (3 starting rows x 7 columns = 21)
DONICVM r VT I VSQVE III FACE {
DONICVM c VT I VSQVE VII FACE {
DONICVM r VT I VSQVE III FAC {
DONICVM c VT I VSQVE VII FAC {
DESIGNA idx VT (r - I) * VII + c
DESIGNA score VT score + INVOCA score_fenestram(b[idx], b[idx + VII], b[idx + XIV], b[idx + XXI])
}
}
// Diagonal up-right windows (3 starting rows x 4 starting columns = 12)
DONICVM r VT I VSQVE III FACE {
DONICVM c VT I VSQVE IV FACE {
DONICVM r VT I VSQVE III FAC {
DONICVM c VT I VSQVE IV FAC {
DESIGNA idx VT (r - I) * VII + c
DESIGNA score VT score + INVOCA score_fenestram(b[idx], b[idx + VIII], b[idx + XVI], b[idx + XXIV])
}
}
// Diagonal up-left windows (3 starting rows x 4 starting columns = 12)
DONICVM r VT I VSQVE III FACE {
DONICVM c VT IV VSQVE VII FACE {
DONICVM r VT I VSQVE III FAC {
DONICVM c VT IV VSQVE VII FAC {
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])
}
@@ -146,7 +146,7 @@ DEFINI minimax(b, depth, alpha, beta, maxi) VT {
SI INVOCA est_victor(b, I) TVNC {
REDI(NVLLVS - M - depth)
}
} ALVID {
} ALIVD {
SI INVOCA est_victor(b, II) TVNC {
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]
SI maxi TVNC {
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)
SI NON (linea EST NVLLVS) TVNC {
DESIGNA b[(linea - I) * VII + c] VT II
@@ -175,9 +175,9 @@ DEFINI minimax(b, depth, alpha, beta, maxi) VT {
}
}
REDI(best)
} ALVID {
} ALIVD {
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)
SI NON (linea EST NVLLVS) TVNC {
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 best_score VT NVLLVS - M - VII
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)
SI NON (linea EST NVLLVS) TVNC {
DESIGNA b[(linea - I) * VII + c] VT II
@@ -220,63 +220,63 @@ DEFINI ai_move(b) VT {
// --- Board setup ---
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 moves VT NVLLVS
DESIGNA game_over VT FALSITAS
DICE("=== CONNECT IV ===")
DICE("You are X. AI is O.")
DICE("Enter column as Roman numeral (I-VII).")
DICE("")
DIC("=== CONNECT IV ===")
DIC("You are X. AI is O.")
DIC("Enter column as Roman numeral (I-VII).")
DIC("")
DVM game_over FACE {
EVERRO()
DVM game_over FAC {
EVERRE()
INVOCA print_board(board)
DICE("Your move:")
DIC("Your move:")
DESIGNA col VT AVDI_NVMERVS()
SI col PLVS VII TVNC {
DICE("Invalid column! Enter I through VII.")
DIC("Invalid column! Enter I through VII.")
CONTINVA
}
DESIGNA linea VT INVOCA find_slot(board, col)
SI linea EST NVLLVS TVNC {
DICE("Column full! Try another.")
DIC("Column full! Try another.")
CONTINVA
}
DESIGNA board[(linea - I) * VII + col] VT I
DESIGNA moves VT moves + I
SI INVOCA est_victor(board, I) TVNC {
INVOCA print_board(board)
DICE("You win!")
DIC("You win!")
DESIGNA game_over VT VERITAS
CONTINVA
}
SI moves EST XLII TVNC {
INVOCA print_board(board)
DICE("Draw!")
DIC("Draw!")
DESIGNA game_over VT VERITAS
CONTINVA
}
DICE("AI is thinking...")
DIC("AI is thinking...")
DESIGNA col VT INVOCA ai_move(board)
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 moves VT moves + I
SI INVOCA est_victor(board, II) TVNC {
INVOCA print_board(board)
DICE("AI wins!")
DIC("AI wins!")
DESIGNA game_over VT VERITAS
CONTINVA
}
SI moves EST XLII TVNC {
INVOCA print_board(board)
DICE("Draw!")
DIC("Draw!")
DESIGNA game_over VT VERITAS
}
}

View File

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

View File

@@ -4,9 +4,9 @@ CVM MAGNVM
DEFINI fact(n) VT {
SI n MINVS I TVNC {
REDI(I)
} ALVID {
} ALIVD {
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
CVM FORS
DESIGNA correct VT FORTIS_NVMERVS(I,C)
DESIGNA correct VT FORTVITVS_NVMERVS(I,C)
DESIGNA gvess VT NVLLVS
DVM correct EST gvess FACE {
DVM correct EST gvess FAC {
DESIGNA gvess VT AVDI_NVMERVS()
SI gvess MINVS correct TVNC {
DICE("Too low!")
} ALVID SI gvess PLVS correct TVNC {
DICE("Too high!")
DIC("Too low!")
} ALIVD SI gvess PLVS correct TVNC {
DIC("Too high!")
}
}
DICE("You guessed correctly!")
DIC("You guessed correctly!")

View File

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

View File

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

View File

@@ -2,14 +2,14 @@
DESIGNA n VT L
DONICVM i VT II VSQVE n FACE {
DONICVM i VT II VSQVE n FAC {
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 {
DESIGNA is_prime VT FALSITAS
}
}
SI is_prime TVNC {
DICE(i)
DIC(i)
}
}

View File

@@ -35,10 +35,10 @@
\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}{\textit{if-statement}} \\
\languageline{statement}{\texttt{DVM} \textit{expression} \texttt{FACE} \textit{scope}} \\
\languageline{statement}{\texttt{AETERNVM} \texttt{FACE} \textit{scope}} \\
\languageline{statement}{\texttt{PER} \textbf{id} \texttt{IN} \textit{expression} \texttt{FACE} \textit{scope}} \\
\languageline{statement}{\texttt{DONICVM} \textbf{id} \texttt{VT} \textit{expression} \texttt{VSQVE} \textit{expression} \texttt{FACE} \textit{scope}} \\
\languageline{statement}{\texttt{DVM} \textit{expression} \texttt{FAC} \textit{scope}} \\
\languageline{statement}{\texttt{AETERNVM} \texttt{FAC} \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{FAC} \textit{scope}} \\
\languageline{statement}{\texttt{REDI(} \textit{optional-expressions} \texttt{)}} \\
\languageline{statement}{\texttt{ERVMPE}} \\
\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} \textit{optional-newline} \textit{else-statement}} \\ \hline
\languageline{else-statement}{\texttt{ALVID} \textit{scope}} \\
\languageline{else-statement}{\texttt{ALVID} \textit{if-statement}} \\ \hline
\languageline{else-statement}{\texttt{ALIVD} \textit{scope}} \\
\languageline{else-statement}{\texttt{ALIVD} \textit{if-statement}} \\ \hline
\languageline{scope}{\textit{optional-newline} \texttt{\{} \textbf{newline} \textit{statements} \texttt{\}}} \\ \hline \hline

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

6
snippets/alivd.cent Normal file
View File

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

BIN
snippets/alivd.png Normal file

Binary file not shown.

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)
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 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]
DICE(x[I])
DIC(x[I])

View File

@@ -1,2 +1,2 @@
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 y VT FALSITAS
SI x ET y TVNC {
DICE(I)
} ALVID SI x AVT y TVNC {
DICE(II)
} ALVID {
DICE(III)
DIC(I)
} ALIVD SI x AVT y TVNC {
DIC(II)
} ALIVD {
DIC(III)
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

View File

@@ -1,3 +1,3 @@
DESIGNA x VT V
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["novus"] VT I

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 41 KiB

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

View File

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

View File

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

View File

@@ -1,11 +1,11 @@
// Immediately invoked
DICE(INVOCA FVNCTIO (x) VT { REDI (x + I) } (V))
DIC(INVOCA FVNCTIO (x) VT { REDI (x + I) } (V))
// From an array
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
DEFINI apply (f, x) VT { REDI (INVOCA f (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]
PER y IN x FACE {
DICE(y)
PER y IN x FAC {
DIC(y)
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

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

View File

@@ -70,7 +70,7 @@ contexts:
scope: constant.language.centvrion
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
modules:
@@ -78,7 +78,7 @@ contexts:
scope: support.class.module.centvrion
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
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_tests = [
("DICE(\"hello\")", Program([], [ExpressionStatement(BuiltIn("DICE", [String("hello")]))]), ValStr("hello"), "hello\n"),
("DICE(\"world\")", Program([], [ExpressionStatement(BuiltIn("DICE", [String("world")]))]), ValStr("world"), "world\n"),
("DICE(III)", Program([], [ExpressionStatement(BuiltIn("DICE", [Numeral("III")]))]), ValStr("III"), "III\n"),
("DICE(X)", Program([], [ExpressionStatement(BuiltIn("DICE", [Numeral("X")]))]), ValStr("X"), "X\n"),
("DICE(MMXXV)", Program([], [ExpressionStatement(BuiltIn("DICE", [Numeral("MMXXV")]))]), ValStr("MMXXV"), "MMXXV\n"),
("DICE('hello')", Program([], [ExpressionStatement(BuiltIn("DICE", [String("hello")]))]), ValStr("hello"), "hello\n"),
("DICE('world')", Program([], [ExpressionStatement(BuiltIn("DICE", [String("world")]))]), ValStr("world"), "world\n"),
("DICE(\"a\", \"b\")", Program([], [ExpressionStatement(BuiltIn("DICE", [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"),
("DICE(DICE(II))", Program([], [ExpressionStatement(BuiltIn("DICE", [BuiltIn("DICE", [Numeral("II")])]))]), ValStr("II"), "II\nII\n"),
("EVERRO()", Program([], [ExpressionStatement(BuiltIn("EVERRO", []))]), ValNul(), "\033[2J\033[H"),
("DIC(\"hello\")", Program([], [ExpressionStatement(BuiltIn("DIC", [String("hello")]))]), ValStr("hello"), "hello\n"),
("DIC(\"world\")", Program([], [ExpressionStatement(BuiltIn("DIC", [String("world")]))]), ValStr("world"), "world\n"),
("DIC(III)", Program([], [ExpressionStatement(BuiltIn("DIC", [Numeral("III")]))]), ValStr("III"), "III\n"),
("DIC(X)", Program([], [ExpressionStatement(BuiltIn("DIC", [Numeral("X")]))]), ValStr("X"), "X\n"),
("DIC(MMXXV)", Program([], [ExpressionStatement(BuiltIn("DIC", [Numeral("MMXXV")]))]), ValStr("MMXXV"), "MMXXV\n"),
("DIC('hello')", Program([], [ExpressionStatement(BuiltIn("DIC", [String("hello")]))]), ValStr("hello"), "hello\n"),
("DIC('world')", Program([], [ExpressionStatement(BuiltIn("DIC", [String("world")]))]), ValStr("world"), "world\n"),
("DIC(\"a\", \"b\")", Program([], [ExpressionStatement(BuiltIn("DIC", [String("a"), String("b")]))]), ValStr("a b"), "a b\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"),
("DIC(DIC(II))", Program([], [ExpressionStatement(BuiltIn("DIC", [BuiltIn("DIC", [Numeral("II")])]))]), ValStr("II"), "II\nII\n"),
("EVERRE()", Program([], [ExpressionStatement(BuiltIn("EVERRE", []))]), ValNul(), "\033[2J\033[H"),
]
class TestOutput(unittest.TestCase):
@@ -285,7 +285,7 @@ assignment_tests = [
ExpressionStatement(ID("x"))]),
ValInt(6)),
# 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()),
PerStatement(DataRangeArray(Numeral("I"), Numeral("III")), ID("i"),
[Designa(ID("s"), BinOp(ID("s"), ID("i"), "SYMBOL_PLUS"))]),
@@ -332,12 +332,12 @@ destructuring_tests = [
),
# 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([], [
Defini(ID("pair"), [ID("a"), ID("b")], [Redi([ID("a"), ID("b")])]),
DesignaDestructure([ID("x"), ID("y")], Invoca(ID("pair"), [Numeral("V"), Numeral("II")])),
ExpressionStatement(BuiltIn("DICE", [ID("x")])),
ExpressionStatement(BuiltIn("DICE", [ID("y")])),
ExpressionStatement(BuiltIn("DIC", [ID("x")])),
ExpressionStatement(BuiltIn("DIC", [ID("y")])),
]),
ValStr("II"),
"V\nII\n",
@@ -353,41 +353,41 @@ class TestDestructuring(unittest.TestCase):
# --- Control flow ---
control_tests = [
# SI without ALVID — true branch
# SI without ALIVD — true branch
("SI VERITAS TVNC { DESIGNA r VT I }\nr",
Program([], [SiStatement(Bool(True), [Designa(ID("r"), Numeral("I"))], None), ExpressionStatement(ID("r"))]),
ValInt(1)),
# SI without ALVID — false branch
# SI without ALIVD — false branch
("SI FALSITAS TVNC { DESIGNA r VT I }",
Program([], [SiStatement(Bool(False), [Designa(ID("r"), Numeral("I"))], None)]),
ValNul()),
# SI with ALVID — true branch
("SI VERITAS TVNC { DESIGNA r VT I } ALVID { DESIGNA r VT II }\nr",
# SI with ALIVD — true branch
("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"))]),
ValInt(1)),
# SI with ALVID — false branch
("SI FALSITAS TVNC { DESIGNA r VT I } ALVID { DESIGNA r VT II }\nr",
# SI with ALIVD — false branch
("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"))]),
ValInt(2)),
# 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"))]),
ValInt(1)),
# 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"))]),
ValInt(2)),
# 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"))]),
ValInt(1)),
# 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"))]),
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([], [
SiStatement(
BinOp(Numeral("I"), Numeral("II"), "KEYWORD_EST"),
@@ -404,7 +404,7 @@ control_tests = [
),
# 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([], [
Designa(ID("x"), Numeral("I")),
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),
),
# DVM with ERVMPE — loop body prints (testing DICE + ERVMPE together)
("DESIGNA x VT I\nDVM FALSITAS FACE {\nDICE(x)\nERVMPE\n}",
# DVM with ERVMPE — loop body prints (testing DIC + ERVMPE together)
("DESIGNA x VT I\nDVM FALSITAS FAC {\nDIC(x)\nERVMPE\n}",
Program([], [
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"),
# 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([], [
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"),
# 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([], [
Designa(ID("x"), Numeral("I")),
DumStatement(Bool(False), [
@@ -440,20 +440,20 @@ control_tests = [
# AETERNVM with CONTINVA — skip printing III; ERVMPE after V.
# 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 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([], [
Designa(ID("x"), Nullus()),
DumStatement(Bool(False), [
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("III"), "KEYWORD_EST"), [Continva()], None),
ExpressionStatement(BuiltIn("DICE", [ID("x")])),
ExpressionStatement(BuiltIn("DIC", [ID("x")])),
]),
]),
ValNul(), "I\nII\nIV\nV\n"),
# 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([], [
Defini(ID("f"), [], [
Designa(ID("x"), Numeral("I")),
@@ -464,12 +464,12 @@ control_tests = [
ValInt(1),
),
# PER foreach
("PER i IN [I, II, III] FACE { DICE(i) }",
Program([], [PerStatement(DataArray([Numeral("I"), Numeral("II"), Numeral("III")]), ID("i"), [ExpressionStatement(BuiltIn("DICE", [ID("i")]))])]),
("PER i IN [I, II, III] FAC { DIC(i) }",
Program([], [PerStatement(DataArray([Numeral("I"), Numeral("II"), Numeral("III")]), ID("i"), [ExpressionStatement(BuiltIn("DIC", [ID("i")]))])]),
ValStr("III"), "I\nII\nIII\n"),
# DONICVM range loop
("DONICVM i VT I VSQVE V FACE { DICE(i) }",
Program([], [PerStatement(DataRangeArray(Numeral("I"), Numeral("V")), ID("i"), [ExpressionStatement(BuiltIn("DICE", [ID("i")]))])]),
("DONICVM i VT I VSQVE V FAC { DIC(i) }",
Program([], [PerStatement(DataRangeArray(Numeral("I"), Numeral("V")), ID("i"), [ExpressionStatement(BuiltIn("DIC", [ID("i")]))])]),
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)
(
"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([], [
Defini(ID("fib"), [ID("n")], [
SiStatement(
@@ -530,14 +530,14 @@ class TestFunctions(unittest.TestCase):
builtin_tests = [
("AVDI_NVMERVS()", Program([], [ExpressionStatement(BuiltIn("AVDI_NVMERVS", []))]), ValInt(3), "", ["III"]),
("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"]),
("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("salve")', Program([], [ExpressionStatement(BuiltIn("LONGITVDO", [String("salve")]))]), ValInt(5)),
('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\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\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)\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)
("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
@@ -621,9 +621,9 @@ error_tests = [
("INVOCA f ()", CentvrionError), # undefined function
("DESIGNA VT III", SyntaxError), # parse error: missing id after DESIGNA
("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
("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, 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
@@ -646,10 +646,10 @@ error_tests = [
("DESIGNA x VT I\nDESIGNA x[I] VT II", CentvrionError), # index-assign to non-array
("SEMEN(I)", CentvrionError), # requires FORS module
('CVM FORS\nSEMEN("abc")', CentvrionError), # SEMEN requires integer seed
("FORTIS_ELECTIONIS([])", CentvrionError), # FORS required for FORTIS_ELECTIONIS
("CVM FORS\nFORTIS_ELECTIONIS([])", CentvrionError), # FORTIS_ELECTIONIS on empty array
("CVM FORS\nFORTIS_NVMERVS(X, I)", CentvrionError), # FORTIS_NVMERVS a > b
("PER i IN I FACE { DICE(i) }", CentvrionError), # PER over non-array
("FORTVITA_ELECTIO([])", CentvrionError), # FORS required for FORTVITA_ELECTIO
("CVM FORS\nFORTVITA_ELECTIO([])", CentvrionError), # FORTVITA_ELECTIO on empty array
("CVM FORS\nFORTVITVS_NVMERVS(X, I)", CentvrionError), # FORTVITVS_NVMERVS a > b
("PER i IN I FAC { DIC(i) }", CentvrionError), # PER over non-array
("DECIMATIO([I, II, III])", CentvrionError), # FORS required for DECIMATIO
("CVM FORS\nDECIMATIO(I)", CentvrionError), # DECIMATIO requires an 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
("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
("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
("DESIGNA z VT I - I\nNON z", CentvrionError), # NON on zero integer
('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)"),
("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)"),
("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)"),
("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])"),
@@ -857,23 +857,23 @@ class TestMakeString(unittest.TestCase):
)
# --- DICE with non-integer types ---
# --- DIC with non-integer types ---
dice_type_tests = [
("DICE(VERITAS)", Program([], [ExpressionStatement(BuiltIn("DICE", [Bool(True)]))]), ValStr("VERITAS"), "VERITAS\n"),
("DICE(FALSITAS)", Program([], [ExpressionStatement(BuiltIn("DICE", [Bool(False)]))]), ValStr("FALSITAS"), "FALSITAS\n"),
("DICE(NVLLVS)", Program([], [ExpressionStatement(BuiltIn("DICE", [Nullus()]))]), ValStr("NVLLVS"), "NVLLVS\n"),
('DICE([I, II])', Program([], [ExpressionStatement(BuiltIn("DICE", [DataArray([Numeral("I"), Numeral("II")])]))]), ValStr("[I II]"), "[I II]\n"),
('DICE("")', Program([], [ExpressionStatement(BuiltIn("DICE", [String("")]))]), ValStr(""), "\n"),
dic_type_tests = [
("DIC(VERITAS)", Program([], [ExpressionStatement(BuiltIn("DIC", [Bool(True)]))]), ValStr("VERITAS"), "VERITAS\n"),
("DIC(FALSITAS)", Program([], [ExpressionStatement(BuiltIn("DIC", [Bool(False)]))]), ValStr("FALSITAS"), "FALSITAS\n"),
("DIC(NVLLVS)", Program([], [ExpressionStatement(BuiltIn("DIC", [Nullus()]))]), ValStr("NVLLVS"), "NVLLVS\n"),
('DIC([I, II])', Program([], [ExpressionStatement(BuiltIn("DIC", [DataArray([Numeral("I"), Numeral("II")])]))]), ValStr("[I II]"), "[I II]\n"),
('DIC("")', Program([], [ExpressionStatement(BuiltIn("DIC", [String("")]))]), ValStr(""), "\n"),
# 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
('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):
@parameterized.expand(dice_type_tests)
def test_dice_types(self, source, nodes, value, output):
class TestDicTypes(unittest.TestCase):
@parameterized.expand(dic_type_tests)
def test_dic_types(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 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([], [
Designa(ID("x"), Numeral("I")),
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"',
Program([], [ExpressionStatement(String("hello world"))]),
ValStr("hello world")),
# interpolation in DICE output
('DESIGNA name VT "Roma"\nDICE("Salve, {name}!")',
# interpolation in DIC output
('DESIGNA name VT "Roma"\nDIC("Salve, {name}!")',
Program([], [
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"),
]
@@ -1043,7 +1043,7 @@ comparison_tests = [
("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"))]),
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"))]),
ValInt(2)),
# result of comparison is ValBool
@@ -1153,7 +1153,7 @@ function_edge_tests = [
),
# 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([],[
Defini(ID("f"), [], [
Designa(ID("x"), Numeral("I")),
@@ -1165,7 +1165,7 @@ function_edge_tests = [
),
# 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([],[
Defini(ID("f"), [], [
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
(
"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([],[
Defini(ID("f"), [], [
Designa(ID("x"), Numeral("I")),
@@ -1206,15 +1206,15 @@ class TestFunctionEdge(unittest.TestCase):
loop_edge_tests = [
# [III VSQVE III] = [3] — single iteration
("DONICVM i VT III VSQVE III FACE { DICE(i) }",
Program([], [PerStatement(DataRangeArray(Numeral("III"), Numeral("III")), ID("i"), [ExpressionStatement(BuiltIn("DICE", [ID("i")]))])]),
("DONICVM i VT III VSQVE III FAC { DIC(i) }",
Program([], [PerStatement(DataRangeArray(Numeral("III"), Numeral("III")), ID("i"), [ExpressionStatement(BuiltIn("DIC", [ID("i")]))])]),
ValStr("III"), "III\n"),
# empty array — body never runs
("PER i IN [] FACE { DICE(i) }",
Program([], [PerStatement(DataArray([]), ID("i"), [ExpressionStatement(BuiltIn("DICE", [ID("i")]))])]),
("PER i IN [] FAC { DIC(i) }",
Program([], [PerStatement(DataArray([]), ID("i"), [ExpressionStatement(BuiltIn("DIC", [ID("i")]))])]),
ValNul(), ""),
# 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([], [
PerStatement(
DataArray([Numeral("I"), Numeral("II"), Numeral("III")]),
@@ -1225,7 +1225,7 @@ loop_edge_tests = [
]),
ValInt(2), ""),
# 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([], [
Designa(ID("btr"), Numeral("I")),
DumStatement(
@@ -1237,7 +1237,7 @@ loop_edge_tests = [
ValInt(3), ""),
# nested PER: inner always breaks on first element; outer completes both iterations
# 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([], [
Designa(ID("cnt"), Numeral("I")),
PerStatement(
@@ -1251,7 +1251,7 @@ loop_edge_tests = [
ValInt(3), ""),
# PER with CONTINVA: skip odd numbers, sum evens
# [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([], [
Designa(ID("cnt"), Numeral("I")),
PerStatement(
@@ -1264,22 +1264,22 @@ loop_edge_tests = [
]),
ValInt(3), ""),
# 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
("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",
# 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 FAC {\nSI x EST II TVNC { DESIGNA x VT x + I\nCONTINVA }\nDIC(x)\nDESIGNA x VT x + I\n}\nx",
Program([], [
Designa(ID("x"), Numeral("I")),
DumStatement(
BinOp(ID("x"), Numeral("IV"), "KEYWORD_EST"),
[SiStatement(BinOp(ID("x"), Numeral("II"), "KEYWORD_EST"),
[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"))],
),
ExpressionStatement(ID("x")),
]),
ValInt(4), "I\nIII\n"),
# 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([], [
Designa(ID("cnt"), Numeral("I")),
PerStatement(
@@ -1293,7 +1293,7 @@ loop_edge_tests = [
]),
ValInt(3), ""),
# 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([], [
Designa(ID("cnt"), Numeral("I")),
PerStatement(
@@ -1306,7 +1306,7 @@ loop_edge_tests = [
]),
ValInt(4)),
# 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([], [
Designa(ID("x"), Numeral("I")),
DumStatement(Bool(True), [Designa(ID("x"), BinOp(ID("x"), Numeral("I"), "SYMBOL_PLUS"))]),
@@ -1314,15 +1314,15 @@ loop_edge_tests = [
]),
ValInt(1), ""),
# two iterations: [I VSQVE II] = [1, 2]
("DONICVM i VT I VSQVE II FACE { DICE(i) }",
Program([], [PerStatement(DataRangeArray(Numeral("I"), Numeral("II")), ID("i"), [ExpressionStatement(BuiltIn("DICE", [ID("i")]))])]),
("DONICVM i VT I VSQVE II FAC { DIC(i) }",
Program([], [PerStatement(DataRangeArray(Numeral("I"), Numeral("II")), ID("i"), [ExpressionStatement(BuiltIn("DIC", [ID("i")]))])]),
ValStr("II"), "I\nII\n"),
# single iteration: [I VSQVE I] = [1]
("DONICVM i VT I VSQVE I FACE { DICE(i) }",
Program([], [PerStatement(DataRangeArray(Numeral("I"), Numeral("I")), ID("i"), [ExpressionStatement(BuiltIn("DICE", [ID("i")]))])]),
("DONICVM i VT I VSQVE I FAC { DIC(i) }",
Program([], [PerStatement(DataRangeArray(Numeral("I"), Numeral("I")), ID("i"), [ExpressionStatement(BuiltIn("DIC", [ID("i")]))])]),
ValStr("I"), "I\n"),
# empty range: [V VSQVE I] = []
("DESIGNA x VT NVLLVS\nDONICVM i VT V VSQVE I FACE { DESIGNA x VT x + i }\nx",
("DESIGNA x VT NVLLVS\nDONICVM i VT V VSQVE I FAC { DESIGNA x VT x + i }\nx",
Program([], [Designa(ID("x"), Nullus()),
PerStatement(DataRangeArray(Numeral("V"), Numeral("I")), ID("i"),
[Designa(ID("x"), BinOp(ID("x"), ID("i"), "SYMBOL_PLUS"))]),
@@ -1387,16 +1387,16 @@ class TestValues(unittest.TestCase):
magnvm_tests = [
# M+M+M+M = 4000; MAGNVM allows display as "MV_"
("CVM MAGNVM\nDICE(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")]))]),
("CVM MAGNVM\nDIC(M + M + M + M)",
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"),
# I_ = 1000 with MAGNVM (same value as M, but written with thousands operator)
("CVM MAGNVM\nI_",
Program([ModuleCall("MAGNVM")], [ExpressionStatement(Numeral("I_"))]),
ValInt(1000), ""),
# I_ + I_ = 2000; displayed as MM with MAGNVM
("CVM MAGNVM\nDICE(I_ + I_)",
Program([ModuleCall("MAGNVM")], [ExpressionStatement(BuiltIn("DICE", [BinOp(Numeral("I_"), Numeral("I_"), "SYMBOL_PLUS")]))]),
("CVM MAGNVM\nDIC(I_ + I_)",
Program([ModuleCall("MAGNVM")], [ExpressionStatement(BuiltIn("DIC", [BinOp(Numeral("I_"), Numeral("I_"), "SYMBOL_PLUS")]))]),
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"))]),
ValBool(True)),
# 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"))]),
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"))]),
ValInt(2)),
]
@@ -1674,13 +1674,13 @@ class TestStringSlice(unittest.TestCase):
comment_tests = [
# 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
('// 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
('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
('/* 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
("II /* ignored */ + III", Program([], [ExpressionStatement(BinOp(Numeral("II"), Numeral("III"), "SYMBOL_PLUS"))]), ValInt(5)),
# line comment after expression (no output)
@@ -1688,7 +1688,7 @@ comment_tests = [
# division still works (/ token not confused with //)
("X / II", Program([], [ExpressionStatement(BinOp(Numeral("X"), Numeral("II"), "SYMBOL_DIVIDE"))]), ValInt(5)),
# 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
('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"))]),
@@ -1716,13 +1716,13 @@ scope_tests = [
("SI VERITAS TVNC { DESIGNA r VT X }\nr",
Program([], [SiStatement(Bool(True), [Designa(ID("r"), Numeral("X"))], None), ExpressionStatement(ID("r"))]),
ValInt(10)),
# SI: variable assigned in ALVID branch persists in outer scope
("SI FALSITAS TVNC { DESIGNA r VT X } ALVID { DESIGNA r VT V }\nr",
# SI: variable assigned in ALIVD branch persists in outer scope
("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"))]),
ValInt(5)),
# 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
("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([], [
Designa(ID("x"), Numeral("I")),
DumStatement(BinOp(ID("x"), Numeral("V"), "KEYWORD_EST"), [
@@ -1733,7 +1733,7 @@ scope_tests = [
]),
ValInt(5)),
# 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([], [
PerStatement(DataArray([Numeral("I"), Numeral("II"), Numeral("III")]), ID("i"), [Designa(ID("nop"), Numeral("I"))]),
ExpressionStatement(ID("i")),
@@ -1741,7 +1741,7 @@ scope_tests = [
ValInt(3)),
# 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
("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([], [
Designa(ID("cnt"), Numeral("I")),
PerStatement(DataArray([Numeral("I"), Numeral("II"), Numeral("III")]), ID("i"), [
@@ -1753,7 +1753,7 @@ scope_tests = [
ValInt(4)),
# 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
("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([], [
PerStatement(DataArray([Numeral("I"), Numeral("II"), Numeral("III")]), ID("i"), [Designa(ID("i"), Numeral("C"))]),
ExpressionStatement(ID("i")),
@@ -1761,7 +1761,7 @@ scope_tests = [
ValInt(100)),
# DONICVM: counter holds last range value after loop ends
# [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([], [
PerStatement(DataRangeArray(Numeral("I"), Numeral("IV")), ID("i"), [Designa(ID("nop"), Numeral("I"))]),
ExpressionStatement(ID("i")),
@@ -1769,7 +1769,7 @@ scope_tests = [
ValInt(4)),
# DONICVM: reassigning counter inside body doesn't reduce the number of iterations
# range [I VSQVE IV] evaluated once; i reset each time; cnt still increments 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([], [
Designa(ID("cnt"), Numeral("I")),
PerStatement(DataRangeArray(Numeral("I"), Numeral("IV")), ID("i"), [
@@ -1780,7 +1780,7 @@ scope_tests = [
]),
ValInt(5)),
# DONICVM: ERVMPE exits loop early; counter persists at break value
("DONICVM i VT I VSQVE X FACE {\nSI i EST III TVNC { ERVMPE }\n}\ni",
("DONICVM i VT I VSQVE X FAC {\nSI i EST III TVNC { ERVMPE }\n}\ni",
Program([], [
PerStatement(DataRangeArray(Numeral("I"), Numeral("X")), ID("i"), [
SiStatement(BinOp(ID("i"), Numeral("III"), "KEYWORD_EST"), [Erumpe()], None),
@@ -1956,9 +1956,9 @@ fractio_tests = [
ValFrac(Fraction(0))
),
# String concatenation with fraction
("CVM FRACTIO\nDICE(IIIS & \"!\")",
("CVM FRACTIO\nDIC(IIIS & \"!\")",
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"
),
@@ -2216,7 +2216,7 @@ class TestDictBuiltins(unittest.TestCase):
dict_iteration_tests = [
# 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([], [
Designa(ID("r"), String("")),
PerStatement(
@@ -2236,17 +2236,17 @@ class TestDictIteration(unittest.TestCase):
dict_display_tests = [
# DICE on dict
('DICE(TABVLA {"a" VT I})',
Program([], [ExpressionStatement(BuiltIn("DICE", [DataDict([(String("a"), Numeral("I"))])]))]),
# DIC on dict
('DIC(TABVLA {"a" VT I})',
Program([], [ExpressionStatement(BuiltIn("DIC", [DataDict([(String("a"), Numeral("I"))])]))]),
ValStr("{a VT I}"), "{a VT I}\n"),
# DICE on multi-entry dict
('DICE(TABVLA {"a" VT I, "b" VT II})',
Program([], [ExpressionStatement(BuiltIn("DICE", [DataDict([(String("a"), Numeral("I")), (String("b"), Numeral("II"))])]))]),
# DIC on multi-entry dict
('DIC(TABVLA {"a" VT I, "b" VT 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"),
# DICE on empty dict
('DICE(TABVLA {})',
Program([], [ExpressionStatement(BuiltIn("DICE", [DataDict([])]))]),
# DIC on empty dict
('DIC(TABVLA {})',
Program([], [ExpressionStatement(BuiltIn("DIC", [DataDict([])]))]),
ValStr("{}"), "{}\n"),
]
@@ -2348,12 +2348,12 @@ fvnctio_tests = [
]),
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([], [
Designa(ID("f"), Fvnctio([ID("x")], [Redi([ID("x")])])),
ExpressionStatement(BuiltIn("DICE", [ID("f")])),
ExpressionStatement(BuiltIn("DIC", [ID("f")])),
]),
ValStr("FVNCTIO"),
"FVNCTIO\n",
@@ -2531,7 +2531,7 @@ class TestScripta(unittest.TestCase):
with tempfile.NamedTemporaryFile(suffix=".txt", delete=False) as f:
path = f.name
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)
captured = StringIO()
with patch("sys.stdout", captured):
@@ -2547,7 +2547,7 @@ class TestScripta(unittest.TestCase):
with tempfile.NamedTemporaryFile(suffix=".txt", delete=False) as f:
path = f.name
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)
output = self._compile_and_run(program)
self.assertEqual(output, "SALVE MVNDE\n")
@@ -2561,7 +2561,7 @@ class TestScripta(unittest.TestCase):
with tempfile.NamedTemporaryFile(suffix=".txt", delete=False) as f:
path = f.name
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)
captured = StringIO()
with patch("sys.stdout", captured):
@@ -2575,7 +2575,7 @@ class TestScripta(unittest.TestCase):
with tempfile.NamedTemporaryFile(suffix=".txt", delete=False) as f:
path = f.name
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)
output = self._compile_and_run(program)
self.assertEqual(output, "SALVE MVNDE\n")
@@ -2722,7 +2722,7 @@ tempta_tests = [
),
# 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([], [
Designa(ID("r"), Nullus()),
DumStatement(

View File

@@ -8,9 +8,9 @@ VSCode extension for [CENTVRION](https://github.com/NikolajDanger/centvrion) —
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 (`+`, `-`, `*`, `/`)
- **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`)
- **Strings** — single and double quoted, with escape sequences
- **Variables** — lowercase Latin identifiers

View File

@@ -45,7 +45,7 @@
"patterns": [
{
"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",
@@ -65,7 +65,7 @@
"patterns": [
{
"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"
}
]
},