fixed label scope/mangling
authorMihai Bazon <mihai@bazon.net>
Tue, 18 Sep 2012 16:26:46 +0000 (19:26 +0300)
committerMihai Bazon <mihai@bazon.net>
Tue, 18 Sep 2012 16:26:46 +0000 (19:26 +0300)
lib/ast.js
lib/scope.js

index 5c4b7e6..6e05a39 100644 (file)
@@ -614,7 +614,7 @@ var AST_SymbolCatch = DEFNODE("SymbolCatch", null, {
     $documentation: "Symbol naming the exception in catch",
 }, AST_SymbolDeclaration);
 
-var AST_Label = DEFNODE("Label", "label_target", {
+var AST_Label = DEFNODE("Label", "references label_target", {
     $documentation: "Symbol naming a label (declaration)",
 }, AST_SymbolDeclaration);
 
index f8d3ac5..0e615eb 100644 (file)
@@ -105,6 +105,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(){
             node.scope = scope;
         }
         if (node instanceof AST_Label) {
+            node.thedef = node;
             node.init_scope_vars();
             var p = tw.parent(); // AST_LabeledStatement
             var block = p.body;
@@ -152,8 +153,12 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(){
         }
         if (node instanceof AST_LabelRef) {
             var sym = labels[node.name];
-            if (!sym) throw new Error("Undefined label " + node.name);
-            node.reference(sym);
+            if (!sym) throw new Error(string_template("Undefined label {name} [{line},{col}]", {
+                name: node.name,
+                line: node.start.line,
+                col: node.start.col
+            }));
+            node.thedef = sym;
         }
     });
     self.walk(tw);
@@ -169,6 +174,10 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(){
             func = prev_func;
             return true;
         }
+        if (node instanceof AST_LabelRef) {
+            node.reference();
+            return true;
+        }
         if (node instanceof AST_SymbolRef) {
             var name = node.name;
             var sym = node.scope.find_variable(name);
@@ -227,9 +236,8 @@ AST_Label.DEFMETHOD("init_scope_vars", function(){
     this.references = [];
 });
 
-AST_LabelRef.DEFMETHOD("reference", function(def){
-    this.thedef = def;
-    def.references.push(this);
+AST_LabelRef.DEFMETHOD("reference", function(){
+    this.thedef.references.push(this);
 });
 
 AST_Scope.DEFMETHOD("find_variable", function(name){