figure out label targets
This commit is contained in:
@@ -287,7 +287,7 @@ var AST_Throw = DEFNODE("Throw", null, {
|
|||||||
$documentation: "A `throw` statement"
|
$documentation: "A `throw` statement"
|
||||||
}, AST_Exit);
|
}, 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`)",
|
$documentation: "Base class for loop control statements (`break` and `continue`)",
|
||||||
_walk: function(visitor) {
|
_walk: function(visitor) {
|
||||||
return visitor._visit(this, this.label && function(){
|
return visitor._visit(this, this.label && function(){
|
||||||
@@ -614,7 +614,7 @@ var AST_SymbolCatch = DEFNODE("SymbolCatch", null, {
|
|||||||
$documentation: "Symbol naming the exception in catch",
|
$documentation: "Symbol naming the exception in catch",
|
||||||
}, AST_SymbolDeclaration);
|
}, AST_SymbolDeclaration);
|
||||||
|
|
||||||
var AST_Label = DEFNODE("Label", null, {
|
var AST_Label = DEFNODE("Label", "label_target", {
|
||||||
$documentation: "Symbol naming a label (declaration)",
|
$documentation: "Symbol naming a label (declaration)",
|
||||||
}, AST_SymbolDeclaration);
|
}, AST_SymbolDeclaration);
|
||||||
|
|
||||||
|
|||||||
27
lib/scope.js
27
lib/scope.js
@@ -101,8 +101,28 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(){
|
|||||||
}
|
}
|
||||||
if (node instanceof AST_Label) {
|
if (node instanceof AST_Label) {
|
||||||
node.init_scope_vars();
|
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);
|
scope.def_function(node);
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_SymbolDefun) {
|
else if (node instanceof AST_SymbolDefun) {
|
||||||
@@ -272,6 +292,11 @@ AST_Symbol.DEFMETHOD("global", function(){
|
|||||||
return this.definition().global;
|
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(){
|
AST_Toplevel.DEFMETHOD("mangle_names", function(){
|
||||||
// We only need to mangle declaration nodes. Special logic wired
|
// We only need to mangle declaration nodes. Special logic wired
|
||||||
// into the code generator will display the mangled name if it's
|
// into the code generator will display the mangled name if it's
|
||||||
|
|||||||
Reference in New Issue
Block a user