refactor: unify n() with other region functions

This commit is contained in:
Glen Whitney 2023-04-29 15:51:49 -04:00
parent 34e8b99585
commit 1c72d0712b
1 changed files with 19 additions and 66 deletions

View File

@ -1280,6 +1280,22 @@ static void minmax_finl(FunctionIdentifier id, Location *loc, Token *tok)
LOCATION_GETS(tok->u.location, *loc);
}
static void n_init(FunctionIdentifier id, Location *loc, Token *tok)
{
assert(id == FUNC_N);
tfree(tok);
tok->type = EMPTY;
tok->type = INT;
tok->u.integer = 0;
}
static void n_updt(FunctionIdentifier id, Location *loc, Token *tok,
const Location* newloc, const Token *newtok)
{
assert(id == FUNC_N);
tok->u.integer += (newtok->type != EMPTY);
}
static Token reg_disp(FunctionIdentifier self, int argc, const Token argv[])
{
RegFuncInit i = 0;
@ -1291,76 +1307,13 @@ static Token reg_disp(FunctionIdentifier self, int argc, const Token argv[])
case FUNC_MIN:
case FUNC_MAX:
u = minmax_updt; f = minmax_finl; break;
case FUNC_N:
i = n_init; u = n_updt; break;
default: assert(0);
}
return region_func(i, u, f, self, argc, argv);
}
/* n -- return whether a value is non-empty, or count the number of
non-empty values in a region or in the argument list */ /*{{{*/
static Token n_func(FunctionIdentifier self, int argc, const Token argv[])
{
assert(self == FUNC_N);
/* variables */ /*{{{*/
Token result;
const char *usage = _("Usage: n([location[,location]])|n(val1,val2,...)");
Location w;
bool singleloc = true;
bool loclist = true;
/*}}}*/
if (argc < 0) return duperror(&result, usage);
result.type = INT;
result.u.integer = 0;
switch (argc) {
case 0: LOCATION_GETS(w, upd_l); break;
case 1:
if (argv[0].type == LOCATION) LOCATION_GETS(w, argv[0].u.location);
else singleloc = false;
break;
case 2:
if (argv[0].type == LOCATION && argv[1].type == LOCATION)
loclist = false;
/* FALL THROUGH */
case 3:
singleloc = false;
}
if (singleloc) {
Token tmp = recompvalue(upd_sheet, w);
result.u.integer = (tmp.type != EMPTY);
tfree(&tmp);
return result;
}
if (loclist) {
for (int i = 0; i < argc; ++i)
switch (argv[i].type) {
case EEK: return argv[i];
case EMPTY: break;
default: result.u.integer++;
}
return result;
}
int x1, y1, z1;
int x2, y2, z2;
x1=argv[0].u.location[0]; x2=argv[1].u.location[0]; posorder(&x1,&x2);
y1=argv[0].u.location[1]; y2=argv[1].u.location[1]; posorder(&y1,&y2);
z1=argv[0].u.location[2]; z2=argv[1].u.location[2]; posorder(&z1,&z2);
for (w[X]=x1; w[X]<=x2; ++(w[X]))
for (w[Y]=y1; w[Y]<=y2; ++(w[Y]))
for (w[Z]=z1; w[Z]<=z2; ++(w[Z]))
{
Token tmp = recompvalue(upd_sheet, w);
if (tmp.type != EMPTY) result.u.integer++;
tfree(&tmp);
}
return result;
}
/*}}}*/
/* binop_func -- common implementation of all binary operations
as function calls */ /*{{{*/
static Token binop_func(FunctionIdentifier self, int argc, const Token argv[])
@ -1831,7 +1784,7 @@ Tfunc tfunc[]=
/* Block operations */
[FUNC_MAX] = { "max", reg_disp, PREFIX_FUNC, FUNCT, 0 },
[FUNC_MIN] = { "min", reg_disp, PREFIX_FUNC, FUNCT, 0 },
[FUNC_N] = { "n", n_func, PREFIX_FUNC, FUNCT, 0 },
[FUNC_N] = { "n", reg_disp, PREFIX_FUNC, FUNCT, 0 },
[FUNC_SUM] = { "sum", reg_disp, PREFIX_FUNC, FUNCT, 0 },
/* String functions */