rgbds icon indicating copy to clipboard operation
rgbds copied to clipboard

`FOR` loops have some unexpected edge cases

Open Rangi42 opened this issue 3 years ago • 1 comments

As mentioned in #1003.

FOR x, $8000_0000, $6000_0000, $4000_0000
  PRINTLN x
ENDR
PRINTLN x

This prints $80000000 and then $C0000000.

FOR x, $80000000, $70000000, $44000000
  PRINTLN x
ENDR
PRINTLN x

This prints $80000000 and then $C4000000.

Rangi42 avatar Aug 28 '22 19:08 Rangi42

Arguably the documentation should clarify how FOR behaves with overflow, but it's not actually different from how anything else behaves with overflow, so maybe there should just be a section noting that numbers are internally 32-bit signed two's complement.

Rangi42 avatar Aug 28 '22 19:08 Rangi42

The logic of FOR loops, from fstack.c:

	/// Values specified by the FOR loop in asm:
	/// int32_t start, int32_t stop, int32_t step

	uint32_t count = 0;

	if (step > 0 && start < stop)
		count = (stop - start - 1) / step + 1;
	else if (step < 0 && stop < start)
		count = (start - stop - 1) / -step + 1;
	else if (step == 0)
		error("FOR cannot have a step value of 0\n");

	if ((step > 0 && start > stop) || (step < 0 && start < stop))
		warning(WARNING_BACKWARDS_FOR, "FOR goes backwards from %d to %d by %d\n",
			start, stop, step);

	/// The FOR loop will run for `count` iterations (possibly zero), starting
	/// at `start` and adding `step` to it at the end of each iteration.

Rangi42 avatar Sep 26 '22 14:09 Rangi42