MOO-cows Mailing List Archive
[Prev][Next][Index][Thread]
Patch for ALPHA release 1.8.0alpha6 of LambdaMOO
The following patch fixes a very nasty set of bugs in the implementation of the
new scattering assignment facility. In the function run() in execute.c, at
about line 1580, replace this entire case for EOP_SCATTER:
-------------------------------------------------------------------------------
case EOP_SCATTER:
{
int nargs = READ_BYTES(bv, 1);
int nreq = READ_BYTES(bv, 1);
int rest = READ_BYTES(bv, 1);
int have_rest = (rest > nargs ? 0 : 1);
Var list;
int len, nopt_avail, nrest, i, offset;
int done, where = 0;
list = TOP_RT_VALUE;
len = list.v.list[0].v.num;
if (len < nreq || (!have_rest && len > nargs)) {
free_var(POP()); /* replace list with error code */
PUSH_ERROR(E_ARGS);
} else {
nopt_avail = len - nreq;
nrest = (have_rest && len >= nargs ? len - nargs + 1
: 0);
for (offset = 0, i = 1; i <= nargs; i++) {
int id = READ_BYTES(bv, bc.numbytes_var_name);
int label = READ_BYTES(bv, bc.numbytes_label);
if (i == rest) { /* rest */
free_var(RUN_ACTIV.rt_env[id]);
RUN_ACTIV.rt_env[id] = sublist(var_ref(list),
i,
i + nrest - 1);
offset += nrest - 1;
} else if (label == 0) { /* required */
free_var(RUN_ACTIV.rt_env[id]);
RUN_ACTIV.rt_env[id] =
var_ref(list.v.list[i + offset]);
} else { /* optional */
if (nopt_avail > 0) {
nopt_avail--;
free_var(RUN_ACTIV.rt_env[id]);
RUN_ACTIV.rt_env[id] =
var_ref(list.v.list[i + offset]);
} else {
offset--;
if (where == 0 && label != 1)
where = label;
}
}
}
done = READ_BYTES(bv, bc.numbytes_label);
if (where == 0)
JUMP(done);
else
JUMP(where);
}
}
break;
-------------------------------------------------------------------------------
with the following new version:
-------------------------------------------------------------------------------
case EOP_SCATTER:
{
int nargs = READ_BYTES(bv, 1);
int nreq = READ_BYTES(bv, 1);
int rest = READ_BYTES(bv, 1);
int have_rest = (rest > nargs ? 0 : 1);
Var list;
int len = 0, nopt_avail, nrest, i, offset;
int done, where = 0;
enum error e = E_NONE;
list = TOP_RT_VALUE;
if (list.type != TYPE_LIST)
e = E_TYPE;
else if ((len = list.v.list[0].v.num) < nreq
|| (!have_rest && len > nargs))
e = E_ARGS;
if (e != E_NONE) { /* skip rest of operands */
free_var(POP()); /* replace list with error code */
PUSH_ERROR(e);
for (i = 1; i <= nargs; i++) {
READ_BYTES(bv, bc.numbytes_var_name);
READ_BYTES(bv, bc.numbytes_label);
}
} else {
nopt_avail = len - nreq;
nrest = (have_rest && len >= nargs ? len - nargs + 1
: 0);
for (offset = 0, i = 1; i <= nargs; i++) {
int id = READ_BYTES(bv, bc.numbytes_var_name);
int label = READ_BYTES(bv, bc.numbytes_label);
if (i == rest) { /* rest */
free_var(RUN_ACTIV.rt_env[id]);
RUN_ACTIV.rt_env[id] = sublist(var_ref(list),
i,
i + nrest - 1);
offset += nrest - 1;
} else if (label == 0) { /* required */
free_var(RUN_ACTIV.rt_env[id]);
RUN_ACTIV.rt_env[id] =
var_ref(list.v.list[i + offset]);
} else { /* optional */
if (nopt_avail > 0) {
nopt_avail--;
free_var(RUN_ACTIV.rt_env[id]);
RUN_ACTIV.rt_env[id] =
var_ref(list.v.list[i + offset]);
} else {
offset--;
if (where == 0 && label != 1)
where = label;
}
}
}
}
done = READ_BYTES(bv, bc.numbytes_label);
if (where == 0)
JUMP(done);
else
JUMP(where);
}
break;
-------------------------------------------------------------------------------
This should fix the major problems recently reported on the MOO-Cows list.
Pavel
Home |
Subject Index |
Thread Index