lpc4/lib/
lpc4/lib/doc/efun/
lpc4/lib/doc/lfun/
lpc4/lib/doc/operators/
lpc4/lib/doc/simul_efuns/
lpc4/lib/doc/types/
lpc4/lib/etc/
lpc4/lib/include/
lpc4/lib/include/arpa/
lpc4/lib/obj/d/
lpc4/lib/save/
lpc4/lib/secure/
lpc4/lib/std/
lpc4/lib/std/living/
#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--;
}