X-Git-Url: http://nitlanguage.org diff --git a/src/semantize/scope.nit b/src/semantize/scope.nit index 00702d0..e595b1c 100644 --- a/src/semantize/scope.nit +++ b/src/semantize/scope.nit @@ -20,6 +20,7 @@ module scope import phase redef class ToolContext + # Run `APropdef::do_scope` on each propdef. var scope_phase: Phase = new ScopePhase(self, null) end @@ -32,13 +33,13 @@ 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 + var name: String is writable # Alias of `name` redef fun to_s do return self.name # The declaration of the variable, if any - var location: nullable Location = null + var location: nullable Location = null is writable # Is the local variable not read and need a warning? var warn_unread = false is writable @@ -71,9 +72,8 @@ private class ScopeVisitor var selfvariable = new Variable("self") - init(toolcontext: ToolContext) + init do - self.toolcontext = toolcontext scopes.add(new Scope) end @@ -99,7 +99,7 @@ private class ScopeVisitor var name = variable.name var found = search_variable(name) if found != null then - self.error(node, "Error: A variable named `{name}' already exists") + self.error(node, "Error: a variable named `{name}` already exists.") return false end scopes.first.variables[name] = variable @@ -160,14 +160,14 @@ private class ScopeVisitor if nid == null then var res = search_label("") if res != null then - self.error(nlabel, "Syntax error: anonymous label already defined.") + 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.") + self.error(nlabel, "Syntax Error: label `{name}` already defined.") end end else @@ -190,7 +190,7 @@ private class ScopeVisitor if nid == null then var res = search_label("") if res == null then - self.error(nlabel, "Syntax error: invalid anonymous label.") + self.error(nlabel, "Syntax Error: invalid anonymous label.") return null end return res @@ -198,7 +198,7 @@ private class ScopeVisitor var name = nid.text var res = search_label(name) if res == null then - self.error(nlabel, "Syntax error: invalid label {name}.") + self.error(nlabel, "Syntax Error: invalid label `{name}`.") return null end return res @@ -209,7 +209,7 @@ private class ScopeVisitor return res end end - self.error(node, "Syntax Error: 'break' statement outside block.") + self.error(node, "Syntax Error: `break` statement outside block.") return null end end @@ -377,9 +377,6 @@ redef class ALoopExpr end redef class AForExpr - # The automatic variables in order - var variables: nullable Array[Variable] - # The break escape mark associated with the 'for' var break_mark: nullable EscapeMark @@ -388,18 +385,22 @@ redef class AForExpr redef fun accept_scope_visitor(v) do - v.enter_visit(n_expr) + for g in n_groups do + v.enter_visit(g.n_expr) + end # Protect automatic variables v.scopes.unshift(new Scope) - # Create the automatic variables - var variables = new Array[Variable] - self.variables = variables - for nid in n_ids do - var va = new Variable(nid.text) - v.register_variable(nid, va) - variables.add(va) + for g in n_groups do + # Create the automatic variables + var variables = new Array[Variable] + g.variables = variables + for nid in g.n_ids do + var va = new Variable(nid.text) + v.register_variable(nid, va) + variables.add(va) + end end var escapemark = v.make_escape_mark(n_label, true) @@ -411,21 +412,52 @@ redef class AForExpr end end +redef class AForGroup + # The automatic variables in order + var variables: nullable Array[Variable] +end + +redef class AWithExpr + # The break escape mark associated with the 'with' + var break_mark: nullable EscapeMark + + redef fun accept_scope_visitor(v) + do + v.scopes.unshift(new Scope) + + var escapemark = v.make_escape_mark(n_label, true) + self.break_mark = escapemark + + v.enter_visit(n_expr) + v.enter_visit_block(n_block, escapemark) + + v.shift_scope + end +end + +redef class AAssertExpr + redef fun accept_scope_visitor(v) + do + v.enter_visit(n_expr) + v.enter_visit_block(n_else, null) + end +end + redef class AVarFormExpr # The associated variable - var variable: nullable Variable + var variable: nullable Variable is writable end redef class ACallFormExpr redef fun accept_scope_visitor(v) do if n_expr isa AImplicitSelfExpr then - var name = n_id.text + var name = n_qid.n_id.text var variable = v.search_variable(name) if variable != null then var n: AExpr if not n_args.n_exprs.is_empty or n_args isa AParExprs then - v.error(self, "Error: {name} is variable, not a function.") + v.error(self, "Error: `{name}` is a variable, not a method.") return end n = variable_create(variable) @@ -447,14 +479,14 @@ redef class ACallExpr redef fun variable_create(variable) do variable.warn_unread = false - return new AVarExpr.init_avarexpr(n_id) + return new AVarExpr.init_avarexpr(n_qid.n_id) end end redef class ACallAssignExpr redef fun variable_create(variable) do - return new AVarAssignExpr.init_avarassignexpr(n_id, n_assign, n_value) + return new AVarAssignExpr.init_avarassignexpr(n_qid.n_id, n_assign, n_value) end end @@ -462,6 +494,6 @@ redef class ACallReassignExpr redef fun variable_create(variable) do variable.warn_unread = false - return new AVarReassignExpr.init_avarreassignexpr(n_id, n_assign_op, n_value) + return new AVarReassignExpr.init_avarreassignexpr(n_qid.n_id, n_assign_op, n_value) end end