@@ -102,14 +102,15 @@ exports.Base = class Base
102
102
# If `level` is passed, then returns `[val, ref]`, where `val` is the compiled value, and `ref`
103
103
# is the compiled reference. If `level` is not passed, this returns `[val, ref]` where
104
104
# the two values are raw nodes which have not been compiled.
105
- cache : (o , level , reused ) ->
106
- unless @ isComplex ()
107
- ref = if level then @ compileToFragments o, level else this
108
- [ref, ref]
109
- else
110
- ref = new Literal reused or o .scope .freeVariable ' ref'
105
+ cache : (o , level , isComplex ) ->
106
+ complex = if isComplex? then isComplex this else @ isComplex ()
107
+ if complex
108
+ ref = new Literal o .scope .freeVariable ' ref'
111
109
sub = new Assign ref, this
112
110
if level then [sub .compileToFragments (o, level), [@ makeCode (ref .value )]] else [sub, ref]
111
+ else
112
+ ref = if level then @ compileToFragments o, level else this
113
+ [ref, ref]
113
114
114
115
cacheToCodeFragments : (cacheValues ) ->
115
116
[fragmentsToText (cacheValues[0 ]), fragmentsToText (cacheValues[1 ])]
@@ -793,9 +794,10 @@ exports.Range = class Range extends Base
793
794
# But only if they need to be cached to avoid double evaluation.
794
795
compileVariables : (o ) ->
795
796
o = merge o, top : true
796
- [@fromC , @fromVar ] = @ cacheToCodeFragments @from .cache o, LEVEL_LIST
797
- [@toC , @toVar ] = @ cacheToCodeFragments @to .cache o, LEVEL_LIST
798
- [@step , @stepVar ] = @ cacheToCodeFragments step .cache o, LEVEL_LIST if step = del o, ' step'
797
+ isComplex = del o, ' isComplex'
798
+ [@fromC , @fromVar ] = @ cacheToCodeFragments @from .cache o, LEVEL_LIST, isComplex
799
+ [@toC , @toVar ] = @ cacheToCodeFragments @to .cache o, LEVEL_LIST, isComplex
800
+ [@step , @stepVar ] = @ cacheToCodeFragments step .cache o, LEVEL_LIST, isComplex if step = del o, ' step'
799
801
[@fromNum , @toNum ] = [@fromVar .match (NUMBER), @toVar .match (NUMBER)]
800
802
@stepNum = @stepVar .match (NUMBER) if @stepVar
801
803
@@ -1971,15 +1973,16 @@ exports.For = class For extends While
1971
1973
kvar = (@range and name) or index or ivar
1972
1974
kvarAssign = if kvar isnt ivar then " #{ kvar} = " else " "
1973
1975
if @step and not @range
1974
- [step , stepVar ] = @ cacheToCodeFragments @step .cache o, LEVEL_LIST
1976
+ [step , stepVar ] = @ cacheToCodeFragments @step .cache o, LEVEL_LIST, isComplexOrAssignable
1975
1977
stepNum = stepVar .match NUMBER
1976
1978
name = ivar if @pattern
1977
1979
varPart = ' '
1978
1980
guardPart = ' '
1979
1981
defPart = ' '
1980
1982
idt1 = @tab + TAB
1981
1983
if @range
1982
- forPartFragments = source .compileToFragments merge (o, {index : ivar, name, @step })
1984
+ forPartFragments = source .compileToFragments merge o,
1985
+ {index : ivar, name, @step , isComplex : isComplexOrAssignable}
1983
1986
else
1984
1987
svar = @source .compile o, LEVEL_LIST
1985
1988
if (name or @own ) and not IDENTIFIER .test svar
@@ -2291,6 +2294,8 @@ isLiteralThis = (node) ->
2291
2294
(node instanceof Code and node .bound ) or
2292
2295
(node instanceof Call and node .isSuper )
2293
2296
2297
+ isComplexOrAssignable = (node ) -> node .isComplex () or node .isAssignable ? ()
2298
+
2294
2299
# Unfold a node's child if soak, then tuck the node under created `If`
2295
2300
unfoldSoak = (o , parent , name ) ->
2296
2301
return unless ifn = parent[name].unfoldSoak o
0 commit comments