mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
starting to cache fancy switch values -- fixing issue #171
This commit is contained in:
parent
8ff977dc65
commit
87e60dccf0
5 changed files with 60 additions and 21 deletions
|
@ -355,7 +355,7 @@
|
|||
// parameter identifiers in order to avoid this. Also, parameter lists can
|
||||
// make use of splats.
|
||||
lex.prototype.tag_parameters = function tag_parameters() {
|
||||
var i, tok;
|
||||
var _a, i, tok;
|
||||
if (this.tag() !== ')') {
|
||||
return null;
|
||||
}
|
||||
|
@ -366,11 +366,11 @@
|
|||
if (!tok) {
|
||||
return null;
|
||||
}
|
||||
if (tok[0] === 'IDENTIFIER') {
|
||||
if ((_a = tok[0]) === 'IDENTIFIER') {
|
||||
tok[0] = 'PARAM';
|
||||
} else if (tok[0] === ')') {
|
||||
} else if (_a === ')') {
|
||||
tok[0] = 'PARAM_END';
|
||||
} else if (tok[0] === '(') {
|
||||
} else if (_a === '(') {
|
||||
return (tok[0] = 'PARAM_START');
|
||||
}
|
||||
}
|
||||
|
|
28
lib/nodes.js
28
lib/nodes.js
|
@ -1216,23 +1216,34 @@
|
|||
this.tags.statement = true;
|
||||
return this;
|
||||
},
|
||||
// Rewrite a chain of IfNodes with their switch condition for equality.
|
||||
// Tag a chain of IfNodes with their switch condition for equality.
|
||||
rewrite_condition: function rewrite_condition(expression) {
|
||||
var _a, _b, _c, cond;
|
||||
this.switcher = expression;
|
||||
return this;
|
||||
},
|
||||
// Rewrite a chain of IfNodes with their switch condition for equality.
|
||||
rewrite_switch: function rewrite_switch(o) {
|
||||
var _a, _b, assigner, cond, i, variable;
|
||||
assigner = this.switcher;
|
||||
if (!(this.switcher.unwrap() instanceof LiteralNode)) {
|
||||
variable = new LiteralNode(o.scope.free_variable());
|
||||
assigner = new AssignNode(variable, this.switcher);
|
||||
this.switcher = variable;
|
||||
}
|
||||
this.condition = (function() {
|
||||
if (this.multiple) {
|
||||
_a = []; _b = this.condition;
|
||||
for (_c = 0; _c < _b.length; _c++) {
|
||||
cond = _b[_c];
|
||||
_a.push(new OpNode('is', expression, cond));
|
||||
for (i = 0; i < _b.length; i++) {
|
||||
cond = _b[i];
|
||||
_a.push(new OpNode('is', (i === 0 ? assigner : this.switcher), cond));
|
||||
}
|
||||
return _a;
|
||||
} else {
|
||||
return new OpNode('is', expression, this.condition);
|
||||
return new OpNode('is', assigner, this.condition);
|
||||
}
|
||||
}).call(this);
|
||||
if (this.is_chain()) {
|
||||
this.else_body.rewrite_condition(expression);
|
||||
this.else_body.rewrite_condition(this.switcher);
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
@ -1269,6 +1280,9 @@
|
|||
// force sub-else bodies into statement form.
|
||||
compile_statement: function compile_statement(o) {
|
||||
var body, child, com_dent, cond_o, else_part, if_dent, if_part, prefix;
|
||||
if (this.switcher) {
|
||||
this.rewrite_switch(o);
|
||||
}
|
||||
child = del(o, 'chain_child');
|
||||
cond_o = merge(o);
|
||||
del(cond_o, 'returns');
|
||||
|
|
|
@ -156,22 +156,23 @@
|
|||
brackets = [0];
|
||||
return this.scan_tokens((function(__this) {
|
||||
var __func = function(prev, token, post, i) {
|
||||
if (token[0] === 'CALL_START') {
|
||||
var _i;
|
||||
if ((_i = token[0]) === 'CALL_START') {
|
||||
parens.push(0);
|
||||
} else if (token[0] === 'INDEX_START') {
|
||||
} else if (_i === 'INDEX_START') {
|
||||
brackets.push(0);
|
||||
} else if (token[0] === '(') {
|
||||
} else if (_i === '(') {
|
||||
parens[parens.length - 1] += 1;
|
||||
} else if (token[0] === '[') {
|
||||
} else if (_i === '[') {
|
||||
brackets[brackets.length - 1] += 1;
|
||||
} else if (token[0] === ')') {
|
||||
} else if (_i === ')') {
|
||||
if (parens[parens.length - 1] === 0) {
|
||||
parens.pop();
|
||||
token[0] = 'CALL_END';
|
||||
} else {
|
||||
parens[parens.length - 1] -= 1;
|
||||
}
|
||||
} else if (token[0] === ']') {
|
||||
} else if (_i === ']') {
|
||||
if (brackets[brackets.length - 1] === 0) {
|
||||
brackets.pop();
|
||||
token[0] = 'INDEX_END';
|
||||
|
|
|
@ -970,13 +970,24 @@ IfNode: exports.IfNode: inherit Node, {
|
|||
@tags.statement: true
|
||||
this
|
||||
|
||||
# Rewrite a chain of IfNodes with their switch condition for equality.
|
||||
# Tag a chain of IfNodes with their switch condition for equality.
|
||||
rewrite_condition: (expression) ->
|
||||
@switcher: expression
|
||||
this
|
||||
|
||||
# Rewrite a chain of IfNodes with their switch condition for equality.
|
||||
rewrite_switch: (o) ->
|
||||
assigner: @switcher
|
||||
if not (@switcher.unwrap() instanceof LiteralNode)
|
||||
variable: new LiteralNode(o.scope.free_variable())
|
||||
assigner: new AssignNode(variable, @switcher)
|
||||
@switcher: variable
|
||||
@condition: if @multiple
|
||||
new OpNode('is', expression, cond) for cond in @condition
|
||||
for cond, i in @condition
|
||||
new OpNode('is', (if i is 0 then assigner else @switcher), cond)
|
||||
else
|
||||
new OpNode('is', expression, @condition)
|
||||
@else_body.rewrite_condition(expression) if @is_chain()
|
||||
new OpNode('is', assigner, @condition)
|
||||
@else_body.rewrite_condition(@switcher) if @is_chain()
|
||||
this
|
||||
|
||||
# Rewrite a chain of IfNodes to add a default case as the final else.
|
||||
|
@ -1003,6 +1014,7 @@ IfNode: exports.IfNode: inherit Node, {
|
|||
# Compile the IfNode as a regular if-else statement. Flattened chains
|
||||
# force sub-else bodies into statement form.
|
||||
compile_statement: (o) ->
|
||||
@rewrite_switch(o) if @switcher
|
||||
child: del o, 'chain_child'
|
||||
cond_o: merge o
|
||||
del cond_o, 'returns'
|
||||
|
|
|
@ -29,3 +29,15 @@ ok func(2)
|
|||
ok func(6)
|
||||
ok !func(3)
|
||||
ok !func(8)
|
||||
|
||||
|
||||
# Should cache the switch value, if anything fancier than a literal.
|
||||
num: 5
|
||||
result: switch num += 5
|
||||
when 5 then false
|
||||
when 15 then false
|
||||
when 10 then true
|
||||
else false
|
||||
|
||||
ok result
|
||||
|
||||
|
|
Loading…
Reference in a new issue