adam-mcdaniel/oakc

Add iterators

Opened this issue · 2 comments

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('\'');
    }
}

I like this idea. Would Range be an internal type or would you actually implement it in oak?

@kevinramharak I would probably implement it in Oak in core.ok, I think. This way its easier for us to hack at it