ceu-lang / ceu

The Programming Language Céu

Home Page:http://www.ceu-lang.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Over/Underflow in closed vector limits

fsantanna opened this issue · comments

The runtime decrements the starting limit 0[:

var int ret = 1;
var u8 i;
loop i in [0->0[ do
    ret = ret + 1;
end
escape ret;

This bug is not specific to u8, u16 or even u32 or restricted to unsigned types. The current logic is utterly flawed, e.g. try [0->253[, 50 or step 250 for fun.

Here is how Céu could generate a different kind of loop expansion. I'm making use of the excellent overflow detection API introduced with GCC version 5. LLVM supports it too.

int main() {
	unsigned int ret = 0;
	unsigned char start = 0, stop = 0, step = 1;
	assert(step > 0); // says the Céu manual
	for ( ; start < stop // Use either < with [a -> b[ or <= with [a -> b]
	      ; ({if (__builtin_add_overflow(start,step,&start)) goto end;})) {
		// for() supports both break; and continue; statements.
		printf(" ..%u", start);
		ret = ret + 1;
	}
  end: // gensym this label, of course
	printf(" ->%u\n", ret);
	return 0;
}

Conversely, a descending loop [ <- ] would use __builtin_sub_overflow().

I'm using another GCC extension, namely ({ statements as expressions }) so that the complete step fits for(;;step) syntax. That allows to support continue; statements within the loop. Céu actually doesn't need that because it compiles Céu break and continue statements to C goto expressions; but well, I thought: "What if the user writes { continue; } as a C escape inside one Céu loop?".

It's good that ceu-maker 0.40 updated the embedded Arduino package from 1.8.3 to 1.8.8. The old one contains avr-gcc version 4.9.2; however GCC did not support __builtin_add_overflow until GCC 5.x. The new package contains GCC 5.4.0.
Overflow detection could be written without these helper functions, but it's touch to get right (avoiding undefined behaviour in C with signed overflow) and there are many different cases to consider (unsigned vs. s8/s16/s32, addition and substraction).