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