//============================================================================// // // // artichoke programming language // // // // Copyright (C) 2025 Erick Saul Guzman Ramos, whoami.artichoke.dev // // // // // // This program is free software: you can redistribute it and/or modify // // it under the terms of the GNU Affero General Public License as published // // by the Free Software Foundation, either version 3 of the License, or // // (at your option) any later version. // // // // This program is distributed in the hope that it will be useful, // // but WITHOUT ANY WARRANTY; without even the implied warranty of // // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // // GNU Affero General Public License for more details. // // // // You should have received a copy of the GNU Affero General Public License // // along with this program. If not, see . // // // //============================================================================// #pragma once #include #include #include #include namespace arti::lang { enum struct ExceptCode { ecEOF, ecEOB, ecInvalidToken, ecStdException, ecInvalidLiteral, ecInvalidCharacter, ecInvalidIndex, ecInvalidComment, ecUnexpectedToken, ecExpectedSemicolon, ecImportInsideModule, ecUnimplemented, }; struct Exception { size_t line; size_t column; std::string message; }; template using Expected = std::expected; template using Unexpected = std::unexpected; template std::string exceptionMessage(Args &&...args) { using enum ExceptCode; if constexpr (code == ecEOF) { return "Reached EOF"; } else if constexpr (code == ecEOB) { return "Buffer empty"; } else if constexpr (code == ecStdException) { return std::format( "Catched instance of {}: '{}'", std::forward(args)... ); } else if constexpr (code == ecInvalidLiteral) { return std::format( "Invalid literal, expected {} got {}", std::forward(args)... ); } else if constexpr (code == ecInvalidCharacter) { return std::format( "Invalid character found '{}'", std::forward(args)... ); } else if constexpr (code == ecInvalidToken) { return std::format( "Invalid token found '{}'", std::forward(args)... ); } else if constexpr (code == ecInvalidIndex) { return "Invalid index"; } else if constexpr (code == ecInvalidComment) { return "Invalid comment found, missing '*/' end of comment"; } else if constexpr (code == ecUnexpectedToken) { return std::format( "Found unexpected token '{}', expected {}", std::forward(args)... ); } else if constexpr (code == ecExpectedSemicolon) { return std::format( "Expected ';', got '{}'", std::forward(args)... ); } else if constexpr (code == ecImportInsideModule) { return "Cannot use import statements inside a module declaration"; } else if constexpr (code == ecUnimplemented) { return "Unimplemented"; } else { return "Unknown error"; } } template static inline Unexpected<> langException(size_t line, size_t col, Args &&...args) { return Unexpected{ Exception{ line, col, exceptionMessage(std::forward(args)...) } }; } } // namespace arti::lang