Array rvals, lvals and dimension

Stefano Corsi <[email protected]> Thu, 1 May 2003 00:27:26 +0000
Newsgroups gmane.comp.lang.moto.devel
Organization Moto Project
Message-ID <[email protected]>
Dave,=20

I have modified array_rval and array_lval in motov.c and motoc.c to refle=
ct=20
the way they are called in motoi.c, as you suggested. All tests pass and =
the=20
change seems to work fine.=20

Then I did something strange: I noticed that the for loop for all dimensi=
ons=20
in motoi_array_lval is never executed more than once. So I did some (dumb=
=20
monkey style)  cutting job and I resized the motoi_array_lval to just=20
evaluate ONE array index without the for loop, and, quite unexpectedly, i=
t=20
works and passes all tests.=20
Can you see some side effects in the cutting job I did and maybe produce =
a=20
test to show it?
Here is the moto_array_lval after my work. If it's good, then implementin=
g the=20
[] overl. operator could be a bit nearer.

motoi_array_lval(const UnionCell *p){
    MotoEnv *env =3D 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 =3D opstack_pop(env);

    /* Evaluate the ARRAY_INDEX element */
    motoi(uc_operand(p, 1));  /* array_index list */
    ival =3D opstack_pop(env);

    /* Build an array of the specified indexes */
    dimarr =3D (int*)emalloc(sizeof(int)* (1));=09

    if (ival->type->kind =3D=3D INT32_TYPE)
        dimarr[0] =3D iv(ival);
    else /* (ival->type->kind =3D=3D INT64_TYPE) */
        dimarr[0] =3D lv(ival);
    moto_freeVal(env,ival);

    rvar =3D moto_createVar(
        env,NULL,
        val->type->atype->name,
        val->type->dim - 1,
        '\1',
        NULL
    );
   =20
    /* Clean up val now since we might need to throw an exception */
    moto_freeVal(env,val);

    if (ua =3D=3D 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] >=3D ua->meta.length){
        /* Clean up and throw ArrayBoundsException */
        free(dimarr);
        moto_freeVar(env,rvar);
        MOTO_THROW("ArrayBoundsException","Attempt to subscript array out=
side=20
of declared bounds");
    }

    if (val->type->dim =3D=3D 1){
        switch (val->type->atype->kind){
            case INT32_TYPE: rvar->address =3D &ua->ia.data[dimarr[0]]; b=
reak;
            case INT64_TYPE: rvar->address =3D &ua->la.data[dimarr[0]]; b=
reak;
            case FLOAT_TYPE: rvar->address =3D &ua->fa.data[dimarr[0]]; b=
reak;
            case DOUBLE_TYPE: rvar->address =3D &ua->da.data[dimarr[0]]; =
break;
            case BOOLEAN_TYPE: rvar->address =3D &ua->ba.data[dimarr[0]];=
 break;
            case BYTE_TYPE: rvar->address =3D &ua->ya.data[dimarr[0]]; br=
eak;
            case CHAR_TYPE: rvar->address =3D &ua->ca.data[dimarr[0]]; br=
eak;
            case REF_TYPE: rvar->address =3D &ua->ra.data[dimarr[0]]; bre=
ak;
            default: {THROW_D("MotoCellTypeException");}
        }
        } else {
        rvar->address =3D &ua->aa.data[dimarr[0]];
}

    free(dimarr);
    opstack_push(env, (MotoVal*)rvar);
}