Re: Array rvals, lvals and dimension

David Hakim <dhakim-Gkm/TONP9n1Wk0Htik3J/[email protected]> Wed, 30 Apr 2003 22:41:53 -0400
Newsgroups gmane.comp.lang.moto.devel
Message-ID <[email protected]>
On Wednesday, April 30, 2003, at 08:27  PM, Stefano Corsi wrote:

> Dave,
>
> I have modified array_rval and array_lval in motov.c and motoc.c to 
> reflect
> the way they are called in motoi.c, as you suggested. All tests pass 
> and the
> change seems to work fine.
>
> Then I did something strange: I noticed that the for loop for all 
> dimensions
> in motoi_array_lval is never executed more than once.

Yep, looks like moto.y changed to a recursive rule for subscripts a 
while back

array_subscript_expression
	: postfix_expression array_index {$$=op(ENV, 
ARRAY_RVAL,UCMetaInfo($1),2,$1,$2);}
;

It grabs one index at a time instead of constructing an 
array_index_list for ARRAY_RVAL and ARRAY_LVAL ops.

>  So I did some (dumb
> monkey style)  cutting job and I resized the motoi_array_lval to just
> evaluate ONE array index without the for loop, and, quite 
> unexpectedly, it
> works and passes all tests.

:)

> Can you see some side effects in the cutting job I did and maybe 
> produce a
> test to show it?
> Here is the moto_array_lval after my work. If it's good, then 
> implementing the
> [] overl. operator could be a bit nearer.
>
> motoi_array_lval(const UnionCell *p){
>     MotoEnv *env = moto_getEnv();
>     MotoVal *val, *ival;
>     MotoVar *rvar;
>     UnArray *ua;
>     int *dimarr;
>
>     /* Evaluate the first operand to get the Array*/
>     motoi(uc_operand(p, 0));
>     val = opstack_pop(env);
>
>     /* Evaluate the ARRAY_INDEX element */
>     motoi(uc_operand(p, 1));  /* array_index list */
>     ival = opstack_pop(env);
>
right ... it looks like it hasn't been an array_index_list for some 
time ... good thing too :)

>     /* Build an array of the specified indexes */
>     dimarr = (int*)emalloc(sizeof(int)* (1));	
>
Do we even need to bother with dimarr anymore ? Since we are only 
subscripting one index at a time I think we can lose it and just store 
a local 'index' value. That will save us from having to clean up the 
memory later and speed up the interpreter in cases when the number of 
array accesses is high.

>     if (ival->type->kind == INT32_TYPE)
>         dimarr[0] = iv(ival);
>     else /* (ival->type->kind == INT64_TYPE) */
>         dimarr[0] = lv(ival);
>     moto_freeVal(env,ival);
>
>     rvar = moto_createVar(
>         env,NULL,
>         val->type->atype->name,
>         val->type->dim - 1,
>         '\1',
>         NULL
>     );
>
>     /* Clean up val now since we might need to throw an exception */
>     moto_freeVal(env,val);
>
>     if (ua == NULL){
>         /* Clean up and throw NullPointerException */
>         free(dimarr);
>         moto_freeVar(env,rvar);
>         MOTO_THROW("NullPointerException","Attempt to subscript null");
>     }
>     if(dimarr[0] < 0 || dimarr[0] >= ua->meta.length){
>         /* Clean up and throw ArrayBoundsException */
>         free(dimarr);
>         moto_freeVar(env,rvar);
>         MOTO_THROW("ArrayBoundsException","Attempt to subscript array 
> outside
> of declared bounds");
>     }
>
>     if (val->type->dim == 1){
>         switch (val->type->atype->kind){
>             case INT32_TYPE: rvar->address = &ua->ia.data[dimarr[0]]; 
> break;
>             case INT64_TYPE: rvar->address = &ua->la.data[dimarr[0]]; 
> break;
>             case FLOAT_TYPE: rvar->address = &ua->fa.data[dimarr[0]]; 
> break;
>             case DOUBLE_TYPE: rvar->address = &ua->da.data[dimarr[0]]; 
> break;
>             case BOOLEAN_TYPE: rvar->address = 
> &ua->ba.data[dimarr[0]]; break;
>             case BYTE_TYPE: rvar->address = &ua->ya.data[dimarr[0]]; 
> break;
>             case CHAR_TYPE: rvar->address = &ua->ca.data[dimarr[0]]; 
> break;
>             case REF_TYPE: rvar->address = &ua->ra.data[dimarr[0]]; 
> break;
>             default: {THROW_D("MotoCellTypeException");}
>         }
>         } else {
>         rvar->address = &ua->aa.data[dimarr[0]];
> }
>
>     free(dimarr);
>     opstack_push(env, (MotoVal*)rvar);
> }
>
>
Looks good to me!

-Dave