🐐 Array functions
This commit is contained in:
15
README.md
15
README.md
@@ -361,6 +361,21 @@ Returns the keys of `dict` as an array.
|
|||||||
|
|
||||||
Sorts an array in ascending order. Returns a new sorted array. All elements must be the same type — integers, fractions, or strings. Integers and fractions sort numerically; strings sort lexicographically.
|
Sorts an array in ascending order. Returns a new sorted array. All elements must be the same type — integers, fractions, or strings. Integers and fractions sort numerically; strings sort lexicographically.
|
||||||
|
|
||||||
|
### ADDE
|
||||||
|
`ADDE(array, value)`
|
||||||
|
|
||||||
|
Returns a new array with `value` appended at the end. The original array is unchanged.
|
||||||
|
|
||||||
|
### TOLLE
|
||||||
|
`TOLLE(array, idx)`
|
||||||
|
|
||||||
|
Returns a new array with the element at 1-based position `idx` removed. The index must be an integer in the range `[I, LONGITVDO(array)]`; out-of-range indices raise an error.
|
||||||
|
|
||||||
|
### INSERE
|
||||||
|
`INSERE(array, idx, value)`
|
||||||
|
|
||||||
|
Returns a new array with `value` inserted at 1-based position `idx`, shifting later elements one position to the right. The index must be an integer in the range `[I, LONGITVDO(array) + I]`; passing `LONGITVDO(array) + I` is equivalent to `ADDE`.
|
||||||
|
|
||||||
### SENATVS
|
### SENATVS
|
||||||
`SENATVS(bool, ...)` or `SENATVS([bool])`
|
`SENATVS(bool, ...)` or `SENATVS([bool])`
|
||||||
|
|
||||||
|
|||||||
@@ -1496,6 +1496,32 @@ class BuiltIn(Node):
|
|||||||
case "EVERRE":
|
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 "ADDE":
|
||||||
|
if len(params) != 2:
|
||||||
|
raise CentvrionError("ADDE takes exactly II arguments")
|
||||||
|
if not isinstance(params[0], ValList):
|
||||||
|
raise CentvrionError("ADDE requires an array")
|
||||||
|
return vtable, ValList(list(params[0].value()) + [params[1]])
|
||||||
|
case "TOLLE":
|
||||||
|
if len(params) != 2:
|
||||||
|
raise CentvrionError("TOLLE takes exactly II arguments")
|
||||||
|
if not isinstance(params[0], ValList):
|
||||||
|
raise CentvrionError("TOLLE requires an array")
|
||||||
|
items = list(params[0].value())
|
||||||
|
idx = _to_index_int(params[1])
|
||||||
|
if idx < 1 or idx > len(items):
|
||||||
|
raise CentvrionError(f"Index {idx} out of range for array of length {len(items)}")
|
||||||
|
return vtable, ValList(items[:idx - 1] + items[idx:])
|
||||||
|
case "INSERE":
|
||||||
|
if len(params) != 3:
|
||||||
|
raise CentvrionError("INSERE takes exactly III arguments")
|
||||||
|
if not isinstance(params[0], ValList):
|
||||||
|
raise CentvrionError("INSERE requires an array")
|
||||||
|
items = list(params[0].value())
|
||||||
|
idx = _to_index_int(params[1])
|
||||||
|
if idx < 1 or idx > len(items) + 1:
|
||||||
|
raise CentvrionError(f"Index {idx} out of range for array of length {len(items)}")
|
||||||
|
return vtable, ValList(items[:idx - 1] + [params[2]] + items[idx - 1:])
|
||||||
case "ORDINA":
|
case "ORDINA":
|
||||||
if not isinstance(params[0], ValList):
|
if not isinstance(params[0], ValList):
|
||||||
raise CentvrionError("ORDINA requires an array")
|
raise CentvrionError("ORDINA requires an array")
|
||||||
|
|||||||
@@ -313,6 +313,15 @@ 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 "ADDE":
|
||||||
|
lines.append(f"CentValue {tmp} = cent_adde({param_vars[0]}, {param_vars[1]});")
|
||||||
|
|
||||||
|
case "TOLLE":
|
||||||
|
lines.append(f"CentValue {tmp} = cent_tolle({param_vars[0]}, {param_vars[1]});")
|
||||||
|
|
||||||
|
case "INSERE":
|
||||||
|
lines.append(f"CentValue {tmp} = cent_insere({param_vars[0]}, {param_vars[1]}, {param_vars[2]});")
|
||||||
|
|
||||||
case "EVERRE":
|
case "EVERRE":
|
||||||
lines.append("cent_everre();")
|
lines.append("cent_everre();")
|
||||||
lines.append(f"CentValue {tmp} = cent_null();")
|
lines.append(f"CentValue {tmp} = cent_null();")
|
||||||
|
|||||||
@@ -848,6 +848,56 @@ CentValue cent_ordina(CentValue lst) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static long _index_arg(CentValue idx, const char *name) {
|
||||||
|
if (idx.type == CENT_INT)
|
||||||
|
return idx.ival;
|
||||||
|
if (idx.type == CENT_FRAC && idx.fval.den == 1)
|
||||||
|
return idx.fval.num;
|
||||||
|
cent_type_error(name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CentValue cent_adde(CentValue lst, CentValue v) {
|
||||||
|
if (lst.type != CENT_LIST)
|
||||||
|
cent_type_error("'ADDE' requires a list");
|
||||||
|
int len = lst.lval.len;
|
||||||
|
CentValue result = cent_list_new(len + 1);
|
||||||
|
for (int i = 0; i < len; i++)
|
||||||
|
cent_list_push(&result, lst.lval.items[i]);
|
||||||
|
cent_list_push(&result, v);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
CentValue cent_tolle(CentValue lst, CentValue idx) {
|
||||||
|
if (lst.type != CENT_LIST)
|
||||||
|
cent_type_error("'TOLLE' requires a list");
|
||||||
|
long i = _index_arg(idx, "'TOLLE' index must be an integer");
|
||||||
|
int len = lst.lval.len;
|
||||||
|
if (i < 1 || i > len)
|
||||||
|
cent_runtime_error("'TOLLE' index out of range");
|
||||||
|
CentValue result = cent_list_new(len - 1);
|
||||||
|
for (int j = 0; j < len; j++)
|
||||||
|
if (j != i - 1)
|
||||||
|
cent_list_push(&result, lst.lval.items[j]);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
CentValue cent_insere(CentValue lst, CentValue idx, CentValue v) {
|
||||||
|
if (lst.type != CENT_LIST)
|
||||||
|
cent_type_error("'INSERE' requires a list");
|
||||||
|
long i = _index_arg(idx, "'INSERE' index must be an integer");
|
||||||
|
int len = lst.lval.len;
|
||||||
|
if (i < 1 || i > len + 1)
|
||||||
|
cent_runtime_error("'INSERE' index out of range");
|
||||||
|
CentValue result = cent_list_new(len + 1);
|
||||||
|
for (int j = 0; j < i - 1; j++)
|
||||||
|
cent_list_push(&result, lst.lval.items[j]);
|
||||||
|
cent_list_push(&result, v);
|
||||||
|
for (int j = i - 1; j < len; j++)
|
||||||
|
cent_list_push(&result, lst.lval.items[j]);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* Array helpers */
|
/* Array helpers */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
|
|||||||
@@ -239,6 +239,9 @@ 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 */
|
||||||
CentValue cent_ordina(CentValue lst); /* ORDINA */
|
CentValue cent_ordina(CentValue lst); /* ORDINA */
|
||||||
|
CentValue cent_adde(CentValue lst, CentValue v); /* ADDE */
|
||||||
|
CentValue cent_tolle(CentValue lst, CentValue idx); /* TOLLE */
|
||||||
|
CentValue cent_insere(CentValue lst, CentValue idx, CentValue v); /* INSERE */
|
||||||
CentValue cent_lege(CentValue path); /* LEGE */
|
CentValue cent_lege(CentValue path); /* LEGE */
|
||||||
void cent_scribe(CentValue path, CentValue content); /* SCRIBE */
|
void cent_scribe(CentValue path, CentValue content); /* SCRIBE */
|
||||||
void cent_adivnge(CentValue path, CentValue content); /* ADIVNGE */
|
void cent_adivnge(CentValue path, CentValue content); /* ADIVNGE */
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ keyword_tokens = [("KEYWORD_"+i, i) for i in [
|
|||||||
]]
|
]]
|
||||||
|
|
||||||
builtin_tokens = [("BUILTIN", i) for i in [
|
builtin_tokens = [("BUILTIN", i) for i in [
|
||||||
|
"ADDE",
|
||||||
"AVDI_NVMERVS",
|
"AVDI_NVMERVS",
|
||||||
"AVDI",
|
"AVDI",
|
||||||
"CLAVES",
|
"CLAVES",
|
||||||
@@ -55,6 +56,7 @@ builtin_tokens = [("BUILTIN", i) for i in [
|
|||||||
"EVERRE",
|
"EVERRE",
|
||||||
"FORTVITVS_NVMERVS",
|
"FORTVITVS_NVMERVS",
|
||||||
"FORTVITA_ELECTIO",
|
"FORTVITA_ELECTIO",
|
||||||
|
"INSERE",
|
||||||
"LITTERA",
|
"LITTERA",
|
||||||
"LONGITVDO",
|
"LONGITVDO",
|
||||||
"MAIVSCVLA",
|
"MAIVSCVLA",
|
||||||
@@ -63,6 +65,7 @@ builtin_tokens = [("BUILTIN", i) for i in [
|
|||||||
"ORDINA",
|
"ORDINA",
|
||||||
"SEMEN",
|
"SEMEN",
|
||||||
"SENATVS",
|
"SENATVS",
|
||||||
|
"TOLLE",
|
||||||
"TYPVS",
|
"TYPVS",
|
||||||
"LEGE",
|
"LEGE",
|
||||||
"SCRIBE",
|
"SCRIBE",
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ contexts:
|
|||||||
scope: constant.language.centvrion
|
scope: constant.language.centvrion
|
||||||
|
|
||||||
builtins:
|
builtins:
|
||||||
- match: '\b(ADIVNGE|AVDI_NVMERVS|AVDI|AVSCVLTA|CLAVES|DECIMATIO|DIC|DORMI|EVERRE|FORTVITVS_NVMERVS|FORTVITA_ELECTIO|LEGE|LITTERA|LONGITVDO|MAIVSCVLA|MINVSCVLA|NVMERVS|ORDINA|PETE|PETITVR|QVAERE|SCINDE|SCRIBE|SEMEN|SENATVS|SVBSTITVE|TYPVS)\b'
|
- match: '\b(ADDE|ADIVNGE|AVDI_NVMERVS|AVDI|AVSCVLTA|CLAVES|DECIMATIO|DIC|DORMI|EVERRE|FORTVITVS_NVMERVS|FORTVITA_ELECTIO|INSERE|LEGE|LITTERA|LONGITVDO|MAIVSCVLA|MINVSCVLA|NVMERVS|ORDINA|PETE|PETITVR|QVAERE|SCINDE|SCRIBE|SEMEN|SENATVS|SVBSTITVE|TOLLE|TYPVS)\b'
|
||||||
scope: support.function.builtin.centvrion
|
scope: support.function.builtin.centvrion
|
||||||
|
|
||||||
modules:
|
modules:
|
||||||
|
|||||||
@@ -76,6 +76,30 @@ builtin_tests = [
|
|||||||
("CVM FRACTIO\nORDINA([III, S, II])", Program([ModuleCall("FRACTIO")], [ExpressionStatement(BuiltIn("ORDINA", [DataArray([Numeral("III"), Fractio("S"), Numeral("II")])]))]), ValList([ValFrac(Fraction(1, 2)), ValInt(2), ValInt(3)])),
|
("CVM FRACTIO\nORDINA([III, S, II])", Program([ModuleCall("FRACTIO")], [ExpressionStatement(BuiltIn("ORDINA", [DataArray([Numeral("III"), Fractio("S"), Numeral("II")])]))]), ValList([ValFrac(Fraction(1, 2)), ValInt(2), ValInt(3)])),
|
||||||
# ORDINA: array passed via variable
|
# ORDINA: array passed via variable
|
||||||
("DESIGNA x VT [III, I, II]\nORDINA(x)", Program([], [Designa(ID("x"), DataArray([Numeral("III"), Numeral("I"), Numeral("II")])), ExpressionStatement(BuiltIn("ORDINA", [ID("x")]))]), ValList([ValInt(1), ValInt(2), ValInt(3)])),
|
("DESIGNA x VT [III, I, II]\nORDINA(x)", Program([], [Designa(ID("x"), DataArray([Numeral("III"), Numeral("I"), Numeral("II")])), ExpressionStatement(BuiltIn("ORDINA", [ID("x")]))]), ValList([ValInt(1), ValInt(2), ValInt(3)])),
|
||||||
|
# ADDE: append to non-empty
|
||||||
|
("ADDE([I, II], III)", Program([], [ExpressionStatement(BuiltIn("ADDE", [DataArray([Numeral("I"), Numeral("II")]), Numeral("III")]))]), ValList([ValInt(1), ValInt(2), ValInt(3)])),
|
||||||
|
# ADDE: append to empty
|
||||||
|
("ADDE([], V)", Program([], [ExpressionStatement(BuiltIn("ADDE", [DataArray([]), Numeral("V")]))]), ValList([ValInt(5)])),
|
||||||
|
# ADDE: heterogeneous types are allowed
|
||||||
|
('ADDE([I, II], "x")', Program([], [ExpressionStatement(BuiltIn("ADDE", [DataArray([Numeral("I"), Numeral("II")]), String("x")]))]), ValList([ValInt(1), ValInt(2), ValStr("x")])),
|
||||||
|
# ADDE: print form to confirm output rendering
|
||||||
|
("DIC(ADDE([I, II], III))", Program([], [ExpressionStatement(BuiltIn("DIC", [BuiltIn("ADDE", [DataArray([Numeral("I"), Numeral("II")]), Numeral("III")])]))]), ValStr("[I II III]"), "[I II III]\n"),
|
||||||
|
# TOLLE: remove middle element
|
||||||
|
("TOLLE([I, II, III], II)", Program([], [ExpressionStatement(BuiltIn("TOLLE", [DataArray([Numeral("I"), Numeral("II"), Numeral("III")]), Numeral("II")]))]), ValList([ValInt(1), ValInt(3)])),
|
||||||
|
# TOLLE: remove first element
|
||||||
|
("TOLLE([I, II, III], I)", Program([], [ExpressionStatement(BuiltIn("TOLLE", [DataArray([Numeral("I"), Numeral("II"), Numeral("III")]), Numeral("I")]))]), ValList([ValInt(2), ValInt(3)])),
|
||||||
|
# TOLLE: remove last element
|
||||||
|
("TOLLE([I, II, III], III)", Program([], [ExpressionStatement(BuiltIn("TOLLE", [DataArray([Numeral("I"), Numeral("II"), Numeral("III")]), Numeral("III")]))]), ValList([ValInt(1), ValInt(2)])),
|
||||||
|
# TOLLE: single-element array → empty
|
||||||
|
("TOLLE([V], I)", Program([], [ExpressionStatement(BuiltIn("TOLLE", [DataArray([Numeral("V")]), Numeral("I")]))]), ValList([])),
|
||||||
|
# INSERE: insert into middle
|
||||||
|
("INSERE([I, III], II, II)", Program([], [ExpressionStatement(BuiltIn("INSERE", [DataArray([Numeral("I"), Numeral("III")]), Numeral("II"), Numeral("II")]))]), ValList([ValInt(1), ValInt(2), ValInt(3)])),
|
||||||
|
# INSERE: insert at front
|
||||||
|
("INSERE([II, III], I, I)", Program([], [ExpressionStatement(BuiltIn("INSERE", [DataArray([Numeral("II"), Numeral("III")]), Numeral("I"), Numeral("I")]))]), ValList([ValInt(1), ValInt(2), ValInt(3)])),
|
||||||
|
# INSERE: insert at len+1 (== append)
|
||||||
|
("INSERE([I, II], III, III)", Program([], [ExpressionStatement(BuiltIn("INSERE", [DataArray([Numeral("I"), Numeral("II")]), Numeral("III"), Numeral("III")]))]), ValList([ValInt(1), ValInt(2), ValInt(3)])),
|
||||||
|
# INSERE: into empty array at idx 1
|
||||||
|
("INSERE([], I, V)", Program([], [ExpressionStatement(BuiltIn("INSERE", [DataArray([]), Numeral("I"), Numeral("V")]))]), ValList([ValInt(5)])),
|
||||||
# TYPVS: integer
|
# TYPVS: integer
|
||||||
("TYPVS(V)", Program([], [ExpressionStatement(BuiltIn("TYPVS", [Numeral("V")]))]), ValStr("NVMERVS")),
|
("TYPVS(V)", Program([], [ExpressionStatement(BuiltIn("TYPVS", [Numeral("V")]))]), ValStr("NVMERVS")),
|
||||||
# TYPVS: string
|
# TYPVS: string
|
||||||
|
|||||||
@@ -65,7 +65,7 @@
|
|||||||
"patterns": [
|
"patterns": [
|
||||||
{
|
{
|
||||||
"name": "support.function.builtin.cent",
|
"name": "support.function.builtin.cent",
|
||||||
"match": "\\b(ADIVNGE|AVDI_NVMERVS|AVDI|AVSCVLTA|CLAVES|DECIMATIO|DIC|DORMI|EVERRE|FORTVITVS_NVMERVS|FORTVITA_ELECTIO|LEGE|LITTERA|LONGITVDO|MAIVSCVLA|MINVSCVLA|NVMERVS|ORDINA|PETE|PETITVR|QVAERE|SCINDE|SCRIBE|SEMEN|SENATVS|SVBSTITVE|TYPVS)\\b"
|
"match": "\\b(ADDE|ADIVNGE|AVDI_NVMERVS|AVDI|AVSCVLTA|CLAVES|DECIMATIO|DIC|DORMI|EVERRE|FORTVITVS_NVMERVS|FORTVITA_ELECTIO|INSERE|LEGE|LITTERA|LONGITVDO|MAIVSCVLA|MINVSCVLA|NVMERVS|ORDINA|PETE|PETITVR|QVAERE|SCINDE|SCRIBE|SEMEN|SENATVS|SVBSTITVE|TOLLE|TYPVS)\\b"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user