summaryrefslogtreecommitdiffhomepage
path: root/dev/LibCompiler/Frontend.h
blob: f39c9d4d2372cf4895108e8666058ca0724d7bb1 (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
/* -------------------------------------------

  Copyright (C) 2024-2025 Amlal EL Mahrouss, all rights reserved

------------------------------------------- */

#pragma once

#include <LibCompiler/CodeGen.h>

#define LC_COMPILER_FRONTEND : public ::LibCompiler::CompilerFrontendInterface

namespace LibCompiler {
inline static auto kInvalidFrontend = "?";

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 {
  STLString   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

    std::string        fUserValue{""};
    struct SyntaxLeaf* fNext{nullptr};
  };

  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.
BOOL find_word(std::string haystack, std::string needle) noexcept;

/// find a word within strict conditions and returns a range of it.
/// \param haystack
/// \param needle
/// \return position of needle.
std::size_t find_word_range(std::string haystack, std::string 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;

  LIBCOMPILER_COPY_DEFAULT(CompilerFrontendInterface);

  // 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 LibCompiler::SyntaxLeafList::SyntaxLeaf 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; }
};
}  // namespace LibCompiler