Pre-and-post-modification operators now work substantially better (i.e.,

working).
This commit is contained in:
David Given 2017-01-07 18:46:03 +01:00
parent 39215c131e
commit 5a38ce2a69

View file

@ -80,33 +80,80 @@ lvalexp(struct tnode *tr)
if (tr->tr1->op == STAR) { if (tr->tr1->op == STAR) {
rcexpr(tr->tr1->tr1); rcexpr(tr->tr1->tr1);
tonativeaddr(); tonativeaddr();
if ((tr->op == DECBEF) || (tr->op == INCBEF)) {
C_dup(wordsize); /* ( addr addr -- ) */
C_loi(wordsize); /* ( addr val -- ) */
if (tr->op == DECBEF)
C_dec(); /* ( addr newval -- ) */
else
C_inc(); /* ( addr newval -- ) */
C_exg(wordsize); /* ( newval addr -- ) */
C_dup(wordsize*2); /* ( newval addr newval addr -- ) */
C_sti(wordsize); /* ( newval addr -- ) */
C_asp(wordsize); /* ( newval -- ) */
} else {
C_dup(wordsize); /* ( addr addr -- ) */
C_loi(wordsize); /* ( addr val -- ) */
C_dup(wordsize*2); /* ( addr val addr val -- ) */
if (tr->op == DECAFT)
C_dec(); /* ( addr val addr newval -- ) */
else
C_inc(); /* ( addr val addr newval -- ) */
C_exg(wordsize); /* ( addr val newval addr -- ) */
C_sti(wordsize); /* ( addr val -- ) */
C_exg(wordsize); /* ( val addr -- ) */
C_asp(wordsize); /* ( val -- ) */
}
} else { /* NAME, checked in "build" */ } else { /* NAME, checked in "build" */
bs = (struct hshtab *) tr->tr1->tr1; bs = (struct hshtab *) tr->tr1->tr1;
if (bs->class == EXTERN) if (bs->class == EXTERN) {
C_lae_dnam(manglename(bs->name, 'b'), 0); switch (tr->op) {
else if (bs->class == AUTO) case INCBEF:
C_lal(bs->offset); C_ine_dnam(manglename(bs->name, 'b'), 0);
else C_loe_dnam(manglename(bs->name, 'b'), 0);
break;
case DECBEF:
C_dee_dnam(manglename(bs->name, 'b'), 0);
C_loe_dnam(manglename(bs->name, 'b'), 0);
break;
case INCAFT:
C_loe_dnam(manglename(bs->name, 'b'), 0);
C_ine_dnam(manglename(bs->name, 'b'), 0);
break;
case DECAFT:
C_loe_dnam(manglename(bs->name, 'b'), 0);
C_dee_dnam(manglename(bs->name, 'b'), 0);
break;
}
} else if (bs->class == AUTO) {
switch (tr->op) {
case INCBEF:
C_inl(bs->offset);
C_lol(bs->offset);
break;
case DECBEF:
C_del(bs->offset);
C_lol(bs->offset);
break;
case INCAFT:
C_lol(bs->offset);
C_inl(bs->offset);
break;
case DECAFT:
C_lol(bs->offset);
C_del(bs->offset);
break;
}
} else
goto classerror; goto classerror;
} }
if (tr->op == DECBEF || tr->op == INCBEF) {
C_dup(wordsize); /* ( addr addr -- ) */
C_loi(wordsize); /* ( addr val -- ) */
C_adp((tr->op == DECBEF) ? -1 : 1); /* ( addr newval -- ) */
C_exg(wordsize); /* ( newval addr -- ) */
C_dup(wordsize*2); /* ( newval addr newval addr -- ) */
C_sti(wordsize); /* ( newval addr -- ) */
C_asp(wordsize); /* ( newval -- ) */
} else {
C_dup(wordsize); /* ( addr addr -- ) */
C_loi(wordsize); /* ( addr val -- ) */
C_exg(wordsize); /* ( val addr -- ) */
C_dup(wordsize*2); /* ( val addr val addr -- ) */
C_asp(wordsize); /* ( val addr val -- ) */
C_adp((tr->op == DECAFT) ? -1 : 1); /* ( val addr newval -- ) */
C_exg(wordsize); /* ( val newval addr -- ) */
C_sti(wordsize); /* ( val -- ) */
}
return; return;
case ASSIGN: case ASSIGN: