diff options
Diffstat (limited to 'lib/compress.js')
-rw-r--r-- | lib/compress.js | 42 |
1 files changed, 40 insertions, 2 deletions
diff --git a/lib/compress.js b/lib/compress.js index 96047291..f8f4d17f 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -184,11 +184,45 @@ function Compressor(options, false_by_default) { } while (CHANGED); return statements; + /// XXX: this function is UGLY and kinda wrong. + /// I think it would be cleaner if it operates backwards. function handle_if_return(statements, compressor) { - var in_lambda = compressor.self() instanceof AST_Lambda; + var self = compressor.self(); + var in_lambda = self instanceof AST_Lambda; var last = statements.length - 1; return MAP(statements, function(stat, i){ if (stat instanceof AST_If + && stat.body instanceof AST_Continue + && !stat.alternative + && self === stat.body.target()) { + CHANGED = true; + if (i < last) { + var rest = statements.slice(i + 1); + var cond = stat.condition; + while (rest[0] instanceof AST_If + && rest[0].body instanceof AST_Continue + && self === rest[0].body.target() + && !rest[0].alternative) { + cond = make_node(AST_Binary, rest[0], { + operator: "||", + left: cond, + right: rest[0].condition + }); + rest.shift(); + } + return MAP.last(make_node(AST_If, stat, { + condition: cond.negate(compressor), + body: make_node(AST_BlockStatement, stat, { + body: rest + }).optimize(compressor) + }).optimize(compressor)) + } else { + return make_node(AST_SimpleStatement, stat, { + body: stat.condition + }).optimize(compressor); + } + } + if (stat instanceof AST_If && stat.body instanceof AST_Return && !stat.alternative && in_lambda) { @@ -199,6 +233,7 @@ function Compressor(options, false_by_default) { var cond = stat.condition; while (rest[0] instanceof AST_If && rest[0].body instanceof AST_Return + && !rest[0].body.value && !rest[0].alternative) { cond = make_node(AST_Binary, rest[0], { operator: "||", @@ -645,7 +680,10 @@ function Compressor(options, false_by_default) { (function(def){ def(AST_StatementBase, function(){ return null }); def(AST_Jump, function(){ return this }); - def(AST_BlockStatement, function(){ return this.body[this.body.length - 1].aborts() }); + def(AST_BlockStatement, function(){ + var n = this.body.length; + return n > 0 && this.body[n - 1].aborts(); + }); })(function(node, func){ node.DEFMETHOD("aborts", func); }); |