pike.git/
src/
builtin_functions.c
Branch:
Tag:
Non-build tags
All tags
No tags
1999-07-27
1999-07-27 19:19:52 by Mirar (Pontus Hagland) <pike@sort.mirar.org>
6279130ab428a532cab32025fca4061d2689ed1b (
195
lines) (+
193
/-
2
)
[
Show
|
Annotate
]
Branch:
7.9
filter() added
Rev: src/builtin_functions.c:1.175
5:
\*/ /**/ #include "global.h"
-
RCSID("$Id: builtin_functions.c,v 1.
174
1999/07/27
17
:
36
:
09
mirar Exp $");
+
RCSID("$Id: builtin_functions.c,v 1.
175
1999/07/27
19
:
19
:
52
mirar Exp $");
#include "interpret.h" #include "svalue.h" #include "pike_macros.h"
4248:
} }
+
void f_filter(INT32 args)
+
{
+
/* filter(mixed arr,mixed fun,mixed ... extra) ->
+
+
_arr__________goes________
+
+
array keep=map(arr,fun,@extra);
+
for (i=0; i<sizeof(arr); i++)
+
if (keep[i]) res+=({arr[i]});
+
+
multiset (multiset)filter((array)arr,fun,@extra);
+
+
mapping | ind=indices(arr),val=values(arr)
+
program | keep=map(val,fun,@extra);
+
function for (i=0; i<sizeof(keep); i++)
+
if (keep[i]) res[ind[i]]=val[i];
+
+
string (string)filter( (array)arr,fun,@extra );
+
+
object if arr->cast :
+
try filter((array)arr,fun,@extra);
+
try filter((mapping)arr,fun,@extra);
+
try filter((multiset)arr,fun,@extra);
+
*/
+
+
int n,i,m,k;
+
struct array *a,*y,*f;
+
struct svalue *mysp;
+
+
if (args<1)
+
SIMPLE_TOO_FEW_ARGS_ERROR("filter", 1);
+
+
switch (sp[-args].type)
+
{
+
case T_ARRAY:
+
MEMMOVE(sp-args+1,sp-args,args*sizeof(*sp));
+
sp++;
+
add_ref_svalue(sp-args);
+
+
f_map(args);
+
f=sp[-1].u.array;
+
a=sp[-2].u.array;
+
n=a->size;
+
for (k=m=i=0; i<n; i++)
+
if (!IS_ZERO(f->item+i))
+
{
+
push_svalue(a->item+i);
+
if (m++>32)
+
{
+
f_aggregate(m),m=0;
+
if (++k>32) f_add(k),k=1;
+
}
+
}
+
if (m||!k) f_aggregate(m);
+
if (m||k) f_add(k+1);
+
stack_pop_n_elems_keep_top(2);
+
return;
+
+
case T_MAPPING:
+
case T_PROGRAM:
+
case T_FUNCTION:
+
/* mapping ret =
+
mkmapping(indices(arr),
+
map(values(arr),fun,@extra)); */
+
MEMMOVE(sp-args+2,sp-args,args*sizeof(*sp));
+
sp+=2;
+
sp[-args-2].type=T_INT;
+
sp[-args-1].type=T_INT;
+
+
push_svalue(sp-args);
+
f_indices(1);
+
sp[-args-3]=*--sp;
+
push_svalue(sp-args);
+
f_values(1);
+
sp[-args-2]=*--sp;
+
+
assign_svalue(sp-args,sp-args-1); /* loop values only */
+
f_map(args);
+
+
y=sp[-3].u.array;
+
a=sp[-2].u.array;
+
f=sp[-1].u.array;
+
n=a->size;
+
+
for (m=i=0; i<n; i++)
+
if (!IS_ZERO(f->item+i)) m++;
+
+
push_mapping(allocate_mapping(MAXIMUM(m,4)));
+
+
for (i=0; i<n; i++)
+
if (!IS_ZERO(f->item+i))
+
mapping_insert(sp[-1].u.mapping,y->item+i,a->item+i);
+
+
stack_pop_n_elems_keep_top(3);
+
return;
+
+
case T_MULTISET:
+
/* multiset ret =
+
(multiset)(map(indices(arr),fun,@extra)); */
+
push_svalue(sp-args); /* take indices from arr */
+
free_svalue(sp-args-1); /* move it to top of stack */
+
sp[-args-1].type=T_INT;
+
f_indices(1); /* call f_indices */
+
sp--;
+
sp[-args]=sp[0]; /* move it back */
+
f_filter(args);
+
sp--; /* allocate_multiset is destructive */
+
push_multiset(allocate_multiset(sp->u.array));
+
return;
+
+
case T_STRING:
+
/* multiset ret =
+
(string)(map((array)arr,fun,@extra)); */
+
push_svalue(sp-args); /* take indices from arr */
+
free_svalue(sp-args-1); /* move it to top of stack */
+
sp[-args-1].type=T_INT;
+
o_cast(NULL,T_ARRAY); /* cast the string to an array */
+
sp--;
+
sp[-args]=sp[0]; /* move it back */
+
f_filter(args);
+
o_cast(NULL,T_STRING); /* cast the array to a string */
+
return;
+
+
case T_OBJECT:
+
/* if arr->cast :
+
try map((array)arr,fun,@extra);
+
try map((mapping)arr,fun,@extra);
+
try map((multiset)arr,fun,@extra); */
+
+
mysp=sp+3-args;
+
+
push_svalue(mysp-3);
+
push_constant_text("cast");
+
f_arrow(2);
+
if (!IS_ZERO(sp-1))
+
{
+
pop_stack();
+
+
push_constant_text("array");
+
safe_apply(mysp[-3].u.object,"cast",1);
+
if (sp[-1].type==T_ARRAY)
+
{
+
free_svalue(mysp-3);
+
mysp[-3]=*(--sp);
+
f_filter(args);
+
return;
+
}
+
pop_stack();
+
+
push_constant_text("mapping");
+
safe_apply(mysp[-3].u.object,"cast",1);
+
if (sp[-1].type==T_MAPPING)
+
{
+
free_svalue(mysp-3);
+
mysp[-3]=*(--sp);
+
f_filter(args);
+
return;
+
}
+
pop_stack();
+
+
push_constant_text("multiset");
+
safe_apply(mysp[-3].u.object,"cast",1);
+
if (sp[-1].type==T_MULTISET)
+
{
+
free_svalue(mysp-3);
+
mysp[-3]=*(--sp);
+
f_filter(args);
+
return;
+
}
+
pop_stack();
+
}
+
pop_stack();
+
+
SIMPLE_BAD_ARG_ERROR("filter",1,
+
"...|object that can be cast to array, multiset or mapping");
+
+
default:
+
SIMPLE_BAD_ARG_ERROR("filter",1,
+
"array|mapping|program|function|"
+
"multiset|string|object");
+
}
+
}
+
void f_string_count(INT32 args) { struct pike_string * haystack=NULL;
4618:
tFuncV(tArr(tStringIndicable) tString,tMix,tMix), tFuncV(tObj,tMix,tMix) ),
+
OPT_TRY_OPTIMIZE);
-
+
ADD_EFUN("filter",f_filter,
+
tOr3( tFuncV(tSetvar(1,tOr4(tArray,tMapping,tMultiset,tString)),
+
tMixed,tVar(1)),
+
tFuncV(tOr(tProgram,tFunction),tMixed,tMap(tString,tMix)),
+
tFuncV(tObj,tMix,tMix) ) ,
OPT_TRY_OPTIMIZE);
-
+
#ifdef DEBUG_MALLOC /* function(void:void) */