예제 #1
0
        private void ParseFunctionParameterList(ScriptFunction func)
        {
            Modifiers modifiers;
            bool      atEndOfParameterList = false;

            while ((!atEndOfParameterList) &&
                   (!_source.NextIsKeyword(PredefinedSymbol.CloseParenthesis)))
            {
                modifiers = new Modifiers();

                while (_source.PeekNextToken() is ModifierToken)
                {
                    modifiers.Add((ModifierToken)_source.ReadNextToken());
                }

                if (_source.NextIsKeyword(PredefinedSymbol.VariableArguments))
                {
                    func.VariableArguments = true;
                    _source.ExpectKeyword(PredefinedSymbol.CloseParenthesis, "Variable arguments must be the last parameter");
                    break;
                }

                Token parameterType = _source.ReadNextAsVariableType();
                Token parameterName = null;
                _source.IgnoreAsteriskIfPresent();

                CompilerUtils.VerifyModifiersAgainstType(ModifierTargets.FunctionParameter, modifiers);

                VerifyParameterTypeValidForFunction(parameterType);

                if (!_source.PeekNextToken().Defined)
                {
                    parameterName = _source.ReadNextTokenAndThrowIfAlreadyDefined();
                }
                else
                {
                    func.IsPrototypeOnly = true;
                }

                FunctionParameter parameter = new FunctionParameter(parameterType, parameterName);
                parameter.Modifiers = modifiers;

                if (_source.NextIsKeyword(PredefinedSymbol.SetEqual))
                {
                    parameter.DefaultValue = _source.ReadNextAsConstInt();
                }

                if (_source.NextIsKeyword(PredefinedSymbol.CloseParenthesis))
                {
                    atEndOfParameterList = true;
                }
                else
                {
                    _source.ExpectKeyword(PredefinedSymbol.Comma);
                }

                func.Parameters.Add(parameter);
            }
        }
예제 #2
0
        private Expression ReadExpression(ScriptReader source, bool readTerminatingSymbolFromStream, params PredefinedSymbol[] endsWithSymbols)
        {
            Expression expression   = new Expression();
            int        bracketLevel = 0;

            while (bracketLevel >= 0)
            {
                foreach (PredefinedSymbol terminatingSymbol in endsWithSymbols)
                {
                    if ((bracketLevel == 0) && (source.NextIsKeyword(terminatingSymbol, !readTerminatingSymbolFromStream)))
                    {
                        return(expression);
                    }
                }

                Token thisToken = source.PeekNextToken();
                if (thisToken is EndOfStreamToken)
                {
                    throw new CompilerMessage(ErrorCode.EndOfInputReached, "End of script reached in the middle of an expression");
                }

                CompilerUtils.AdjustBracketLevelIfTokenIsBracket(thisToken, ref bracketLevel);

                if (bracketLevel >= 0)
                {
                    expression.Add(source.ReadNextToken());
                }
            }
            throw new CompilerMessage(ErrorCode.UnexpectedToken, "Unexpected '" + source.ReadNextToken() + "'");
        }
예제 #3
0
        private Expression ReadExpression(ScriptReader source, bool readTerminatingSymbolFromStream, params PredefinedSymbol[] endsWithSymbols)
        {
            Expression expression = new Expression();
            int bracketLevel = 0;
            while (bracketLevel >= 0)
            {
                foreach (PredefinedSymbol terminatingSymbol in endsWithSymbols)
                {
                    if ((bracketLevel == 0) && (source.NextIsKeyword(terminatingSymbol, !readTerminatingSymbolFromStream)))
                    {
                        return expression;
                    }
                }

                Token thisToken = source.PeekNextToken();
                if (thisToken is EndOfStreamToken)
                {
                    throw new CompilerMessage(ErrorCode.EndOfInputReached, "End of script reached in the middle of an expression");
                }

                CompilerUtils.AdjustBracketLevelIfTokenIsBracket(thisToken, ref bracketLevel);

                if (bracketLevel >= 0)
                {
                    expression.Add(source.ReadNextToken());
                }
            }
            throw new CompilerMessage(ErrorCode.UnexpectedToken, "Unexpected '" + source.ReadNextToken() + "'");
        }
예제 #4
0
        private void ProcessNextCodeStatement(bool allowVariableDeclarations)
        {
            Token nextToken = _source.PeekNextToken();

            while (nextToken is ModifierToken)
            {
                _source.ReadNextToken();

                _state.NextTokenModifiers.Add((ModifierToken)nextToken);

                nextToken = _source.PeekNextToken();
            }

            if (nextToken is EndOfStreamToken)
            {
                throw new CompilerMessage(ErrorCode.EndOfInputReached, "The end of the script was reached in the middle of a function");
            }

            if ((nextToken is KeywordToken) &&
                (((KeywordToken)nextToken).SymbolType == PredefinedSymbol.OpenBrace))
            {
                ProcessCodeBlock();
            }
            else if (nextToken is KeywordToken)
            {
                _source.ReadNextToken();
                ProcessKeyword((KeywordToken)nextToken);
            }
            else if (nextToken.IsVariableType)
            {
                _source.PushLocation();
                Token variableType = _source.ReadNextToken();

                if (_source.NextIsKeyword(PredefinedSymbol.Dot))
                {
                    // it's a static member access
                    _source.PopLocation();
                    GenerateCodeForExpression(ReadExpression(true, PredefinedSymbol.Semicolon));
                }
                else
                {
                    _source.DeletePushedLocation();

                    if (!allowVariableDeclarations)
                    {
                        throw new CompilerMessage(ErrorCode.VariableDeclarationNotAllowedHere, "The variable would go out of scope as soon as it was declared");
                    }
                    do
                    {
                        DeclareLocalVariable(variableType);
                    }while (_source.NextIsKeyword(PredefinedSymbol.Comma));

                    _source.ExpectKeyword(PredefinedSymbol.Semicolon);
                    _state.NextTokenModifiers.Clear();
                }
            }
            else
            {
                GenerateCodeForExpression(ReadExpression(true, PredefinedSymbol.Semicolon));
            }
        }