private void ParseAndAddFunctionDefinition(Token variableType, Token variableName, bool isMemberFunction) { if (isMemberFunction) { VerifyModifiersAgainstType(ModifierTargets.MemberFunction); } else { VerifyModifiersAgainstType(ModifierTargets.GlobalFunction); } VerifyReturnTypeValidForFunction(variableType); ScriptFunction func = new ScriptFunction(variableType, variableName); ParseFunctionParameterList(func); if (_source.NextIsKeyword(PredefinedSymbol.Semicolon)) { func.IsPrototypeOnly = true; } else { if (func.IsPrototypeOnly == true) { throw new CompilerMessage(ErrorCode.AnonymousParameterInFunctionBody, "One or more parameters did not have a name"); } func.IsPrototypeOnly = false; _state.NextTokenModifiers.Clear(); ProcessFunctionBody(); } }
private static bool AddFunctionDeclaration(List<ScriptFunction> functions, ref FastString script, string thisWord, AutoCompleteParserState state, bool isExtenderMethod) { bool succeeded = false; if ((state.LastWord.Length > 0) && (state.WordBeforeLast.Length > 0)) { if (!DoesCurrentLineHaveToken(script, AUTO_COMPLETE_IGNORE)) { string functionName = state.LastWord; string type = state.WordBeforeLast; bool isPointer = false, isNoInherit = false; bool isStatic = false, isStaticOnly = false; bool isProtected = false; if (type == "::") { functionName = state.WordBeforeWordBeforeLast + "::" + functionName; type = (state.PreviousWords.Length > 3) ? state.PreviousWords[3] : "unknown"; } if (type == "*") { isPointer = true; type = state.WordBeforeWordBeforeLast; } if (state.DynamicArrayDefinition) { // get the type name and the [] type = state.WordBeforeWordBeforeLast + state.WordBeforeLast; } if (state.IsWordInPreviousList("static")) { isStatic = true; } if (state.IsWordInPreviousList("protected")) { isProtected = true; } if (DoesCurrentLineHaveToken(script, AUTO_COMPLETE_STATIC_ONLY)) { isStaticOnly = true; } if (DoesCurrentLineHaveToken(script, AUTO_COMPLETE_NO_INHERIT)) { isNoInherit = true; } int parameterListEndIndex = script.IndexOf(')'); if (parameterListEndIndex >= 0) { string parameterList = script.Substring(0, parameterListEndIndex); script = script.Substring(parameterListEndIndex + 1); ScriptFunction newFunc = new ScriptFunction(functionName, type, parameterList, state.InsideIfDefBlock, state.InsideIfNDefBlock, isPointer, isStatic, isStaticOnly, isNoInherit, isProtected, isExtenderMethod, state.CurrentScriptCharacterIndex - 1); if (!string.IsNullOrEmpty(state.PreviousComment)) { newFunc.Description = state.PreviousComment; state.PreviousComment = null; } functions.Add(newFunc); succeeded = true; } state.DynamicArrayDefinition = false; } } return succeeded; }
private void ParseAndAddMemberToStruct(Token variableType, Token structName, ScriptStruct structDefinition, Token parentStruct) { _source.IgnoreAsteriskIfPresent(); Token memberName = _source.ReadNextToken(); if ((memberName is KeywordToken) || (memberName is OperatorToken) || (memberName is ModifierToken)) { throw new CompilerMessage(ErrorCode.TokenAlreadyDefined, "Cannot use '" + memberName.Name + "' as variable name since it has another meaning"); } string mangledName; memberName = GetTokenForStructMember(structName, memberName, out mangledName); if (memberName != null) { throw new CompilerMessage(ErrorCode.TokenAlreadyDefined, "Member '" + mangledName + "' already exists"); } memberName = new Token(mangledName, true); // TODO: Set necessary fields on new token for this struct member _tokenizedScript.AddToken(memberName); CompilerUtils.SetArrayPropertiesOnTokenFromStream(_source, memberName); if (_source.NextIsKeyword(PredefinedSymbol.OpenParenthesis)) { VerifyModifiersAgainstType(ModifierTargets.MemberFunction); VerifyReturnTypeValidForFunction(variableType); ScriptFunction func = new ScriptFunction(variableType, memberName); ParseFunctionParameterList(func); func.IsPrototypeOnly = true; } else { VerifyModifiersAgainstType(ModifierTargets.MemberVariable); ProcessVariableDeclaration(variableType, structDefinition, parentStruct, _state.NextTokenModifiers); } }
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); } }