-
Notifications
You must be signed in to change notification settings - Fork 24
Open
Description
Dear @davidgiven, thank you for developing that language, that's very enjoyable and interesting!
Reading some code in, e.g. strings.coh, I noticed that you often use "loop+break" idioms, and rarely rely on "while loop invariants", for example:
sub StrLen(s: [uint8]): (size: intptr) is
var p := s;
loop
var c := [p];
if c == 0 then
break;
end if;
p := p + 1;
end loop;
size := p - s;
end loop;
end sub;
could also be written as:
sub StrLen(s: [uint8]): (size: intptr) is
var p := s;
# invariant: forall x in [s..p[: [x] != 0
while [p] != 0 loop
# here we know that [s..p[ != 0 (invariant) and [p] != 0 (loop condition)
# so it's safe to increase p and consider [s..p[ != 0 (invariant is restored)
p := @next p;
end loop;
size := p - s;
end sub;
Maybe the underlying assembly is easier to generate with breaks?
Another thought is that some loop condition can be really terrible as with StrICmp (not sure about syntax errors, I'm just starting to learn the language):
sub StrICmp(s1: [uint8], s2: [uint8]): (res: int8) is
while ((ToLower([s1]) - ToLower([s2])) == 0) and ([s1] != 0) loop
s1 := @next s1;
s2 := @next s2;
end loop;
# if [s1] = 0 we reached the end of the strings (second condition),
# otherwise the strings are different (first condition)
res := [s1] as int8;
end sub;
EDIT: the last res value is wrong here as s1 can be shorter than s2. Therefore another computation is needed and this is avoided with the "break template". Maybe that's a fair enough reason to keep breaks :)
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels