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); }
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; } }