public static TypeNode Parse(Parser.State state) { state.Save(); TypeNode type = new TypeNode(); while (true) { var tok = state.GetToken(); if (tok.Is(TokenType.Identifier, "const")) { if (type.IsConstant) { state.ErrorCode = (uint)ErrorCodes.P_DuplicatedModifier; state.ErrorMessage = "<const> type modifier can not be used twice" + " for the same type"; return(null); } type.IsConstant = true; } else if (tok.Is(TokenType.Identifier, "ref")) { state.GetNextNEToken(); type.IsReference = true; type.ReferenceType = Parse(state); if (type.IsConstant) { state.ErrorCode = (uint)ErrorCodes.P_ReferenceCanNotBeConstant; state.ErrorMessage = "Reference can not have a constant modifier:\n" + type.ToString(); } return(type); } else if (tok.Is(TokenSubType.BraceSquareLeft, "[")) { state.GetNextNEToken(); type.IsArrayType = true; // TODO: Parse sizes if (!state.GetToken().Is(TokenSubType.BraceSquareRight, "]")) { state.ErrorCode = 999; state.ErrorMessage = "Array does not support sizes and dimmensions " + "in the current version"; return(type); } state.GetNextNEToken(); type.ReferenceType = Parse(state); if (type.ReferenceType.IsReference) { state.ErrorCode = (uint)ErrorCodes.P_ArrayCanNotContainReferences; state.ErrorMessage = "Array can not consist of references"; } return(type); } else { // End of modifiers break; } state.GetNextNEToken(); } type.TypePath = ParsePath(state); return(type); }
private static bool ParseFunctionDeclaration(Parser.State state, CoreNode coreNode) { state.Save(); if (state.GetToken().Type != TokenType.Identifier) { state.Restore(); return(false); } string name = state.GetTokenAndMoveNE().Value; if (!state.GetToken().Is(TokenSubType.Colon, ":")) { state.ErrorCode = (uint)ErrorCodes.P_ColonBeforeTypeSpeceficationNotFound; state.ErrorMessage = $"Expected <Colon>(:) before function type specification " + $"but <{state.GetToken().SubType}>({state.GetToken().Value}) were given"; return(false); } state.GetNextNEToken(); TypeNode type = TypeParser.Parse(state); if (state.IsErrorOccured()) { return(false); } /* * // Only for class methods * bool isInstance = state.GetToken().Is(TokenSubType.Dot, "."); * bool isStatic = state.GetToken().Is(TokenSubType.Colon, ":"); * * if (!(isStatic || isInstance)) * { * state.ErrorCode = (uint)ErrorCodes.P_MethodTypeExpected; * state.ErrorMessage = * $"Expected '.' or ':' as type modifier, but " + * $"<{state.GetToken().SubType.ToString()}> were found"; * return false; * } */ FunctionNode function = new FunctionNode { Parent = coreNode, Name = name, Type = FunctionNode.EType.Static, ReturnType = type }; coreNode.FunctionNodes.Add(function); if (!state.GetToken().Is(TokenSubType.BraceRoundLeft, "(")) { state.ErrorCode = (uint)ErrorCodes.P_OpeningBracketExpected; state.ErrorMessage = $"Opening round bracket is expected before parameters list " + $"but <{state.GetToken().SubType}> were given"; return(false); } state.GetNextNEToken(); FunctionParser.ParseParametersList(state, function); if (state.IsErrorOccured()) { return(true); } // FunctionParser.ParseTemplateValues(state, function); function.Code = CodeParser.Parse(state); return(!state.IsErrorOccured()); }