summaryrefslogtreecommitdiffhomepage
path: root/dev/CompilerKit/Frontend.h
blob: df70048e5bc51805bfb19f332d8ee2bc6c19229e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/* ========================================

  Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license

======================================== */

#pragma once

#include <CompilerKit/Compiler.h>

#define CK_COMPILER_FRONTEND : public ::CompilerKit::CompilerFrontendInterface

namespace CompilerKit {
inline static auto kInvalidFrontend = "(null)";

struct SyntaxLeafList;
struct SyntaxLeafList;
struct CompilerKeyword;

/// =========================================================== ///
/// @note we want to do that 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 {
  CompilerKeyword(STLString name, KeywordKind kind) : keyword_name(name), keyword_kind(kind) {}

  STLString   keyword_name{""};
  KeywordKind keyword_kind{kKeywordKindInvalid};
};

struct SyntaxLeafList final {
  struct SyntaxLeaf final {
    Int32           fUserType{0U};
    CompilerKeyword fUserData{"", kKeywordKindInvalid};

    STLString          fUserValue{""};
    struct SyntaxLeaf* fNext{nullptr};
  };

  std::vector<SyntaxLeaf> fLeafList;
  SizeType                fNumLeafs{0};

  SizeType                 SizeOf() { return fNumLeafs; }
  std::vector<SyntaxLeaf>& Get() { return fLeafList; }
  SyntaxLeaf&              At(SizeType 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.
/// =========================================================== ///
Bool find_word(STLString haystack, STLString needle) noexcept;

/// =========================================================== ///
/// find a word within strict conditions and returns a range of it.
/// \param haystack
/// \param needle
/// \return position of needle.
/// =========================================================== ///
SizeType find_word_range(STLString haystack, STLString needle) noexcept;

/// =========================================================== ///
/// @brief Compiler backend, implements a frontend, such as C, C++...
/// See Toolchain, for some examples.
/// =========================================================== ///
class CompilerFrontendInterface {
 public:
  explicit CompilerFrontendInterface() = default;
  virtual ~CompilerFrontendInterface() = default;

  NECTI_COPY_DEFAULT(CompilerFrontendInterface);

  /// =========================================================== ///
  // NOTE: cast this to your user defined ast.
  /// =========================================================== ///
  typedef VoidPtr AstType;

  /// =========================================================== ///
  //! @brief Compile a syntax tree ouf of the text.
  //! Also takes the source file name for metadata.
  /// =========================================================== ///

  virtual CompilerKit::SyntaxLeafList::SyntaxLeaf Compile(std::string text, std::string file) = 0;

  /// =========================================================== ///
  //! @brief What language are we dealing with?
  /// =========================================================== ///
  virtual const char* Language() { return kInvalidFrontend; }

  /// =========================================================== ///
  /// @brief Checks if language is a valid frontend.
  /// =========================================================== ///
  virtual bool IsValid() { return strcmp(this->Language(), kInvalidFrontend) > 0; }
};
}  // namespace CompilerKit