Closed davidhesselbom closed 8 years ago
ping @shamanas
I'll take a look at this today (read the mailing list too)
On a somewhat unrelated note, it would be cool if you could make ranges run backwards, like this:
for (i in 5 .. 0)
println(i toString())
but I suppose there are reasons why that would be a bad idea.
@davidhesselbom there's a bunch of stuff in the SDK to do backward/reverse iteration, cf. https://github.com/fasterthanlime/rock/blob/94362e9ee6f7cda1f8ffdcda5636c5ed0ad40c3d/sdk/lang/Iterators.ooc
Using iterators, yes, but I'd prefer not to use them (iirc, unfixable memory leaks when no gc, but not sure). Thanks for the suggestion, though.
For loops only seem to handle range literal collections as an edge-case, changing this to any expression of type Range should be trivial (I think?).
should be trivial
famous last words :tm: but you're the maintainer :) go ahead.
I've got a version that is 99% of the way there but for some reason it generates both a correct index variable vdecl and an incorrect one that makes rock choke T_T
They say 90% of the time is spent on the last 10% of the job, so by extension, that means 81% of the development time remains? :P
Seems accurate to me, although the time I've spent so far is minimal anyway :)
I'll try to finish this off now, add a couple of tests and then move on to the cover member assignment bug.
@davidhesselbom You beat me to say that by 10 minutes.
For some reason a foreach loop adds it's index variable vdecl in a scope before it, so when I do my hackish replacement of a range collection with a range literal, I generate a secon vdecl and the first one is unresolvable.
The problem is the fact that I can't find the code that actually adds the vDecl before the for loop (although the code that generates the decl is obvious)
@shamanas
I haven't read all the discussion, but if you mean Foreach variable
,
I think it is added to parent scope while being resolved.
In middle/VariableDecl.ooc: 230 ~
if(!parent isScope() && !parent instanceOf?(TypeDecl) && !parent instanceOf?(FuncType)) {
This part try to unwrap variable decl to its parent scope. Maybe it is mainly designed for things like
while ( a := get_next() )
The debug loop information also shows than i
is unwrapped while resolving
Resolving variable decl i: Int
For i: Int, resolving type Int, of type BaseType
Done resolving the type, ref = CoverDecl Int
info wholeAgain 'because parent isn't scope nor typedecl, unwrapped' for i: Int (of type VariableDecl)
for (i in 0..10 ){
Response of statement [Foreach] for (i in RangeLiteral) = LOOP
response of body = LOOP
@zhaihj
Thank you, I couldn't figure out where it was added to the parent scope (I assumed Foreach was doing it), this still leaves things a bit complicated but I suppose I can go up the trail and fetch the declaration :)
That was going to be my solution anyway but it frustrated me too much I couldn't find where the variable was unwrapped, since it is done in VariableDecl.ooc I think it is the correct solution.
By the way @fasterthanlime the C backend seems to be making the index variable iterate over the same range as the foreach variable (for range foreaches).
Here is some generated code:
// Should be:
// for (i = test__range.min, j = 0; i < test__range.max; i++, j++) {
for (i = test__range.min, j = test__range.min; i < test__range.max; i++, j++) {
}
From:
range := 10 .. 15
for ((j, i) in range) {
}
This doesn't build, because
What if rock could pre-process this into
(which does work) so you wouldn't have to spell it out? As far as I can tell, a new
Range
is created with this syntax anyway.