X-Git-Url: http://nitlanguage.org diff --git a/src/scope.nit b/src/scope.nit index 2805556..83c5fe4 100644 --- a/src/scope.nit +++ b/src/scope.nit @@ -17,12 +17,8 @@ # Identification and scping of local variables and labels. module scope -import parser -import toolcontext import phase -import modelbuilder #FIXME useless - redef class ToolContext var scope_phase: Phase = new ScopePhase(self, null) end @@ -42,18 +38,13 @@ class Variable 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 @@ -65,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` # FIXME: Should the class be private? private class ScopeVisitor super Visitor @@ -148,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 @@ -171,7 +169,16 @@ private class ScopeVisitor 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}.") @@ -181,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 @@ -241,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 @@ -311,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 @@ -394,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 @@ -438,49 +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 ASendExpr - # The escape mark used with the closures if any - var escapemark: nullable EscapeMark - - redef fun accept_scope_visitor(v) - do - if self.n_closure_defs.length > 0 then - var escapemark = v.make_escape_mark(self.n_closure_defs.last.n_label, true) - self.escapemark = escapemark - end - super - end -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 - - self.escapemark = self.parent.as(ASendExpr).escapemark - v.enter_visit_block(self.n_expr, escapemark) - - v.scopes.shift - end -end