#include "efuns.h"
#include "array.h"
#include "mapping.h"
#include "simulate.h"
void f_m_aggregate(int num_arg,struct svalue *argp)
{
int i;
struct vector *v, *w;
if(num_arg%2)
error("Odd number of arguments to m_aggregate.\n");
num_arg/=2;
v = allocate_array_no_init(num_arg,0);
w = allocate_array_no_init(num_arg,0);
for (i=0; i < num_arg; i ++)
{
v->item[i]=*argp;
#ifdef WARN
argp->type=2000;
#endif
argp++;
w->item[i]=*argp;
#ifdef WARN
argp->type=2000;
#endif
argp++;
}
sp-=num_arg*2;
v = allocate_mapping(v, w);
order_alist(v);
push_mapping(v);
v->ref--;
}
void f_m_cleanup(int num_arg,struct svalue *argp)
{
struct vector *v;
extern struct vector *cleanup_map(struct vector *);
v=cleanup_map(argp->u.vec);
pop_stack();
push_mapping(v);
v->ref--;
}
void f_sum_mappings(int num_arg,struct svalue *argp)
{
struct vector *v;
extern struct vector *sum_mappings(struct vector *,struct vector *,struct svalue *,struct svalue *,struct svalue *);
if(!IS_TYPE(argp[2],BT_FUNCTION | BT_NUMBER)) bad_arg(2,F_SUM_MAPPINGS);
if(!IS_TYPE(argp[3],BT_FUNCTION | BT_NUMBER)) bad_arg(3,F_SUM_MAPPINGS);
if(!IS_TYPE(argp[4],BT_FUNCTION | BT_NUMBER)) bad_arg(4,F_SUM_MAPPINGS);
v=sum_mappings(argp[0].u.vec,argp[1].u.vec,argp+2,argp+3,argp+4);
pop_n_elems(5);
push_mapping(v);
v->ref--;
}
void f_m_set_default(int num_arg,struct svalue *argp)
{
map_set_default(argp[0].u.vec,argp+1);
pop_stack();
}
void f_m_get_default(int num_arg,struct svalue *argp)
{
struct vector *v;
v=sp->u.vec;
v->ref++;
assign_svalue(sp,v->item+2);
free_vector(v);
}
void f_filter_mapping(int num_arg,struct svalue *argp)
{
struct vector *v,*res,*m;
int e,s;
m=argp[0].u.vec;
check_alist_for_destruct(m);
res = map_array(m->item[1].u.vec,argp+1,argp+2,num_arg-2);
for(s=e=0;e<res->size;e++)
if(res->item[e].type!=T_NUMBER || res->item[e].u.number!=0) s++;
v = allocate_mapping(allocate_array_no_init(s,0),allocate_array_no_init(s,0));
for(s=e=0;e<res->size;e++)
{
if(res->item[e].type!=T_NUMBER || res->item[e].u.number!=0)
{
assign_svalue_no_free(v->item[0].u.vec->item+s,m->item[0].u.vec->item+e);
assign_svalue_no_free(v->item[1].u.vec->item+s,m->item[1].u.vec->item+e);
s++;
}
}
free_vector(res);
pop_n_elems(num_arg);
push_mapping(v); /* This will make ref count == 2 */
v->ref--;
}
void f_mkmapping(int num_arg,struct svalue *argp)
{
struct vector *v;
int i;
i = (sp-1)->u.vec->size;
if (i > sp->u.vec->size)
{
i = sp->u.vec->size;
}
v = allocate_mapping(slice_array((sp-1)->u.vec, 0, i - 1),
slice_array(sp->u.vec, 0, i - 1));
pop_n_elems(2);
order_alist(v);
push_mapping(v);
v->ref--;
}
void f_indices(int num_arg,struct svalue *argp)
{
struct vector *v;
switch(sp->type)
{
default:
bad_arg(1,F_INDICES);
break;
case T_LIST:
case T_MAPPING:
v=sp->u.vec;
check_alist_for_destruct(v);
v=v->item[0].u.vec;
v=slice_array(v,0,v->size-1);
pop_stack();
push_vector(v);
v->ref--;
}
}
void f_m_indices(int num_arg,struct svalue *argp)
{
struct vector *v;
v = sp->u.vec;
check_alist_for_destruct(v);
v = v->item[0].u.vec;
v = slice_array(v, 0, v->size - 1);
pop_stack();
push_vector(v);
v->ref--; /* Will make ref count == 1 */
}
void f_m_values(int num_arg,struct svalue *argp)
{
struct vector *v;
v = sp->u.vec;
check_alist_for_destruct(v);
v = v->item[1].u.vec;
#if 0
v = slice_array(v, 0, v->size - 1);
pop_stack();
push_vector(v);
v->ref--; /* Will make ref count == 1 */
#else
v->ref++;
pop_stack();
push_vector(v);
v->ref--;
#endif
}
void f_m_delete(int num_arg,struct svalue *argp)
{
struct vector *v;
check_alist_for_destruct((sp-1)->u.vec);
v=remove_mapping2((sp-1)->u.vec,sp);
pop_stack();
}
void f_map_mapping(int num_arg,struct svalue *argp)
{
struct vector *res;
check_eval_cost();
check_alist_for_destruct(argp[0].u.vec);
res = map_array(argp[0].u.vec->item[1].u.vec,argp+1,argp+2,num_arg-2);
res = allocate_mapping(argp[0].u.vec->item[0].u.vec,res);
argp[0].u.vec->item[0].u.vec->ref++;
pop_n_elems(num_arg);
push_mapping(res);
res->ref--;
}
void f_solidify_mapping(int num_arg,struct svalue *argp)
{
int e,num,num2;
struct vector *v,*ind,*val,*ret_ind,*ret_val,*data;
v=argp[0].u.vec;
check_alist_for_destruct(v);
ind=v->item[0].u.vec;
val=v->item[1].u.vec;
if(ind->size)
{
num=1;
for(e=0;e<ind->size-1;e++)
if(alist_cmp(ind->item+e,ind->item+e+1))
num++;
}else{
num=0;
}
ret_ind=allocate_array_no_init(num,0);
ret_val=allocate_array_no_init(num,0);
num=0;
for(e=0;e<ind->size;)
{
assign_svalue_raw(ret_ind->item+num,ind->item+e);
for(num2=0;num2+e<ind->size-1 &&
!alist_cmp(ind->item+e+num2,ind->item+e+num2+1);num2++);
data=allocate_array_no_init(num2+1,0);
copy_svalues_raw(data->item,val->item+e,num2+1);
e+=num2+1;
ret_val->item[num].u.vec=data;
ret_val->item[num].type=T_POINTER;
num++;
}
pop_stack();
v=allocate_mapping(ret_ind,ret_val);
push_mapping(v);
v->ref--;
}