🐐 LITTERA
This commit is contained in:
@@ -366,6 +366,11 @@ Parses a Roman numeral string and returns its integer value. The argument must b
|
||||
|
||||
Returns the type of `value` as a string: `NVMERVS` (integer), `LITTERA` (string), `VERAX` (boolean), `CATALOGVS` (list), `FRACTIO` (fraction), `TABVLA` (dict), `FVNCTIO` (function), or `NVLLVS` (null).
|
||||
|
||||
### LITTERA
|
||||
`LITTERA(value)`
|
||||
|
||||
Returns `value` formatted as the same display string `DIC` would print. Integers become Roman numerals (zero becomes `NVLLVS`), fractions use the `S`/`:`/`.`/`|` notation, booleans become `VERITAS`/`FALSITAS`, arrays are space-separated in brackets, and dicts use the `{ key VT value, ... }` form. Strings pass through unchanged. Respects `MAGNVM` and `SVBNVLLA` for large and negative numbers. Inverse of `NVMERVS` for integers: `NVMERVS(LITTERA(n)) == n`.
|
||||
|
||||
### DORMI
|
||||
`DORMI(n)`
|
||||
|
||||
|
||||
@@ -1441,6 +1441,10 @@ class BuiltIn(Node):
|
||||
if isinstance(params[0], (ValList, ValStr, ValDict)):
|
||||
return vtable, ValInt(len(params[0].value()))
|
||||
raise CentvrionError("LONGITVDO requires an array, string, or dict")
|
||||
case "LITTERA":
|
||||
if len(params) != 1:
|
||||
raise CentvrionError("LITTERA takes exactly I argument")
|
||||
return vtable, ValStr(make_string(params[0], magnvm, svbnvlla))
|
||||
case "CLAVES":
|
||||
if not isinstance(params[0], ValDict):
|
||||
raise CentvrionError("CLAVES requires a dict")
|
||||
|
||||
@@ -237,6 +237,9 @@ def _emit_builtin(node, ctx):
|
||||
case "LONGITVDO":
|
||||
lines.append(f"CentValue {tmp} = cent_longitudo({param_vars[0]});")
|
||||
|
||||
case "LITTERA":
|
||||
lines.append(f"CentValue {tmp} = cent_littera({param_vars[0]});")
|
||||
|
||||
case "FORTVITVS_NVMERVS":
|
||||
if not ctx.has_module("FORS"):
|
||||
lines.append('cent_runtime_error("FORS module required for FORTVITVS_NVMERVS");')
|
||||
|
||||
@@ -644,6 +644,10 @@ CentValue cent_longitudo(CentValue v) {
|
||||
return cent_null(); /* unreachable; silences warning */
|
||||
}
|
||||
|
||||
CentValue cent_littera(CentValue v) {
|
||||
return cent_str(cent_make_string(v));
|
||||
}
|
||||
|
||||
CentValue cent_typvs(CentValue v) {
|
||||
switch (v.type) {
|
||||
case CENT_INT: return cent_str("NVMERVS");
|
||||
|
||||
@@ -223,6 +223,7 @@ 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_littera(CentValue v); /* LITTERA */
|
||||
CentValue cent_fortuitus_numerus(CentValue lo, CentValue hi); /* FORTVITVS_NVMERVS */
|
||||
CentValue cent_fortuita_electionis(CentValue lst); /* FORTVITA_ELECTIO */
|
||||
CentValue cent_decimatio(CentValue lst); /* DECIMATIO */
|
||||
|
||||
@@ -54,6 +54,7 @@ builtin_tokens = [("BUILTIN", i) for i in [
|
||||
"EVERRE",
|
||||
"FORTVITVS_NVMERVS",
|
||||
"FORTVITA_ELECTIO",
|
||||
"LITTERA",
|
||||
"LONGITVDO",
|
||||
"NVMERVS",
|
||||
"ORDINA",
|
||||
|
||||
3
snippets/littera.cent
Normal file
3
snippets/littera.cent
Normal file
@@ -0,0 +1,3 @@
|
||||
DESIGNA n VT VII
|
||||
DESIGNA s VT LITTERA(n) & " est septem"
|
||||
DIC(s)
|
||||
BIN
snippets/littera.png
Normal file
BIN
snippets/littera.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
@@ -70,7 +70,7 @@ contexts:
|
||||
scope: constant.language.centvrion
|
||||
|
||||
builtins:
|
||||
- match: '\b(ADIVNGE|AVDI_NVMERVS|AVDI|AVSCVLTA|CLAVES|DECIMATIO|DIC|DORMI|EVERRE|FORTVITVS_NVMERVS|FORTVITA_ELECTIO|LEGE|LONGITVDO|NVMERVS|ORDINA|PETE|PETITVR|QVAERE|SCINDE|SCRIBE|SEMEN|SENATVS|SVBSTITVE|TYPVS)\b'
|
||||
- match: '\b(ADIVNGE|AVDI_NVMERVS|AVDI|AVSCVLTA|CLAVES|DECIMATIO|DIC|DORMI|EVERRE|FORTVITVS_NVMERVS|FORTVITA_ELECTIO|LEGE|LITTERA|LONGITVDO|NVMERVS|ORDINA|PETE|PETITVR|QVAERE|SCINDE|SCRIBE|SEMEN|SENATVS|SVBSTITVE|TYPVS)\b'
|
||||
scope: support.function.builtin.centvrion
|
||||
|
||||
modules:
|
||||
|
||||
32
tests.py
32
tests.py
@@ -646,6 +646,38 @@ builtin_tests = [
|
||||
("TYPVS(FVNCTIO () VT { REDI(I) })", Program([], [ExpressionStatement(BuiltIn("TYPVS", [Fvnctio([], [Redi([Numeral("I")])])]))]), ValStr("FVNCTIO")),
|
||||
# TYPVS: null
|
||||
("TYPVS(NVLLVS)", Program([], [ExpressionStatement(BuiltIn("TYPVS", [Nullus()]))]), ValStr("NVLLVS")),
|
||||
# LITTERA: integer → Roman numeral
|
||||
("LITTERA(V)", Program([], [ExpressionStatement(BuiltIn("LITTERA", [Numeral("V")]))]), ValStr("V")),
|
||||
# LITTERA: larger integer
|
||||
("LITTERA(MCMLXXXIV)", Program([], [ExpressionStatement(BuiltIn("LITTERA", [Numeral("MCMLXXXIV")]))]), ValStr("MCMLXXXIV")),
|
||||
# LITTERA: zero → NVLLVS
|
||||
("LITTERA(I - I)", Program([], [ExpressionStatement(BuiltIn("LITTERA", [BinOp(Numeral("I"), Numeral("I"), "SYMBOL_MINUS")]))]), ValStr("NVLLVS")),
|
||||
# LITTERA: string passthrough
|
||||
('LITTERA("salve")', Program([], [ExpressionStatement(BuiltIn("LITTERA", [String("salve")]))]), ValStr("salve")),
|
||||
# LITTERA: empty string
|
||||
('LITTERA("")', Program([], [ExpressionStatement(BuiltIn("LITTERA", [String("")]))]), ValStr("")),
|
||||
# LITTERA: VERITAS
|
||||
("LITTERA(VERITAS)", Program([], [ExpressionStatement(BuiltIn("LITTERA", [Bool(True)]))]), ValStr("VERITAS")),
|
||||
# LITTERA: FALSITAS
|
||||
("LITTERA(FALSITAS)", Program([], [ExpressionStatement(BuiltIn("LITTERA", [Bool(False)]))]), ValStr("FALSITAS")),
|
||||
# LITTERA: NVLLVS
|
||||
("LITTERA(NVLLVS)", Program([], [ExpressionStatement(BuiltIn("LITTERA", [Nullus()]))]), ValStr("NVLLVS")),
|
||||
# LITTERA: array of integers
|
||||
("LITTERA([I, II, III])", Program([], [ExpressionStatement(BuiltIn("LITTERA", [DataArray([Numeral("I"), Numeral("II"), Numeral("III")])]))]), ValStr("[I II III]")),
|
||||
# LITTERA: empty array
|
||||
("LITTERA([])", Program([], [ExpressionStatement(BuiltIn("LITTERA", [DataArray([])]))]), ValStr("[]")),
|
||||
# LITTERA: dict with string keys (make_string emits bare keys, not quoted — matches DIC's output)
|
||||
('LITTERA(TABVLA {"a" VT I})', Program([], [ExpressionStatement(BuiltIn("LITTERA", [DataDict([(String("a"), Numeral("I"))])]))]), ValStr('{a VT I}')),
|
||||
# LITTERA: fraction (requires FRACTIO module)
|
||||
("CVM FRACTIO\nLITTERA(S)", Program([ModuleCall("FRACTIO")], [ExpressionStatement(BuiltIn("LITTERA", [Fractio("S")]))]), ValStr("S")),
|
||||
# LITTERA: negative integer
|
||||
("CVM SVBNVLLA\nLITTERA(-III)", Program([ModuleCall("SVBNVLLA")], [ExpressionStatement(BuiltIn("LITTERA", [UnaryMinus(Numeral("III"))]))]), ValStr("-III")),
|
||||
# LITTERA: round-trips through NVMERVS
|
||||
('NVMERVS(LITTERA(VII))', Program([], [ExpressionStatement(BuiltIn("NVMERVS", [BuiltIn("LITTERA", [Numeral("VII")])]))]), ValInt(7)),
|
||||
# LITTERA: concatenated with a string via &
|
||||
('LITTERA(V) & " est quinque"', Program([], [ExpressionStatement(BinOp(BuiltIn("LITTERA", [Numeral("V")]), String(" est quinque"), "SYMBOL_AMPERSAND"))]), ValStr("V est quinque")),
|
||||
# LITTERA: via variable
|
||||
("DESIGNA x VT IX\nLITTERA(x)", Program([], [Designa(ID("x"), Numeral("IX")), ExpressionStatement(BuiltIn("LITTERA", [ID("x")]))]), ValStr("IX")),
|
||||
# QVAERE: basic literal match
|
||||
('QVAERE("ab", "abcabc")', Program([], [ExpressionStatement(BuiltIn("QVAERE", [String("ab"), String("abcabc")]))]), ValList([ValStr("ab"), ValStr("ab")])),
|
||||
# QVAERE: no match → empty list
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
"FORTVITA_ELECTIO": { "prefix": "FORTVITA_ELECTIO", "body": "FORTVITA_ELECTIO", "description": "pick a random element from an array (FORS module)" },
|
||||
"FORTVITVS_NVMERVS": { "prefix": "FORTVITVS_NVMERVS", "body": "FORTVITVS_NVMERVS", "description": "random integer in a range (FORS module)" },
|
||||
"LEGE": { "prefix": "LEGE", "body": "LEGE", "description": "read file contents (SCRIPTA module)" },
|
||||
"LITTERA": { "prefix": "LITTERA", "body": "LITTERA", "description": "coerce any value to its display string" },
|
||||
"LONGITVDO": { "prefix": "LONGITVDO", "body": "LONGITVDO", "description": "length of array, string, or dict" },
|
||||
"NVMERVS": { "prefix": "NVMERVS", "body": "NVMERVS", "description": "parse a Roman numeral string to an integer" },
|
||||
"ORDINA": { "prefix": "ORDINA", "body": "ORDINA", "description": "sort an array in ascending order" },
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
"patterns": [
|
||||
{
|
||||
"name": "support.function.builtin.cent",
|
||||
"match": "\\b(ADIVNGE|AVDI_NVMERVS|AVDI|AVSCVLTA|CLAVES|DECIMATIO|DIC|DORMI|EVERRE|FORTVITVS_NVMERVS|FORTVITA_ELECTIO|LEGE|LONGITVDO|NVMERVS|ORDINA|PETE|PETITVR|QVAERE|SCINDE|SCRIBE|SEMEN|SENATVS|SVBSTITVE|TYPVS)\\b"
|
||||
"match": "\\b(ADIVNGE|AVDI_NVMERVS|AVDI|AVSCVLTA|CLAVES|DECIMATIO|DIC|DORMI|EVERRE|FORTVITVS_NVMERVS|FORTVITA_ELECTIO|LEGE|LITTERA|LONGITVDO|NVMERVS|ORDINA|PETE|PETITVR|QVAERE|SCINDE|SCRIBE|SEMEN|SENATVS|SVBSTITVE|TYPVS)\\b"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user