src: cleanup importations
[nit.git] / src / scope.nit
index 95e4d4a..83c5fe4 100644 (file)
 # Identification and scping of local variables and labels.
 module scope
 
-import parser
-import toolcontext
+import phase
+
+redef class ToolContext
+       var scope_phase: Phase = new ScopePhase(self, null)
+end
+
+private class ScopePhase
+       super Phase
+       redef fun process_npropdef(npropdef) do npropdef.do_scope(toolcontext)
+end
+
 
 # A local variable (including parameters, automatic variables and self)
 class Variable
        # The name of the variable (as used in the program)
        var name: String
 
-       # Alias of `name'
+       # Alias of `name`
        redef fun to_s do return self.name
 end
 
-# A local variable associated to a closure definition
-class ClosureVariable
-       super Variable
-end
-
 # Mark where break and continue will branch.
 # Marks are either associated with a label of with a for_loop structure
 class EscapeMark
        # The name of the label (unless the mark is an anonymous loop mark)
        var name: nullable String
 
-       # Is the mark atached to a loop (loop, while, for, closure)
+       # Is the mark atached to a loop (loop, while, for)
        # Such a mark is a candidate to a labelless 'continue' or 'break'
        var for_loop: Bool
 
@@ -52,10 +56,9 @@ class EscapeMark
 end
 
 # Visit a npropdef and:
-#  * Identify variables, closures and labels
+#  * Identify variables and labels
 #  * Associate each break and continue to its escapemark
-#  * Transform ACallFormExpr that access a variable into AVarFormExpr
-#  * Transform ACallFormExpr that call a closure into AClosureCallExpr
+#  * Transform `ACallFormExpr` that access a variable into `AVarFormExpr`
 # FIXME: Should the class be private?
 private class ScopeVisitor
        super Visitor
@@ -71,7 +74,7 @@ private class ScopeVisitor
                scopes.add(new Scope)
        end
 
-       # All stacked scope. `scopes.first' is the current scope
+       # All stacked scope. `scopes.first` is the current scope
        private var scopes: List[Scope] = new List[Scope]
 
        # Regiter a local variable.
@@ -88,7 +91,7 @@ private class ScopeVisitor
                return true
        end
 
-       # Look for a variable named `name'.
+       # Look for a variable named `name`.
        # Return null if no such a variable is found.
        fun search_variable(name: String): nullable Variable
        do
@@ -101,13 +104,13 @@ private class ScopeVisitor
                return null
        end
 
-       redef fun visit(n: nullable ANode)
+       redef fun visit(n)
        do
                n.accept_scope_visitor(self)
        end
 
-       # Enter in a statement block `node' as inside a new scope.
-       # The block can be optionally attached to an `escapemark'.
+       # Enter in a statement block `node` as inside a new scope.
+       # The block can be optionally attached to an `escapemark`.
        private fun enter_visit_block(node: nullable AExpr, escapemark: nullable EscapeMark)
        do
                if node == null then return
@@ -118,7 +121,7 @@ private class ScopeVisitor
                scopes.shift
        end
 
-       # Look for a label `name'.
+       # Look for a label `name`.
        # Return nulll if no such a label is found.
        private fun search_label(name: String): nullable EscapeMark
        do
@@ -135,13 +138,21 @@ private class ScopeVisitor
        # Display an error on toolcontext if a label with the same name is masked.
        private fun make_escape_mark(nlabel: nullable ALabel, for_loop: Bool): EscapeMark
        do
-               assert named_or_for_loop: nlabel != null or for_loop
                var name: nullable String
                if nlabel != null then
-                       name = nlabel.n_id.text
-                       var found = self.search_label(name)
-                       if found != null then
-                               self.error(nlabel, "Syntax error: label {name} already defined.")
+                       var nid = nlabel.n_id
+                       if nid == null then
+                               var res = search_label("")
+                               if res != null then
+                                       self.error(nlabel, "Syntax error: anonymous label already defined.")
+                               end
+                               name = ""
+                       else
+                               name = nid.text
+                               var found = self.search_label(name)
+                               if found != null then
+                                       self.error(nlabel, "Syntax error: label {name} already defined.")
+                               end
                        end
                else
                        name = null
