diff options
author | Mihai Bazon <mihai@bazon.net> | 2012-09-15 16:05:01 +0300 |
---|---|---|
committer | Mihai Bazon <mihai@bazon.net> | 2012-09-15 16:05:17 +0300 |
commit | 4e0262bdfb4097a2d2ff000d38f5c847631f0eb2 (patch) | |
tree | f6e19b28ce920d9b0f3a2f252e0308fe0959e398 /lib | |
parent | 86c14d0988960b5fc52551f143f0ae4361794b4b (diff) | |
download | tracifyjs-4e0262bdfb4097a2d2ff000d38f5c847631f0eb2.tar.gz tracifyjs-4e0262bdfb4097a2d2ff000d38f5c847631f0eb2.zip |
figure out label targets
Diffstat (limited to 'lib')
-rw-r--r-- | lib/ast.js | 4 | ||||
-rw-r--r-- | lib/scope.js | 27 |
2 files changed, 28 insertions, 3 deletions
@@ -287,7 +287,7 @@ var AST_Throw = DEFNODE("Throw", null, { $documentation: "A `throw` statement" }, AST_Exit); -var AST_LoopControl = DEFNODE("LoopControl", "label", { +var AST_LoopControl = DEFNODE("LoopControl", "label loopcontrol_target", { $documentation: "Base class for loop control statements (`break` and `continue`)", _walk: function(visitor) { return visitor._visit(this, this.label && function(){ @@ -614,7 +614,7 @@ var AST_SymbolCatch = DEFNODE("SymbolCatch", null, { $documentation: "Symbol naming the exception in catch", }, AST_SymbolDeclaration); -var AST_Label = DEFNODE("Label", null, { +var AST_Label = DEFNODE("Label", "label_target", { $documentation: "Symbol naming a label (declaration)", }, AST_SymbolDeclaration); diff --git a/lib/scope.js b/lib/scope.js index ef0ac6ed..79d6e91d 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -101,8 +101,28 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(){ } if (node instanceof AST_Label) { node.init_scope_vars(); + var p = tw.parent(); // AST_LabeledStatement + var block = p.body; + if (block instanceof AST_StatementWithBody) + block = block.body; + node.label_target = block; } - if (node instanceof AST_SymbolLambda) { + if (node instanceof AST_LoopControl) { + if (!node.label) { + var a = tw.stack, i = a.length - 1; + while (--i >= 0) { + var p = a[i]; + if (p instanceof AST_For + || p instanceof AST_ForIn + || p instanceof AST_DWLoop + || p instanceof AST_Switch) { + node.loopcontrol_target = p.body; + break; + } + } + } + } + else if (node instanceof AST_SymbolLambda) { scope.def_function(node); } else if (node instanceof AST_SymbolDefun) { @@ -272,6 +292,11 @@ AST_Symbol.DEFMETHOD("global", function(){ return this.definition().global; }); +AST_LoopControl.DEFMETHOD("target", function(){ + if (this.label) return this.label.definition().label_target; + return this.loopcontrol_target; +}); + AST_Toplevel.DEFMETHOD("mangle_names", function(){ // We only need to mangle declaration nodes. Special logic wired // into the code generator will display the mangled name if it's |