2003-04-28
2003-04-28 00:32:44 by Martin Stjernholm <mast@lysator.liu.se>
-
2523ce4a7cf39f2e501784efc1df8ad1a473cbd2
(176 lines)
(+111/-65)
[
Show
| Annotate
]
Branch: 7.9
Improved type fields for arrays.
Rev: src/array.c:1.143
Rev: src/backend.cmod:1.42
Rev: src/builtin.cmod:1.134
Rev: src/builtin_functions.c:1.490
Rev: src/encode.c:1.172
Rev: src/interpret.c:1.304
Rev: src/iterators.cmod:1.41
Rev: src/main.c:1.175
Rev: src/mapping.c:1.166
Rev: src/modules/files/efuns.c:1.127
Rev: src/modules/system/memory.c:1.24
Rev: src/object.c:1.236
Rev: src/opcodes.c:1.145
Rev: src/operators.c:1.177
Rev: src/post_modules/Unicode/unicode_module.cmod:1.7
Rev: src/post_modules/_ADT/circular_list.cmod:1.8
Rev: src/post_modules/_ADT/sequence.cmod:1.8
2:
|| This file is part of Pike. For copyright information see COPYRIGHT.
|| Pike is distributed under GPL, LGPL and MPL. See the file COPYING
|| for more information.
- || $Id: builtin_functions.c,v 1.489 2003/04/27 20:12:11 mast Exp $
+ || $Id: builtin_functions.c,v 1.490 2003/04/28 00:32:43 mast Exp $
*/
#include "global.h"
- RCSID("$Id: builtin_functions.c,v 1.489 2003/04/27 20:12:11 mast Exp $");
+ RCSID("$Id: builtin_functions.c,v 1.490 2003/04/28 00:32:43 mast Exp $");
#include "interpret.h"
#include "svalue.h"
#include "pike_macros.h"
1787:
}
/*! @decl array allocate(int size)
- *! @decl array allocate(int size, mixed zero)
+ *! @decl array allocate(int size, mixed init)
*!
- *! Allocate an array of @[size] elements and initialize them to @[zero].
+ *! Allocate an array of @[size] elements. If @[init] is specified
+ *! then each element is initialized by copying that value
+ *! recursively.
*!
*! @seealso
*! @[sizeof()], @[aggregate()], @[arrayp()]
1812:
if(args>1)
{
INT32 e;
+ struct svalue *init = Pike_sp - args + 1;
+ push_array (a);
for(e=0;e<a->size;e++)
- copy_svalues_recursively_no_free(a->item+e, Pike_sp-args+1, 1, 0);
+ copy_svalues_recursively_no_free(a->item+e, init, 1, 0);
+ a->type_field = 1 << init->type;
+ stack_pop_n_elems_keep_top (args);
}
-
+ else {
+ a->type_field = BIT_INT;
pop_n_elems(args);
push_array(a);
}
-
+ }
/*! @decl object this_object(void|int level);
*!
2206:
a=allocate_array_no_init(size,0);
while(--size>=0)
{
- ITEM(a)[size].type=T_INT;
- ITEM(a)[size].subtype=NUMBER_NUMBER;
+ /* Elements are already integers. */
ITEM(a)[size].u.integer = DO_NOT_WARN((INT_TYPE)size);
}
-
+ a->type_field = BIT_INT;
break;
case T_MAPPING:
2501:
a = allocate_array_no_init(size,0);
while(--size >= 0)
{
- ITEM(a)[size].type = T_INT;
- ITEM(a)[size].subtype = NUMBER_NUMBER;
+ /* Elements are already integers. */
ITEM(a)[size].u.integer = index_shared_string(Pike_sp[-args].u.string, size);
}
-
+ a->type_field = BIT_INT;
break;
case T_ARRAY:
2523:
a=allocate_array_no_init(size,0);
while(--size>=0)
{
- ITEM(a)[size].type=T_INT;
- ITEM(a)[size].subtype=NUMBER_NUMBER;
+ /* Elements are already integers. */
ITEM(a)[size].u.integer=1;
}
-
+ a->type_field = BIT_INT;
#endif
break;
3848:
INT32 e;
struct array *a,*tmp;
struct svalue *val;
+ TYPE_FIELD types;
get_all_args("rows", args, "%*%a", &val, &tmp);
3856:
{
struct svalue sval;
tmp->type_field = BIT_MIXED | BIT_UNFINISHED;
+ types = 0;
for(e=0;e<tmp->size;e++)
{
index_no_free(&sval, val, ITEM(tmp)+e);
-
+ types |= 1 << sval.type;
free_svalue(ITEM(tmp)+e);
- ITEM(tmp)[e]=sval;
+ move_svalue (ITEM(tmp) + e, &sval);
}
-
+ tmp->type_field = types;
stack_swap();
pop_stack();
return;
}
push_array(a=allocate_array(tmp->size));
-
- for(e=0;e<a->size;e++)
+ types = 0;
+ for(e=0;e<a->size;e++) {
index_no_free(ITEM(a)+e, val, ITEM(tmp)+e);
-
+ types |= 1 << ITEM(a)[e].type;
+ }
+ a->type_field = types;
Pike_sp--;
dmalloc_touch_svalue(Pike_sp);
4624:
}
nelems++;
}
- /* FIXME: Is this needed? Isn't T_INT default? */
+
ITEM(min)[i].u.integer = low;
}
-
+ min->type_field = T_INT;
ref_push_array(order);
f_sort(2); /* Sort the order array on the minimum index */
4795:
res = low_allocate_array(top, 0);
while (ltop != -1)
{
- res->item[--top].u.integer = ltop;
+ ITEM(res)[--top].u.integer = ltop;
ltop = links[ltop];
}
-
+ res->type_field = T_INT;
UNSET_ONERROR(tmp2);
UNSET_ONERROR(tmp);
4846:
struct mapping *map;
struct svalue *pval;
int i;
+ TYPE_FIELD types;
if (u) {
*u = 0; /* Unique rows in array b */
4862:
struct svalue val;
val.type=T_ARRAY;
val.u.array=low_allocate_array(1,1);
- val.u.array->item[0].type=T_INT;
- val.u.array->item[0].subtype=NUMBER_NUMBER;
- val.u.array->item[0].u.integer=i;
- mapping_insert(map,b->item+i,&val);
+ ITEM(val.u.array)[0].u.integer=i;
+ val.u.array->type_field = BIT_INT;
+ mapping_insert(map,ITEM(b)+i,&val);
free_svalue(&val);
if (u) {
(*u)++;
4881:
}
res=low_allocate_array(a->size,0);
+ types = 0;
for (i=0; i<a->size; i++)
{
pval=low_mapping_lookup(map,a->item+i);
if (!pval)
{
- res->item[i].type=T_ARRAY;
- add_ref(res->item[i].u.array=&empty_array);
+ ITEM(res)[i].type=T_ARRAY;
+ add_ref(ITEM(res)[i].u.array=&empty_array);
+ types |= BIT_ARRAY;
}
else
{
- assign_svalue(res->item+i,pval);
+ assign_svalue(ITEM(res)+i,pval);
+ types |= 1 << ITEM(res)[i].type;
}
}
-
+ res->type_field = types;
pop_stack();
return res;
}
5256:
dml=stack[top-1];
while (dml)
{
- a->item[--top].u.integer=dml->x;
+ ITEM(a)[--top].u.integer=dml->x;
dml=dml->prev;
}
-
+ a->type_field = BIT_INT;
}
free(stack);
5410:
res = allocate_array(sz);
if (!res) {
+ /* FIXME: This is never called, so there should probably be
+ * SET_ONERROR stuff somewhere. I can't find where dml_pool is
+ * initialized, though. /mast */
int args = 0;
if (dml_pool) {
dml_free_pools(dml_pool);
5429: Inside #if defined(DIFF_DEBUG)
#ifdef DIFF_DEBUG
fprintf(stderr, " %02d: %d\n", i, dml->x);
#endif /* DIFF_DEBUG */
- res->item[i].type = T_INT;
- res->item[i].subtype = 0;
+
res->item[i].u.integer = dml->x;
dml = dml->prev;
i++;
}
-
+ res->type_field = BIT_INT;
#ifdef PIKE_DEBUG
if (i != sz) {
Pike_fatal("Consistency error in diff_dyn_longest_sequence()\n");
6284:
*! Remove elements that are duplicates.
*!
*! @returns
- *! This function returns an copy of the array @[a] with all duplicate
- *! values removed. The order of the values is kept in the result.
+ *! This function returns an copy of the array @[a] with all
+ *! duplicate values removed. The order of the values is kept in the
+ *! result; it's always the first of several equal elements that is
+ *! kept.
+ *!
+ *! @note
+ *! Elements are compared with @[`==]. They are also hashed (see
+ *! @[lfun::__hash] for further details if @[a] contains objects).
*/
PMOD_EXPORT void f_uniq_array(INT32 args)
{
6311:
}
dmalloc_touch_svalue(Pike_sp-1);
Pike_sp--; /* keep the ref to 'b' */
+ ACCEPT_UNFINISHED_TYPE_FIELDS {
b=resize_array(b, j);
-
+ } END_ACCEPT_UNFINISHED_TYPE_FIELDS;
+ b->type_field = a->type_field;
pop_n_elems(args-1); /* pop args and the mapping */
push_array(b);
}
6321:
*!
*! Splice two or more arrays.
*!
- *! This means that the the array becomes an array of the first element
- *! in the first given array, the first argument in next array and so on
- *! for all arrays. Then the second elements are added, etc.
+ *! This means that the returned array has the first element in the
+ *! first given array, then the first argument in next array and so
+ *! on for all arrays. Then the second elements are added, etc.
*!
*! @seealso
*! @[`/()], @[`*()], @[`+()], @[`-()], @[everynth()]
6334:
INT32 size=0x7fffffff;
INT32 i,j,k;
- #ifdef PIKE_DEBUG
- if(args < 0) Pike_fatal("Negative args to f_splice()\n");
- #endif
-
+
for(i=0;i<args;i++)
if (Pike_sp[i-args].type!=T_ARRAY)
SIMPLE_BAD_ARG_ERROR("splice", i+1, "array");
6380:
INT32 start=0;
struct array *a;
struct array *ina;
+ TYPE_FIELD types;
INT32 size=0;
#ifdef PIKE_DEBUG
if(args < 0) Pike_fatal("Negative args to f_everynth()\n");
6406:
}
a=allocate_array(((size=ina->size)-start+n-1)/n);
- for(k=0; start<size; start+=n)
- assign_svalue_no_free(a->item+(k++), ina->item+start);
+ types = 0;
+ for(k=0; start<size; k++, start+=n) {
+ assign_svalue_no_free(ITEM(a) + k, ina->item+start);
+ types |= 1 << ITEM(a)[k].type;
+ }
+ a->type_field=types;
- a->type_field=ina->type_field;
+
pop_n_elems(args);
push_array(a);
return;
6651:
INT32 e;
struct svalue *fun;
struct array *ret,*foo;
+ TYPE_FIELD types;
if (args < 2)
SIMPLE_TOO_FEW_ARGS_ERROR("map_array", 2);
6662:
fun=Pike_sp-args+1;
ret=allocate_array(foo->size);
+ types = 0;
SET_ONERROR(tmp, do_free_array, ret);
for(e=0;e<foo->size;e++)
{
- push_svalue(foo->item+e);
+ push_svalue(ITEM(foo)+e);
assign_svalues_no_free(Pike_sp,fun+1,args-2,-1);
Pike_sp+=args-2;
apply_svalue(fun,args-1);
- ret->item[e]=*(--Pike_sp);
- dmalloc_touch_svalue(Pike_sp);
+ stack_pop_to_no_free (ITEM(ret) + e);
+ types |= 1 << ITEM(ret)[e].type;
}
-
+ ret->type_field = types;
pop_n_elems(args);
UNSET_ONERROR(tmp);
push_array(ret);
6750:
struct svalue *mysp;
struct array *a,*d;
int splice,i,n;
+ TYPE_FIELD types;
if (args<1)
SIMPLE_TOO_FEW_ARGS_ERROR("map", 1);
6901:
n=Pike_sp[-1].u.integer;
pop_stack();
push_array(d=allocate_array(n));
+ types = 0;
stack_swap();
for (i=0; i<n; i++)
{
stack_dup(); /* `[] */
push_int(i);
f_call_function(2);
- d->item[i]=*(--Pike_sp);
- dmalloc_touch_svalue(Pike_sp);
+ stack_pop_to_no_free (ITEM(d) + i);
+ types |= 1 << ITEM(d)->type;
}
-
+ d->type_field = types;
pop_stack();
free_svalue(mysp-3);
mysp[-3]=*(--Pike_sp);
6945:
/* ret[i]=fun(arr[i],@extra); */
push_array(d=allocate_array(n));
d=Pike_sp[-1].u.array;
+ types = 0;
if(mysp[-2].type == T_FUNCTION &&
mysp[-2].subtype == FUNCTION_BUILTIN)
6962:
(* fun)(1+splice);
if(Pike_sp>spbase)
{
- dmalloc_touch_svalue(Pike_sp-1);
- d->item[i]=*--Pike_sp;
+ stack_pop_to_no_free (ITEM(d) + i);
+ types |= 1 << ITEM(d)[i].type;
pop_n_elems(Pike_sp-spbase);
}
}
}else{
for (i=0; i<n; i++)
{
- push_svalue(a->item+i);
+ push_svalue(ITEM(a)+i);
(* fun)(1);
if(Pike_sp>spbase)
{
- dmalloc_touch_svalue(Pike_sp-1);
- d->item[i]=*--Pike_sp;
+ stack_pop_to_no_free (ITEM(d) + i);
+ types |= 1 << ITEM(d)[i].type;
pop_n_elems(Pike_sp-spbase);
}
}
6983:
}else{
for (i=0; i<n; i++)
{
- push_svalue(a->item+i);
+ push_svalue(ITEM(a)+i);
if (splice)
{
add_ref_svalue(mysp-1);
6994:
{
apply_svalue(mysp-2,1);
}
- dmalloc_touch_svalue(Pike_sp-1);
- d->item[i]=*--Pike_sp;
+ stack_pop_to_no_free (ITEM(d) + i);
+ types |= 1 << ITEM(d)[i].type;
}
}
-
+ d->type_field = types;
stack_pop_n_elems_keep_top(3); /* fun arr extra d -> d */
return;
7012:
case T_STRING:
/* ret[i]=arr[i][fun](@extra); */
push_array(d=allocate_array(n));
- d=Pike_sp[-1].u.array;
+ types = 0;
for (i=0; i<n; i++)
{
- push_svalue(a->item+i);
+ push_svalue(ITEM(a)+i);
push_svalue(mysp-2);
f_arrow(2);
if(UNSAFE_IS_ZERO(Pike_sp-1))
7026:
add_ref_svalue(mysp-1);
push_array_items(mysp[-1].u.array);
f_call_function(splice+1);
- d->item[i]=*--Pike_sp;
- dmalloc_touch_svalue(Pike_sp);
+ stack_pop_to_no_free (ITEM(d) + i);
+ types |= 1 << ITEM(d)[i].type;
}
-
+ d->type_field = types;
stack_pop_n_elems_keep_top(3); /* fun arr extra d -> d */
return;
7416:
push_array(d=allocate_array(n));
for (i=0; i<n; i++)
{
- d->item[i].u.integer=start;
- d->item[i].type=T_INT;
- d->item[i].subtype=NUMBER_NUMBER;
+ ITEM(d)[i].u.integer=start;
#ifdef AUTO_BIGNUM
if ((step>0 && start+step<start) ||
(step<0 && start+step>start)) /* overflow */
7435:
#endif
start+=step;
}
+ d->type_field = BIT_INT;
}
else if (args<=3 &&
((Pike_sp[1-args].type==T_INT ||
7457:
d->item[i].type=T_FLOAT;
start+=step;
}
+ d->type_field = BIT_FLOAT;
}
else
{
-
+ TYPE_FIELD types = 0;
get_all_args("enumerate", args, "%i", &n);
if (n<0) SIMPLE_BAD_ARG_ERROR("enumerate",1,"int(0..)");
if (args>4) pop_n_elems(args-4);
-
+ push_array(d=allocate_array(n));
if (args<4)
{
- push_array(d=allocate_array(n));
+
push_svalue(Pike_sp-2); /* start */
for (i=0; i<n; i++)
{
- assign_svalue_no_free(d->item+i,Pike_sp-1);
+ assign_svalue_no_free(ITEM(d)+i,Pike_sp-1);
+ types |= 1 << ITEM(d)[i].type;
if (i<n-1)
{
push_svalue(Pike_sp-4); /* step */
7479:
}
else
{
- push_array(d=allocate_array(n));
+
push_svalue(Pike_sp-3); /* start */
for (i=0; i<n; i++)
{
- assign_svalue_no_free(d->item+i,Pike_sp-1);
+ assign_svalue_no_free(ITEM(d)+i,Pike_sp-1);
+ types |= 1 << ITEM(d)[i].type;
if (i<n-1)
{
push_svalue(Pike_sp-3); /* function */
7493:
}
}
}
+ d->type_field = types;
pop_stack();
stack_pop_n_elems_keep_top(args);
}