diff options
| author | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-12-27 07:39:05 +0100 |
|---|---|---|
| committer | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-12-27 07:39:05 +0100 |
| commit | f61c814a0a95e98529c96361c992f1a8ea24688a (patch) | |
| tree | 0c5fcb7976f5753149e0b8cc3b974a318e013f61 /dev/LibCompiler/Parser.h | |
| parent | c2046f25120d8c39b36cb81459f3370c8a5f1fa3 (diff) | |
META: Refactor source code.
Signed-off-by: Amlal El Mahrouss <amlal.elmahrouss@icloud.com>
Diffstat (limited to 'dev/LibCompiler/Parser.h')
| -rw-r--r-- | dev/LibCompiler/Parser.h | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/dev/LibCompiler/Parser.h b/dev/LibCompiler/Parser.h new file mode 100644 index 0000000..35e0c45 --- /dev/null +++ b/dev/LibCompiler/Parser.h @@ -0,0 +1,177 @@ +/* ------------------------------------------- + + Copyright (C) 2024 Theater Quality Inc, all rights reserved + +------------------------------------------- */ + +#pragma once + +#include <LibCompiler/AAL/AssemblyInterface.h> + +namespace LibCompiler +{ + inline auto kInvalidFrontend = "NoLang"; + + /// @brief Compiler backend, implements a frontend, such as C, C++... + /// See Toolchain, for some examples. + class ICompilerFrontend + { + public: + explicit ICompilerFrontend() = default; + virtual ~ICompilerFrontend() = default; + + TOOLCHAINKIT_COPY_DEFAULT(ICompilerFrontend); + + // NOTE: cast this to your user defined ast. + typedef void* AstType; + + //! @brief Compile a syntax tree ouf of the text. + //! Also takes the source file name for metadata. + + virtual bool Compile(const std::string text, const std::string file) = 0; + + //! @brief What language are we dealing with? + virtual const char* Language() + { + return kInvalidFrontend; + } + + virtual bool IsValid() + { + return strcmp(this->Language(), kInvalidFrontend); + } + }; + + struct SyntaxLeafList; + struct SyntaxLeafList; + struct CompilerKeyword; + + /// we want to do that because to separate keywords. + enum KeywordKind + { + eKeywordKindNamespace, + eKeywordKindFunctionStart, + eKeywordKindFunctionEnd, + eKeywordKindVariable, + eKeywordKindVariablePtr, + eKeywordKindType, + eKeywordKindTypePtr, + eKeywordKindExpressionBegin, + eKeywordKindExpressionEnd, + eKeywordKindArgSeparator, + eKeywordKindBodyStart, + eKeywordKindBodyEnd, + eKeywordKindClass, + eKeywordKindPtrAccess, + eKeywordKindAccess, + eKeywordKindIf, + eKeywordKindElse, + eKeywordKindElseIf, + eKeywordKindVariableAssign, + eKeywordKindVariableDec, + eKeywordKindVariableInc, + eKeywordKindConstant, + eKeywordKindTypedef, + eKeywordKindEndInstr, + eKeywordKindSpecifier, + eKeywordKindInvalid, + eKeywordKindReturn, + eKeywordKindCommentInline, + eKeywordKindCommentMultiLineStart, + eKeywordKindCommentMultiLineEnd, + eKeywordKindEq, + eKeywordKindNotEq, + eKeywordKindGreaterEq, + eKeywordKindLessEq, + eKeywordKindPtr, + }; + + /// \brief Compiler keyword information struct. + struct CompilerKeyword + { + std::string keyword_name; + KeywordKind keyword_kind = eKeywordKindInvalid; + }; + struct SyntaxLeafList final + { + struct SyntaxLeaf final + { + Int32 fUserType; +#ifdef TK_USE_STRUCTS + CompilerKeyword fUserData; +#else + std::string fUserData; +#endif + + std::string fUserValue; + struct SyntaxLeaf* fNext; + }; + + std::vector<SyntaxLeaf> fLeafList; + SizeType fNumLeafs; + + size_t SizeOf() + { + return fNumLeafs; + } + std::vector<SyntaxLeaf>& Get() + { + return fLeafList; + } + SyntaxLeaf& At(size_t index) + { + return fLeafList[index]; + } + }; + + /// find the perfect matching word in a haystack. + /// \param haystack base string + /// \param needle the string we search for. + /// \return if we found it or not. + inline bool find_word(const std::string& haystack, + const std::string& needle) noexcept + { + auto index = haystack.find(needle); + + // check for needle validity. + if (index == std::string::npos) + return false; + + // declare lambda + auto not_part_of_word = [&](int index) { + if (std::isspace(haystack[index]) || std::ispunct(haystack[index])) + return true; + + if (index <= 0 || index >= haystack.size()) + return true; + + return false; + }; + + return not_part_of_word(index - 1) && not_part_of_word(index + needle.size()); + } + + /// find a word within strict conditions and returns a range of it. + /// \param haystack + /// \param needle + /// \return position of needle. + inline std::size_t find_word_range(const std::string& haystack, + const std::string& needle) noexcept + { + auto index = haystack.find(needle); + + // check for needle validity. + if (index == std::string::npos) + return false; + + if (!isalnum((haystack[index + needle.size() + 1])) && + !isdigit(haystack[index + needle.size() + 1]) && + !isalnum((haystack[index - needle.size() - 1])) && + !isdigit(haystack[index - needle.size() - 1])) + { + return index; + } + + return false; + } +} // namespace LibCompiler |
