Example #1
0
        private FunctionBodyStatement ParseFunctionBody()
        {
            var result = new FunctionBodyStatement();

            // Обработать директивы
            while (Lookahead.Type == TokenType.String)
            {
                var next = PeekNextToken();
                if (next.Type == TokenType.Semicolon || next.IsAfterLineTerminator || next.Type == TokenType.Unknown)
                {
                    _currentFunction.AppendDirective(Lookahead.Value);
                    if (next.Type == TokenType.Semicolon || next.Type == TokenType.Unknown)
                    {
                        MoveForwardLookahead();
                    }
                    else
                    {
                        ReadNextToken();
                    }
                }
            }

            for (;;)
            {
                if (Lookahead.Type == TokenType.Function)
                {
                    // ReadNextToken вызовет ParseFunctionDeclaration
                    ParseFunctionDeclaration();
                }
                else
                {
                    var statement = ParseStatement(false);
                    if (statement == null)
                    {
                        break;
                    }
                    result.Add(statement);
                    if (Lookahead.Type == TokenType.Unknown)
                    {
                        break;
                    }
                    if (Lookahead.Type == TokenType.Semicolon)
                    {
                        ReadNextToken();
                    }
                    else if (!Lookahead.IsAfterLineTerminator)
                    {
                        Errors.ThrowUnmatchedToken(TokenType.Semicolon, Lookahead);
                    }
                }
            }

            return(result);
        }
Example #2
0
        public Function(
            string name,
            int lineNo,
            List <string> parameterNames,
            HashSet <string> directives,
            List <string> declaredVariables,
            List <Function> nestedFunctions,
            FunctionBodyStatement functionBody,
            bool isDeclaration)
        {
            Contract.Requires(!(isDeclaration && string.IsNullOrEmpty(name)));
            Contract.Requires(parameterNames != null);
            Contract.Requires(directives != null);
            Contract.Requires(declaredVariables != null);
            Contract.Requires(nestedFunctions != null);
            Contract.Requires(functionBody != null);

            Name              = name;
            LineNo            = lineNo;
            ParameterNames    = parameterNames;
            Directives        = directives;
            DeclaredVariables = declaredVariables;
            NestedFunctions   = nestedFunctions;
            FunctionBody      = functionBody;
            IsDeclaration     = isDeclaration;

            // Переупорядочить NestedFunctions переместив FunctionDeclaration в начало
            // в порядке следования в исходном тексте. Необходимо для более быстрого
            // нахождения FunctionDeclaration при инициализации LocalScope
            for (var i = 0; i < NestedFunctions.Count; i++)
            {
                if (NestedFunctions[i].IsDeclaration)
                {
                    if (i > FunctionDeclarationCount)
                    {
                        var t = NestedFunctions[FunctionDeclarationCount];
                        NestedFunctions[FunctionDeclarationCount] = NestedFunctions[i];
                        NestedFunctions[i] = t;
                        NestedFunctions[FunctionDeclarationCount].Index = i;
                    }
                    FunctionDeclarationCount++;
                }
            }

            // Присвоить индексы всем оставшимся вложенным функциям
            for (var i = FunctionDeclarationCount; i < NestedFunctions.Count; i++)
            {
                NestedFunctions[i].Index = i;
            }
        }