Skip to content

Smart for loop#585

Closed
tomblind wants to merge 21 commits intomasterfrom
smart-for-loop
Closed

Smart for loop#585
tomblind wants to merge 21 commits intomasterfrom
smart-for-loop

Conversation

@tomblind
Copy link
Copy Markdown
Collaborator

@tomblind tomblind commented May 18, 2019

Allows certain for loops to be transpiled as lua numerical for loops.

for (let i = 0; i < limit; ++i) {}

=>

for i = 0, limit - 1 do
end
  • i must be declared with let and not modified inside the loop body
  • condition must be one of:
    • i < limit or i <= limit for forward (addition) loops
    • i > limit or i >= limit for reverse (subtraction) loops
  • limit must be either:
    • a const or number literal, when condition uses <= or >=
    • a whole number literal, when condition uses < or > (to avoid issues with offsetting)
  • the incrementor must be one of:
    • unary increment or decrement (++i, --i, etc...)
    • compound assignment addition or subtraction (i += x or i -= x)
    • assignment to addition or subtraction operation using same variable (i = i + x or i = i - x)

There is also support for a special case:

for (let i = 0, limit = x; i < limit; ++i) {}

=>

for i = 0, x - 1 do
end

Since this is a common paradigm in (oldschool) javscript, it seemed like a good thing to support. Note that it will only be transpiled as a numerical for if the limit variable is not referenced in the the loop body at all.

Also included in this PR:

  • for...of loops over arrays now use ipairs instead of a numerical lua for loop
  • dis-allowed object destructuring in for...of loops (this silently produced bad code before)
  • fixed issues with source mappings of lua for...in statements

Also fixed scoping issue with for loops which transpile to lua while statements
Prevented use of numerical for loops when the loop variable is modified in the loops body. This is done by
tracking symbols that are assigned in scopes and checking that when deciding how to transpile the for statement.
also:
- added checking for object destructuring in for...of
- fixed lua for...in in source maps
@tomblind
Copy link
Copy Markdown
Collaborator Author

I'm taking this out of draft as I'm not seeing any ways to simplify/clarify the code any better.

@tomblind tomblind marked this pull request as ready for review May 20, 2019 13:29
@ark120202
Copy link
Copy Markdown
Contributor

Offset limit when using < or > is always 1 now, but it should be equal to increment:

for (let i = 0; i < 2; i += 0.5) {
    console.log(i); // 0 0.5 1 1.5
}
for i = 0, 1, 0.5 do
    print(i) -- 0 0.5 1
end

@tomblind
Copy link
Copy Markdown
Collaborator Author

After looking at this more closely, setting the offset to the step value only works in certain situations.

for (let i = 0; i < 1; i += 0.3) {
    console.log(i); // 0, 0.3, 0.6, 0.9
}
for i = 0, 1 - 0.3, 0.3 do
    print(i) -- 0, 0.3, 0.6
end

@tomblind
Copy link
Copy Markdown
Collaborator Author

For now, I'm dis-allowing optimization on loops using < or > that don't have a whole number literal as a step value.

@ark120202
Copy link
Copy Markdown
Contributor

True, what about using epsilon?

for i = 0, 1 - 2.220446049250313e-16, 0.3 do
    print(i) -- 0, 0.3, 0.6, 0.9
end

for i = 0, 2 - 2.220446049250313e-16, 0.5 do
    print(i) -- 0, 0.5, 1, 1.5
end

@tomblind
Copy link
Copy Markdown
Collaborator Author

I considered that, but any value we use could have precision issues in some lua implementations. It's too bad lua doesn't have a built in const for that like math.huge

tomblind added a commit that referenced this pull request May 25, 2019
Extracted from #585
Also includes:
- Throwing error on attempts to use object destructuring in for...of loops
- Fixed issue with sourcemaps in lua for...in loops
@tomblind
Copy link
Copy Markdown
Collaborator Author

Closing as implicit optimization is out of scope of the main TSTL project. This is better done as a plugin.

@tomblind tomblind closed this May 25, 2019
tomblind added a commit that referenced this pull request May 26, 2019
Extracted from #585
Also includes:
- Throwing error on attempts to use object destructuring in for...of loops
- Fixed issue with sourcemaps in lua for...in loops
@Perryvw Perryvw deleted the smart-for-loop branch July 14, 2019 18:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants