Branch: Tag:

2014-08-14

2014-08-14 13:36:53 by Per Hedbor <ph@opera.com>

Fixed support for automap in assignments.

This was handled in a somewhat so-so manner in += and friends.

Specifically, it ignored the [*] on the LHS and just assigned the
variable to the result of the automap.

So, x[*]+=10; was transformed to x = x[*] + 10;

It also only worked for += with friends, not =, so x[*] = x[*] + 1 did
not work.

Now a new opcode is used that assigns array elements individually.
This means that this works:

| array x = ({1,2,3});
| array y = x;
|
| x[*] += 10;
| x==y; // will now be true, was previously false.

Of course, this actually changes how automap works.

The assignment is currently only done on the toplevel, x[*][*] =
x[*][*]+1 still works just fine, but it has some similarities with the
previous situation, the arrays in the toplevel array will be swapped,
not altered.

this will be fixed soonish(tm)

1078:    Pike_sp-=2;   });    + OPCODE1(F_ASSIGN_INDICES, "assign[]", I_UPDATE_SP, { +  LOCAL_VAR(struct array *arr); +  LOCAL_VAR(struct array *from); +  LOCAL_VAR(int i); +  +  /* Note: All thse checks are presumably fairly pointless. */ +  if(TYPEOF(Pike_sp[-2]) != PIKE_T_ARRAY ) +  PIKE_ERROR("[*]=", "Destination is not an array.\n", Pike_sp, 1); +  +  if(TYPEOF(Pike_sp[-1]) != PIKE_T_ARRAY ) +  PIKE_ERROR("[*]=", "Source is not an array.\n", Pike_sp-1, 1); +  +  arr = Pike_sp[-2].u.array; +  from = Pike_sp[-1].u.array; +  +  if( arr->size != from->size ) +  Pike_error("Source and destination differs in size in automap.\n"); +  +  assign_svalues(arr->item,from->item,arr->size,arr->type_field|from->type_field); +  +  pop_stack(); /* leaves arr on stack. */ + }); +    OPCODE2(F_APPLY_ASSIGN_LOCAL_AND_POP, "apply, assign local and pop", I_UPDATE_SP|I_UPDATE_M_SP, {    apply_svalue(&((Pike_fp->context->prog->constants + arg1)->sval),    DO_NOT_WARN((INT32)(Pike_sp - *--Pike_mark_sp)));