Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fixed recursive closure capture, now checks intermediate scopes for v…

…ariable declaration
  • Loading branch information...
commit e7c0599dcd8fa5f1957a6b57e4aaaf61bf2671e1 1 parent cee2f30
@shamanas shamanas authored
View
28 source/rock/middle/FunctionCall.ooc
@@ -360,13 +360,29 @@ FunctionCall: class extends Expression {
while(scopeDepth > 0) {
maybeScope := trail get(scopeDepth, Node)
if(maybeScope instanceOf?(Scope)) {
+ scope := maybeScope as Scope
maybeClosure := trail get(scopeDepth - 1, Node)
- // Make sure the variable we will partial on the top level closure is not one of its arguments
- if(maybeClosure instanceOf?(FunctionDecl) && maybeClosure as FunctionDecl isAnon \
- && !maybeClosure as FunctionDecl args contains?(|arg| arg == ref vDecl || arg name == ref vDecl name + "_generic") \
- && !maybeScope as Scope list contains?(|stmt| stmt instanceOf?(VariableDecl) && stmt as VariableDecl name == ref vDecl name)) {
- // Mark the variable for partialing in the top level closure
- maybeClosure as FunctionDecl markForPartialing(ref vDecl, "v")
+ if(maybeClosure instanceOf?(FunctionDecl)) {
+ closure := maybeClosure as FunctionDecl
+ // Find out if our access is between the kid closure and the parent closure
+ isDefined? := false
+ intermediateScopeIndex := closureIndex - 1
+ while(intermediateScopeIndex > scopeDepth) {
+ interScope? := trail get(intermediateScopeIndex, Node)
+ if(interScope? instanceOf?(Scope)) {
+ interScope := interScope? as Scope
+ if(interScope list contains?(|stmt| stmt instanceOf?(VariableDecl) && stmt as VariableDecl name == name)) {
+ isDefined? = true
+ }
+ }
+ intermediateScopeIndex -= 1
+ }
+ // Only partial the variable in the top function if it has not be defined by it and it is not one of its arguments
+ if(closure isAnon && !closure args contains?(|arg| arg name == ref vDecl name || arg name == ref vDecl name + "_generic") \
+ && !isDefined?) {
+ // Mark the variable for partialing to top level closure
+ closure markForPartialing(ref vDecl, "v")
+ }
}
}
scopeDepth -= 1
View
34 source/rock/middle/VariableAccess.ooc
@@ -249,20 +249,38 @@ VariableAccess: class extends Expression {
if (bOp getLeft() == this && bOp isAssign()) mode = "r"
}
+ // TODO: Abstract this out and use it from FunctionCall.ooc
+ // Also, try to find some better way to do things, maybe from resolveAccess
// Find the first Scope that is the body of a function declaration in the top of the trail
scopeDepth := closureIndex - 1
while(scopeDepth > 0) {
maybeScope := trail get(scopeDepth, Node)
if(maybeScope instanceOf?(Scope)) {
+ scope := maybeScope as Scope
maybeClosure := trail get(scopeDepth - 1, Node)
- // Only partial the variable in the top function if it has not be defined by it and it is not one of its arguments
- if(maybeClosure instanceOf?(FunctionDecl) && maybeClosure as FunctionDecl isAnon \
- && !maybeClosure as FunctionDecl args contains?(|arg| arg name == name || arg name == name + "_generic") \
- && !maybeScope as Scope list contains?(|stmt| stmt instanceOf?(VariableDecl) && stmt as VariableDecl name == name)) {
- // Mark the variable for partialing to top level closure
- maybeClosure as FunctionDecl markForPartialing(ref as VariableDecl, mode)
- if(!maybeClosure as FunctionDecl clsAccesses contains?(this)) {
- maybeClosure as FunctionDecl clsAccesses add(this)
+ if(maybeClosure instanceOf?(FunctionDecl)) {
+ closure := maybeClosure as FunctionDecl
+ // Find out if our access is between the kid closure and the parent closure
+ isDefined? := false
+ intermediateScopeIndex := closureIndex - 1
+ while(intermediateScopeIndex > scopeDepth) {
+ interScope? := trail get(intermediateScopeIndex, Node)
+ if(interScope? instanceOf?(Scope)) {
+ interScope := interScope? as Scope
+ if(interScope list contains?(|stmt| stmt instanceOf?(VariableDecl) && stmt as VariableDecl name == name)) {
+ isDefined? = true
+ }
+ }
+ intermediateScopeIndex -= 1
+ }
+ // Only partial the variable in the top function if it has not be defined by it and it is not one of its arguments
+ if(closure isAnon && !closure args contains?(|arg| arg name == name || arg name == name + "_generic") \
+ && !isDefined?) {
+ // Mark the variable for partialing to top level closure
+ closure markForPartialing(ref as VariableDecl, mode)
+ if(!closure clsAccesses contains?(this)) {
+ closure clsAccesses add(this)
+ }
}
}
}
Please sign in to comment.
Something went wrong with that request. Please try again.