🐐 MVTA, CRIBRA, CONFLA
This commit is contained in:
@@ -1580,6 +1580,51 @@ class BuiltIn(Node):
|
||||
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 "MVTA":
|
||||
if len(params) != 2:
|
||||
raise CentvrionError("MVTA takes II arguments")
|
||||
if not isinstance(params[0], ValList):
|
||||
raise CentvrionError("MVTA requires an array")
|
||||
fn = params[1]
|
||||
if not isinstance(fn, ValFunc):
|
||||
raise CentvrionError("MVTA requires a function")
|
||||
if len(fn.params) != 1:
|
||||
raise CentvrionError("MVTA function must take I argument")
|
||||
out = [_call_func(fn, [item], vtable, "MVTA function")
|
||||
for item in params[0].value()]
|
||||
return vtable, ValList(out)
|
||||
case "CRIBRA":
|
||||
if len(params) != 2:
|
||||
raise CentvrionError("CRIBRA takes II arguments")
|
||||
if not isinstance(params[0], ValList):
|
||||
raise CentvrionError("CRIBRA requires an array")
|
||||
fn = params[1]
|
||||
if not isinstance(fn, ValFunc):
|
||||
raise CentvrionError("CRIBRA requires a function")
|
||||
if len(fn.params) != 1:
|
||||
raise CentvrionError("CRIBRA predicate must take I argument")
|
||||
out = []
|
||||
for item in params[0].value():
|
||||
r = _call_func(fn, [item], vtable, "CRIBRA predicate")
|
||||
if not isinstance(r, ValBool):
|
||||
raise CentvrionError("CRIBRA predicate must return VERAX")
|
||||
if r.value():
|
||||
out.append(item)
|
||||
return vtable, ValList(out)
|
||||
case "CONFLA":
|
||||
if len(params) != 3:
|
||||
raise CentvrionError("CONFLA takes III arguments")
|
||||
if not isinstance(params[0], ValList):
|
||||
raise CentvrionError("CONFLA requires an array")
|
||||
fn = params[2]
|
||||
if not isinstance(fn, ValFunc):
|
||||
raise CentvrionError("CONFLA requires a function")
|
||||
if len(fn.params) != 2:
|
||||
raise CentvrionError("CONFLA function must take II arguments")
|
||||
acc = params[1]
|
||||
for item in params[0].value():
|
||||
acc = _call_func(fn, [acc, item], vtable, "CONFLA function")
|
||||
return vtable, acc
|
||||
case "TYPVS":
|
||||
type_map = {
|
||||
ValInt: "NVMERVS", ValStr: "LITTERA", ValBool: "VERAX",
|
||||
|
||||
@@ -320,6 +320,27 @@ def _emit_builtin(node, ctx):
|
||||
else:
|
||||
raise CentvrionError("ORDINA takes 1 or 2 arguments")
|
||||
|
||||
case "MVTA":
|
||||
if len(param_vars) != 2:
|
||||
raise CentvrionError("MVTA takes II arguments")
|
||||
lines.append(
|
||||
f"CentValue {tmp} = cent_mvta({param_vars[0]}, {param_vars[1]}, _scope);"
|
||||
)
|
||||
|
||||
case "CRIBRA":
|
||||
if len(param_vars) != 2:
|
||||
raise CentvrionError("CRIBRA takes II arguments")
|
||||
lines.append(
|
||||
f"CentValue {tmp} = cent_cribra({param_vars[0]}, {param_vars[1]}, _scope);"
|
||||
)
|
||||
|
||||
case "CONFLA":
|
||||
if len(param_vars) != 3:
|
||||
raise CentvrionError("CONFLA takes III arguments")
|
||||
lines.append(
|
||||
f"CentValue {tmp} = cent_confla({param_vars[0]}, {param_vars[1]}, {param_vars[2]}, _scope);"
|
||||
)
|
||||
|
||||
case "ADDE":
|
||||
lines.append(f"CentValue {tmp} = cent_adde({param_vars[0]}, {param_vars[1]});")
|
||||
|
||||
|
||||
@@ -897,6 +897,62 @@ CentValue cent_ordina_cmp(CentValue lst, CentValue cmp, CentScope scope) {
|
||||
return result;
|
||||
}
|
||||
|
||||
CentValue cent_mvta(CentValue lst, CentValue fn, CentScope scope) {
|
||||
if (lst.type != CENT_LIST)
|
||||
cent_type_error("'MVTA' requires an array");
|
||||
if (fn.type != CENT_FUNC)
|
||||
cent_type_error("'MVTA' requires a function");
|
||||
if (fn.fnval.param_count != 1)
|
||||
cent_runtime_error("'MVTA' function must take I argument");
|
||||
int len = lst.lval.len;
|
||||
CentValue result = cent_list_new(len);
|
||||
for (int i = 0; i < len; i++) {
|
||||
CentScope s = cent_scope_copy(&scope);
|
||||
cent_scope_set(&s, fn.fnval.param_names[0], lst.lval.items[i]);
|
||||
cent_list_push(&result, fn.fnval.fn(s));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
CentValue cent_cribra(CentValue lst, CentValue fn, CentScope scope) {
|
||||
if (lst.type != CENT_LIST)
|
||||
cent_type_error("'CRIBRA' requires an array");
|
||||
if (fn.type != CENT_FUNC)
|
||||
cent_type_error("'CRIBRA' requires a function");
|
||||
if (fn.fnval.param_count != 1)
|
||||
cent_runtime_error("'CRIBRA' predicate must take I argument");
|
||||
int len = lst.lval.len;
|
||||
CentValue result = cent_list_new(len);
|
||||
for (int i = 0; i < len; i++) {
|
||||
CentScope s = cent_scope_copy(&scope);
|
||||
cent_scope_set(&s, fn.fnval.param_names[0], lst.lval.items[i]);
|
||||
CentValue r = fn.fnval.fn(s);
|
||||
if (r.type != CENT_BOOL)
|
||||
cent_type_error("'CRIBRA' predicate must return VERAX");
|
||||
if (r.bval)
|
||||
cent_list_push(&result, lst.lval.items[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
CentValue cent_confla(CentValue lst, CentValue init, CentValue fn, CentScope scope) {
|
||||
if (lst.type != CENT_LIST)
|
||||
cent_type_error("'CONFLA' requires an array");
|
||||
if (fn.type != CENT_FUNC)
|
||||
cent_type_error("'CONFLA' requires a function");
|
||||
if (fn.fnval.param_count != 2)
|
||||
cent_runtime_error("'CONFLA' function must take II arguments");
|
||||
CentValue acc = init;
|
||||
int len = lst.lval.len;
|
||||
for (int i = 0; i < len; i++) {
|
||||
CentScope s = cent_scope_copy(&scope);
|
||||
cent_scope_set(&s, fn.fnval.param_names[0], acc);
|
||||
cent_scope_set(&s, fn.fnval.param_names[1], lst.lval.items[i]);
|
||||
acc = fn.fnval.fn(s);
|
||||
}
|
||||
return acc;
|
||||
}
|
||||
|
||||
static long _index_arg(CentValue idx, const char *name) {
|
||||
if (idx.type == CENT_INT)
|
||||
return idx.ival;
|
||||
|
||||
@@ -240,6 +240,9 @@ CentValue cent_typvs(CentValue v); /* TYPVS */
|
||||
void cent_dormi(CentValue n); /* DORMI */
|
||||
CentValue cent_ordina(CentValue lst); /* ORDINA */
|
||||
CentValue cent_ordina_cmp(CentValue lst, CentValue cmp, CentScope scope); /* ORDINA w/ comparator */
|
||||
CentValue cent_mvta(CentValue lst, CentValue fn, CentScope scope); /* MVTA */
|
||||
CentValue cent_cribra(CentValue lst, CentValue fn, CentScope scope); /* CRIBRA */
|
||||
CentValue cent_confla(CentValue lst, CentValue init, CentValue fn, CentScope scope); /* CONFLA */
|
||||
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 */
|
||||
|
||||
@@ -50,6 +50,8 @@ builtin_tokens = [("BUILTIN", i) for i in [
|
||||
"AVDI_NVMERVS",
|
||||
"AVDI",
|
||||
"CLAVES",
|
||||
"CONFLA",
|
||||
"CRIBRA",
|
||||
"DECIMATIO",
|
||||
"DIC",
|
||||
"DORMI",
|
||||
@@ -62,6 +64,7 @@ builtin_tokens = [("BUILTIN", i) for i in [
|
||||
"LONGITVDO",
|
||||
"MAIVSCVLA",
|
||||
"MINVSCVLA",
|
||||
"MVTA",
|
||||
"NECTE",
|
||||
"NVMERVS",
|
||||
"ORDINA",
|
||||
|
||||
Reference in New Issue
Block a user