Example #1
0
        // 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);
        }
Example #2
0
        // 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);
        }