Add iterators
Opened this issue · 2 comments
adam-mcdaniel commented
Right now, for loops look like the following:
for (let i=0; i<10; i+=1) { ... }
// or
for i in 0..10 { ... }
Although these look different, they are identical after TIR. I think the first for loop should stay the same, but the second should change. Instead of being expanded to for (let i=0; i<10; i+=1) {...}
, it should be expanded to something like
// Replace 1 with however many for loops have preceded this one, so that the variables don't clobber each other in nested loops
let %FOR_ITER_1% = Range::new(0, 10);
for (let i = %FOR_ITER_1%.next(); !(itr.is_done()); i=%FOR_ITER_1%.next()) { ... }
Additionally, this compile time expansion would allow any type that has a next
and is_done
method to be an iterator for a loop.
#[std]
const EOF = 0;
struct Input {
let last: char;
fn stdin() -> Input { return ' ' as Input }
fn next(self: &Input) -> char {
self->last = get_char();
return self->last;
}
fn is_done(self: &Input) -> bool { return self->last == EOF as char }
}
fn main() {
for ch in Input::stdin() {
putstr("Got char '");
putchar(ch);
putcharln('\'');
}
}
kevinramharak commented
I like this idea. Would Range
be an internal type or would you actually implement it in oak?
adam-mcdaniel commented
@kevinramharak I would probably implement it in Oak in core.ok
, I think. This way its easier for us to hack at it