@@ -152,13 +163,22 @@ private class ScopeVisitor
 
        # Look for an escape mark optionally associated with a label.
        # If a label is given, the the escapemark of this label is returned.
-       # If there is no label, the nearest escapemark that is `for loop' ir returned.
+       # If there is no label, the nearest escapemark that is `for loop` is returned.
        # If there is no valid escapemark, then an error is displayed ans null is returned.
        # Return nulll if no such a label is found.
        private fun get_escapemark(node: ANode, nlabel: nullable ALabel): nullable EscapeMark
        do
                if nlabel != null then
-                       var name = nlabel.n_id.text
+                       var nid = nlabel.n_id
+                       if nid == null then
+                               var res = search_label("")
+                               if res == null then
+                                       self.error(nlabel, "Syntax error: invalid anonymous label.")
+                                       return null
+                               end
+                               return res
+                       end
+                       var name = nid.text
                        var res = search_label(name)
                        if res == null then
                                self.error(nlabel, "Syntax error: invalid label {name}.")
@@ -168,7 +188,7 @@ private class ScopeVisitor
                else
                        for scope in scopes do
                                var res = scope.escapemark
-                               if res != null and res.for_loop then
+                               if res != null then
                                        return res
                                end
                        end
@@ -228,18 +248,6 @@ redef class AParam
        end
 end
 
-redef class AClosureDecl
-       # The variable associated with the closure declaration
-       var variable: nullable ClosureVariable
-       redef fun accept_scope_visitor(v)
-       do
-               var nid = self.n_id
-               var variable = new ClosureVariable(nid.text)
-               v.register_variable(nid, variable)
-               self.variable = variable
-       end
-end
-
 redef class AVardeclExpr
        # The variable associated with the variable declaration
        var variable: nullable Variable
@@ -298,9 +306,7 @@ redef class ADoExpr
        var escapemark: nullable EscapeMark
        redef fun accept_scope_visitor(v)
        do
-               if n_label != null then
-                       self.escapemark = v.make_escape_mark(n_label, false)
-               end
+               self.escapemark = v.make_escape_mark(n_label, false)
                v.enter_visit_block(n_block, self.escapemark)
        end
 end
@@ -381,17 +387,12 @@ redef class ACallFormExpr
                        var variable = v.search_variable(name)
                        if variable != null then
                                var n: AExpr
-                               if variable isa ClosureVariable then
-                                       n = new AClosureCallExpr.init_aclosurecallexpr(n_id, n_args, n_closure_defs)
-                                       n.variable = variable
-                               else
-                                       if not n_args.n_exprs.is_empty or n_args isa AParExprs then
-                                               v.error(self, "Error: {name} is variable, not a function.")
-                                               return
-                                       end
-                                       n = variable_create(variable)
-                                       n.variable = variable
+                               if not n_args.n_exprs.is_empty or n_args isa AParExprs then
+                                       v.error(self, "Error: {name} is variable, not a function.")
+                                       return
                                end
+                               n = variable_create(variable)
+                               n.variable = variable
                                replace_with(n)
                                n.accept_scope_visitor(v)
                                return
@@ -425,36 +426,3 @@ redef class ACallReassignExpr
                return new AVarReassignExpr.init_avarreassignexpr(n_id, n_assign_op, n_value)
        end
 end
-
-redef class AClosureCallExpr
-       # the associate closure variable
-       var variable: nullable ClosureVariable
-end
-
-redef class AClosureDef
-       # The automatic variables in order
-       var variables: nullable Array[Variable]
-
-       # The escape mark used with the closure
-       var escapemark: nullable EscapeMark
-
-       redef fun accept_scope_visitor(v)
-       do
-               v.scopes.unshift(new Scope)
-
-               var variables = new Array[Variable]
-               self.variables = variables
-
-               for nid in self.n_ids do
-                       var va = new Variable(nid.text)
-                       v.register_variable(nid, va)
-                       variables.add(va)
-               end
-
-               var escapemark = v.make_escape_mark(n_label, true)
-               self.escapemark = escapemark
-               v.enter_visit_block(self.n_expr, escapemark)
-
-               v.scopes.shift
-       end
-end