Added pattern preprocessor and #define and #include support

This commit is contained in:
WerWolv
2020-11-17 02:31:51 +01:00
parent b28d45df8a
commit 4c07983834
17 changed files with 176 additions and 26 deletions

98
include/lang/ast_node.hpp Normal file
View File

@@ -0,0 +1,98 @@
#pragma once
#include "token.hpp"
#include <optional>
#include <unordered_map>
#include <vector>
namespace hex::lang {
class ASTNode {
public:
enum class Type {
VariableDecl,
TypeDecl,
Struct,
Enum,
Scope,
};
explicit ASTNode(Type type) : m_type(type) {}
virtual ~ASTNode() = default;
Type getType() { return this->m_type; }
private:
Type m_type;
};
class ASTNodeVariableDecl : public ASTNode {
public:
explicit ASTNodeVariableDecl(const Token::TypeToken::Type &type, const std::string &name, const std::string& customTypeName = "", std::optional<u64> offset = { }, size_t arraySize = 1)
: ASTNode(Type::VariableDecl), m_type(type), m_name(name), m_customTypeName(customTypeName), m_offset(offset), m_arraySize(arraySize) { }
const Token::TypeToken::Type& getVariableType() const { return this->m_type; }
const std::string& getCustomVariableTypeName() const { return this->m_customTypeName; }
const std::string& getVariableName() const { return this->m_name; };
std::optional<u64> getOffset() const { return this->m_offset; }
size_t getArraySize() const { return this->m_arraySize; }
private:
Token::TypeToken::Type m_type;
std::string m_name, m_customTypeName;
std::optional<u64> m_offset;
size_t m_arraySize;
};
class ASTNodeScope : public ASTNode {
public:
explicit ASTNodeScope(std::vector<ASTNode*> nodes) : ASTNode(Type::Scope), m_nodes(nodes) { }
std::vector<ASTNode*> &getNodes() { return this->m_nodes; }
private:
std::vector<ASTNode*> m_nodes;
};
class ASTNodeStruct : public ASTNode {
public:
explicit ASTNodeStruct(std::string name, std::vector<ASTNode*> nodes)
: ASTNode(Type::Struct), m_name(name), m_nodes(nodes) { }
const std::string& getName() const { return this->m_name; }
std::vector<ASTNode*> &getNodes() { return this->m_nodes; }
private:
std::string m_name;
std::vector<ASTNode*> m_nodes;
};
class ASTNodeTypeDecl : public ASTNode {
public:
explicit ASTNodeTypeDecl(const Token::TypeToken::Type &type, const std::string &name, const std::string& customTypeName = "")
: ASTNode(Type::TypeDecl), m_type(type), m_name(name), m_customTypeName(customTypeName) { }
const std::string& getTypeName() const { return this->m_name; };
const Token::TypeToken::Type& getAssignedType() const { return this->m_type; }
const std::string& getAssignedCustomTypeName() const { return this->m_customTypeName; }
private:
Token::TypeToken::Type m_type;
std::string m_name, m_customTypeName;
};
class ASTNodeEnum : public ASTNode {
public:
explicit ASTNodeEnum(const Token::TypeToken::Type &type, const std::string &name)
: ASTNode(Type::Enum), m_type(type), m_name(name) { }
const std::string& getName() const { return this->m_name; };
const Token::TypeToken::Type& getUnderlyingType() const { return this->m_type; }
std::vector<std::pair<u64, std::string>>& getValues() { return this->m_values; }
private:
Token::TypeToken::Type m_type;
std::string m_name;
std::vector<std::pair<u64, std::string>> m_values;
};
}

19
include/lang/lexer.hpp Normal file
View File

@@ -0,0 +1,19 @@
#pragma once
#include <hex.hpp>
#include "token.hpp"
#include <string>
#include <vector>
namespace hex::lang {
class Lexer {
public:
Lexer();
std::pair<Result, std::vector<Token>> lex(const std::string& code);
};
}

19
include/lang/parser.hpp Normal file
View File

@@ -0,0 +1,19 @@
#pragma once
#include <hex.hpp>
#include "token.hpp"
#include "ast_node.hpp"
#include <vector>
namespace hex::lang {
class Parser {
public:
Parser();
std::pair<Result, std::vector<ASTNode*>> parse(const std::vector<Token> &tokens);
};
}

View File

@@ -0,0 +1,23 @@
#pragma once
#include <hex.hpp>
#include "token.hpp"
#include <string>
#include <utility>
#include <set>
namespace hex::lang {
class Preprocessor {
public:
Preprocessor();
std::pair<Result, std::string> preprocess(const std::string& code, bool applyDefines = true);
private:
std::set<std::pair<std::string, std::string>> m_defines;
};
}

21
include/lang/result.hpp Normal file
View File

@@ -0,0 +1,21 @@
#pragma once
#include <cstdint>
namespace hex::lang {
class Result {
public:
constexpr Result(const std::uint8_t module, const std::uint32_t desc) noexcept : m_result((module << 24) | (desc & 0x00FFFFFF)) { }
constexpr std::uint32_t getResult() const noexcept { return this->m_result; }
constexpr std::uint8_t getModule() const noexcept { return this->m_result >> 24; }
constexpr std::uint32_t getDescription() const noexcept { return this->m_result & 0x00FFFFFF; }
constexpr bool succeeded() const noexcept { return this->m_result == 0; }
constexpr bool failed() const noexcept { return !succeeded(); }
private:
const std::uint32_t m_result;
};
}

13
include/lang/results.hpp Normal file
View File

@@ -0,0 +1,13 @@
#pragma once
#include "result.hpp"
namespace hex::lang {
constexpr Result ResultSuccess(0, 0);
constexpr Result ResultPreprocessingError(1, 1);
constexpr Result ResultLexicalError(2, 1);
constexpr Result ResultParseError(3, 1);
}

63
include/lang/token.hpp Normal file
View File

@@ -0,0 +1,63 @@
#pragma once
#include <hex.hpp>
#include <string>
namespace hex::lang {
struct Token {
enum class Type : u64 {
Keyword,
Type,
Operator,
Integer,
Identifier,
EndOfExpression,
ScopeOpen,
ScopeClose,
ArrayOpen,
ArrayClose,
Separator,
EndOfProgram
} type;
struct KeywordToken {
enum class Keyword {
Struct,
Using,
Enum
} keyword;
} keywordToken;
struct IdentifierToken {
std::string identifier;
} identifierToken;
struct OperatorToken {
enum class Operator {
AtDeclaration,
Assignment,
Inherit
} op;
} operatorToken;
struct IntegerToken {
s128 integer;
} integerToken;
struct TypeToken {
enum class Type {
Unsigned8Bit = 0x10,
Signed8Bit = 0x11,
Unsigned16Bit = 0x20,
Signed16Bit = 0x21,
Unsigned32Bit = 0x40,
Signed32Bit = 0x41,
Unsigned64Bit = 0x80,
Signed64Bit = 0x81,
Unsigned128Bit = 0x100,
Signed128Bit = 0x101,
Float = 0x42,
Double = 0x82,
CustomType = 0x00
} type;
} typeToken;
};
}

View File

@@ -0,0 +1,20 @@
#pragma once
#include <hex.hpp>
#include "token.hpp"
#include "ast_node.hpp"
#include <string>
#include <vector>
namespace hex::lang {
class Validator {
public:
Validator();
bool validate(const std::vector<ASTNode*>& ast);
};
}