// Declares a variable in the current scope whose name is the given token. // // If [token] is `null`, uses the previously consumed token. Returns its symbol. private int DeclareVariable(Token? token) { if (token == null) token = _parser.Previous; Token t = token.Value; if (t.Length > MaxVariableName) { Error(string.Format("Variable name cannot be longer than {0} characters.", MaxVariableName)); } // Top-level module scope. if (_scopeDepth == -1) { int symbol = _parser.vm.DefineVariable(_parser.Module, _parser.Source.Substring(t.Start, t.Length), Obj.Null); switch (symbol) { case -1: Error("Module variable is already defined."); break; case -2: Error("Too many module variables defined."); break; } return symbol; } string tokenName = _parser.Source.Substring(t.Start, t.Length); // See if there is already a variable with this name declared in the current // scope. (Outer scopes are OK: those get shadowed.) for (int i = _numLocals - 1; i >= 0; i--) { Local local = _locals[i]; // Once we escape this scope and hit an outer one, we can stop. if (local.Depth < _scopeDepth) break; if (local.Length == t.Length && tokenName == local.Name) { Error(string.Format("Variable '{0}' is already declared in this scope.", local.Name)); return i; } } if (_numLocals > MaxLocals) { Error(string.Format("Cannot declare more than {0} variables in one scope.", MaxLocals)); return -1; } return DefineLocal(tokenName, t.Length); }
// Declares a variable in the current scope whose name is the given token. // // If [token] is `null`, uses the previously consumed token. Returns its symbol. private int DeclareVariable(Token? token) { if (token == null) token = parser.previous; Token t = token.Value; if (t.length > MAX_VARIABLE_NAME) { Error(string.Format("Variable name cannot be longer than {0} characters.", MAX_VARIABLE_NAME)); } // Top-level module scope. if (scopeDepth == -1) { int symbol = parser.vm.DefineVariable(parser.module, parser.source.Substring(t.start, t.length), new Value(ValueType.Null)); switch (symbol) { case -1: Error("Module variable is already defined."); break; case -2: Error("Too many module variables defined."); break; } return symbol; } // See if there is already a variable with this name declared in the current // scope. (Outer scopes are OK: those get shadowed.) for (int i = numLocals - 1; i >= 0; i--) { Local local = locals[i]; // Once we escape this scope and hit an outer one, we can stop. if (local.depth < scopeDepth) break; if (local.length == t.length && parser.source.Substring(t.start, t.length) == local.name) { Error(string.Format("Variable '{0}' is already declared in this scope.", local.name)); return i; } } if (numLocals >= MAX_LOCALS) { Error(string.Format("Cannot declare more than {0} variables in one scope.", MAX_LOCALS)); return -1; } return DefineLocal(parser.source.Substring(t.start, t.length), t.length); }