summaryrefslogtreecommitdiffhomepage
path: root/dev/LibCompiler/CompilerFrontend.h
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal@nekernel.org>2025-05-14 17:49:19 +0200
committerAmlal El Mahrouss <amlal@nekernel.org>2025-05-14 17:50:15 +0200
commit9f031e69aace747feb5bac78eccb9a1d5df81f74 (patch)
tree3cc53814499a1b2c2d44fdffc7f694732cd44a1f /dev/LibCompiler/CompilerFrontend.h
parent94ceccd5acda2fd035eb55235126b944b0915576 (diff)
feat(cc): Rename Parser.h to CompilerFrontend.h, refactor codebase
accordingly. why: - To make its intent clearer, and avoid future confusions. also: - Ran ./format.sh to the codebase. Signed-off-by: Amlal El Mahrouss <amlal@nekernel.org>
Diffstat (limited to 'dev/LibCompiler/CompilerFrontend.h')
-rw-r--r--dev/LibCompiler/CompilerFrontend.h149
1 files changed, 149 insertions, 0 deletions
diff --git a/dev/LibCompiler/CompilerFrontend.h b/dev/LibCompiler/CompilerFrontend.h
new file mode 100644
index 0000000..858473b
--- /dev/null
+++ b/dev/LibCompiler/CompilerFrontend.h
@@ -0,0 +1,149 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024-2025 Amlal EL Mahrous, all rights reserved
+
+------------------------------------------- */
+
+#pragma once
+
+#include <LibCompiler/AssemblyInterface.h>
+
+namespace LibCompiler {
+inline auto kInvalidFrontend = "NA";
+
+/// @brief Compiler backend, implements a frontend, such as C, C++...
+/// See Toolchain, for some examples.
+class ICompilerFrontend {
+ public:
+ explicit ICompilerFrontend() = default;
+ virtual ~ICompilerFrontend() = default;
+
+ LIBCOMPILER_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(std::string text, 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) > 0; }
+};
+
+struct SyntaxLeafList;
+struct SyntaxLeafList;
+struct CompilerKeyword;
+
+/// we want to do that because to separate keywords.
+enum KeywordKind {
+ kKeywordKindNamespace,
+ kKeywordKindFunctionStart,
+ kKeywordKindFunctionEnd,
+ kKeywordKindVariable,
+ kKeywordKindVariablePtr,
+ kKeywordKindType,
+ kKeywordKindTypePtr,
+ kKeywordKindExpressionBegin,
+ kKeywordKindExpressionEnd,
+ kKeywordKindArgSeparator,
+ kKeywordKindBodyStart,
+ kKeywordKindBodyEnd,
+ kKeywordKindClass,
+ kKeywordKindPtrAccess,
+ kKeywordKindAccess,
+ kKeywordKindIf,
+ kKeywordKindElse,
+ kKeywordKindElseIf,
+ kKeywordKindVariableAssign,
+ kKeywordKindVariableDec,
+ kKeywordKindVariableInc,
+ kKeywordKindConstant,
+ kKeywordKindTypedef,
+ kKeywordKindEndInstr,
+ kKeywordKindSpecifier,
+ kKeywordKindInvalid,
+ kKeywordKindReturn,
+ kKeywordKindCommentInline,
+ kKeywordKindCommentMultiLineStart,
+ kKeywordKindCommentMultiLineEnd,
+ kKeywordKindEq,
+ kKeywordKindNotEq,
+ kKeywordKindGreaterEq,
+ kKeywordKindLessEq,
+ kKeywordKindPtr,
+};
+
+/// \brief Compiler keyword information struct.
+struct CompilerKeyword {
+ std::string keyword_name;
+ KeywordKind keyword_kind = kKeywordKindInvalid;
+};
+struct SyntaxLeafList final {
+ struct SyntaxLeaf final {
+ Int32 fUserType;
+#ifdef LC_USE_STRUCTS
+ CompilerKeyword fUserData;
+#else
+ std::string fUserData;
+#endif
+
+ SyntaxLeaf() = default;
+
+ 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(std::string haystack, 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(std::string haystack, 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 std::string::npos;
+}
+} // namespace LibCompiler