🐐 ORDINA
This commit is contained in:
@@ -1122,6 +1122,17 @@ class BuiltIn(Node):
|
||||
case "EVERRO":
|
||||
print("\033[2J\033[H", end="", flush=True)
|
||||
return vtable, ValNul()
|
||||
case "ORDINA":
|
||||
if not isinstance(params[0], ValList):
|
||||
raise CentvrionError("ORDINA requires an array")
|
||||
items = list(params[0].value())
|
||||
if not items:
|
||||
return vtable, ValList([])
|
||||
all_numeric = all(isinstance(i, (ValInt, ValFrac)) for i in items)
|
||||
all_string = all(isinstance(i, ValStr) for i in items)
|
||||
if not (all_numeric or all_string):
|
||||
raise CentvrionError("ORDINA requires all elements to be numbers or all strings")
|
||||
return vtable, ValList(sorted(items, key=lambda v: v.value()))
|
||||
case "TYPVS":
|
||||
type_map = {
|
||||
ValInt: "NVMERVS", ValStr: "LITTERA", ValBool: "VERAX",
|
||||
|
||||
@@ -251,6 +251,9 @@ def _emit_builtin(node, ctx):
|
||||
case "CLAVES":
|
||||
lines.append(f"CentValue {tmp} = cent_dict_keys({param_vars[0]});")
|
||||
|
||||
case "ORDINA":
|
||||
lines.append(f"CentValue {tmp} = cent_ordina({param_vars[0]});")
|
||||
|
||||
case "EVERRO":
|
||||
lines.append("cent_everro();")
|
||||
lines.append(f"CentValue {tmp} = cent_null();")
|
||||
|
||||
@@ -633,6 +633,36 @@ void cent_semen(CentValue seed) {
|
||||
srand((unsigned)seed.ival);
|
||||
}
|
||||
|
||||
static int _ordina_comparator(const void *a, const void *b) {
|
||||
const CentValue *va = (const CentValue *)a;
|
||||
const CentValue *vb = (const CentValue *)b;
|
||||
if ((va->type == CENT_INT || va->type == CENT_FRAC) &&
|
||||
(vb->type == CENT_INT || vb->type == CENT_FRAC)) {
|
||||
long an, ad, bn, bd;
|
||||
to_frac(*va, &an, &ad);
|
||||
to_frac(*vb, &bn, &bd);
|
||||
long lhs = an * bd;
|
||||
long rhs = bn * ad;
|
||||
return (lhs > rhs) - (lhs < rhs);
|
||||
}
|
||||
if (va->type == CENT_STR && vb->type == CENT_STR)
|
||||
return strcmp(va->sval, vb->sval);
|
||||
cent_type_error("'ORDINA' requires all elements to be the same type");
|
||||
return 0;
|
||||
}
|
||||
|
||||
CentValue cent_ordina(CentValue lst) {
|
||||
if (lst.type != CENT_LIST)
|
||||
cent_type_error("'ORDINA' requires a list");
|
||||
int len = lst.lval.len;
|
||||
CentValue result = cent_list_new(len);
|
||||
for (int i = 0; i < len; i++)
|
||||
cent_list_push(&result, lst.lval.items[i]);
|
||||
if (len > 1)
|
||||
qsort(result.lval.items, len, sizeof(CentValue), _ordina_comparator);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Array helpers */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
@@ -222,6 +222,7 @@ void cent_everro(void); /* EVERRO */
|
||||
CentValue cent_senatus(CentValue *args, int n); /* SENATVS */
|
||||
CentValue cent_typvs(CentValue v); /* TYPVS */
|
||||
void cent_dormi(CentValue n); /* DORMI */
|
||||
CentValue cent_ordina(CentValue lst); /* ORDINA */
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Array helpers */
|
||||
|
||||
@@ -49,6 +49,7 @@ builtin_tokens = [("BUILTIN", i) for i in [
|
||||
"FORTIS_NVMERVS",
|
||||
"FORTIS_ELECTIONIS",
|
||||
"LONGITVDO",
|
||||
"ORDINA",
|
||||
"SEMEN",
|
||||
"SENATVS",
|
||||
"TYPVS"
|
||||
|
||||
Reference in New Issue
Block a user