1
0
mirror of synced 2025-02-26 22:29:16 +01:00

Add enums

This commit is contained in:
WerWolv 2020-11-14 14:40:21 +01:00
parent 999db12a3a
commit 41c70bce44
4 changed files with 85 additions and 6 deletions

View File

@ -3,6 +3,7 @@
#include "token.hpp" #include "token.hpp"
#include <optional> #include <optional>
#include <unordered_map>
#include <vector> #include <vector>
namespace hex::lang { namespace hex::lang {
@ -13,6 +14,7 @@ namespace hex::lang {
VariableDecl, VariableDecl,
TypeDecl, TypeDecl,
Struct, Struct,
Enum,
Scope, Scope,
}; };
@ -78,4 +80,19 @@ namespace hex::lang {
std::string m_name, m_customTypeName; 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;
};
} }

View File

@ -25,7 +25,8 @@ namespace hex::lang {
struct KeywordToken { struct KeywordToken {
enum class Keyword { enum class Keyword {
Struct, Struct,
Using Using,
Enum
} keyword; } keyword;
} keywordToken; } keywordToken;
struct IdentifierToken { struct IdentifierToken {
@ -34,7 +35,8 @@ namespace hex::lang {
struct OperatorToken { struct OperatorToken {
enum class Operator { enum class Operator {
AtDeclaration, AtDeclaration,
Assignment Assignment,
Inherit
} op; } op;
} operatorToken; } operatorToken;
struct IntegerToken { struct IntegerToken {

View File

@ -70,6 +70,7 @@ namespace hex::lang {
u32 offset = 0; u32 offset = 0;
while (offset < code.length()) { while (offset < code.length()) {
// Handle comments // Handle comments
if (code[offset] == '/') { if (code[offset] == '/') {
offset++; offset++;
@ -121,6 +122,9 @@ namespace hex::lang {
} else if (c == '=') { } else if (c == '=') {
tokens.push_back({.type = Token::Type::Operator, .operatorToken = { .op = Token::OperatorToken::Operator::Assignment}}); tokens.push_back({.type = Token::Type::Operator, .operatorToken = { .op = Token::OperatorToken::Operator::Assignment}});
offset += 1; offset += 1;
} else if (c == ':') {
tokens.push_back({.type = Token::Type::Operator, .operatorToken = { .op = Token::OperatorToken::Operator::Inherit}});
offset += 1;
} else if (std::isalpha(c)) { } else if (std::isalpha(c)) {
std::string identifier = matchTillInvalid(&code[offset], [](char c) -> bool { return std::isalnum(c) || c == '_'; }); std::string identifier = matchTillInvalid(&code[offset], [](char c) -> bool { return std::isalnum(c) || c == '_'; });
@ -130,6 +134,8 @@ namespace hex::lang {
tokens.push_back({.type = Token::Type::Keyword, .keywordToken = { .keyword = Token::KeywordToken::Keyword::Struct}}); tokens.push_back({.type = Token::Type::Keyword, .keywordToken = { .keyword = Token::KeywordToken::Keyword::Struct}});
else if (identifier == "using") else if (identifier == "using")
tokens.push_back({.type = Token::Type::Keyword, .keywordToken = { .keyword = Token::KeywordToken::Keyword::Using}}); tokens.push_back({.type = Token::Type::Keyword, .keywordToken = { .keyword = Token::KeywordToken::Keyword::Using}});
else if (identifier == "enum")
tokens.push_back({.type = Token::Type::Keyword, .keywordToken = { .keyword = Token::KeywordToken::Keyword::Enum}});
// Check for built-in types // Check for built-in types
else if (identifier == "u8") else if (identifier == "u8")

View File

@ -51,7 +51,7 @@ namespace hex::lang {
return new ASTNodeVariableDecl(Token::TypeToken::Type::CustomType, curr[-4].identifierToken.identifier, curr[-5].identifierToken.identifier, curr[-2].integerToken.integer); return new ASTNodeVariableDecl(Token::TypeToken::Type::CustomType, curr[-4].identifierToken.identifier, curr[-5].identifierToken.identifier, curr[-2].integerToken.integer);
} }
std::optional<ASTNode*> parseStruct(TokenIter &curr) { ASTNode* parseStruct(TokenIter &curr) {
const std::string &structName = curr[-2].identifierToken.identifier; const std::string &structName = curr[-2].identifierToken.identifier;
std::vector<ASTNode*> nodes; std::vector<ASTNode*> nodes;
@ -69,12 +69,51 @@ namespace hex::lang {
if (!tryConsume(curr, {Token::Type::EndOfExpression})) { if (!tryConsume(curr, {Token::Type::EndOfExpression})) {
for(auto &node : nodes) delete node; for(auto &node : nodes) delete node;
return { }; return nullptr;
} }
return new ASTNodeStruct(structName, nodes); return new ASTNodeStruct(structName, nodes);
} }
ASTNode* parseEnum(TokenIter &curr) {
const std::string &enumName = curr[-4].identifierToken.identifier;
const Token::TypeToken::Type underlyingType = curr[-2].typeToken.type;
if (curr[-3].operatorToken.op != Token::OperatorToken::Operator::Inherit)
return nullptr;
if ((static_cast<u32>(underlyingType) & 0x0F) != 0x00)
return nullptr;
auto enumNode = new ASTNodeEnum(underlyingType, enumName);
while (!tryConsume(curr, {Token::Type::ScopeClose})) {
if (tryConsume(curr, { Token::Type::Identifier, Token::Type::Separator})) {
u64 value;
if (enumNode->getValues().empty())
value = 0;
else
value = enumNode->getValues().back().first + 1;
enumNode->getValues().push_back({ value, curr[-2].identifierToken.identifier });
}
else if (tryConsume(curr, { Token::Type::Identifier, Token::Type::Operator, Token::Type::Integer, Token::Type::Separator})) {
enumNode->getValues().push_back({ curr[-2].integerToken.integer, curr[-4].identifierToken.identifier });
}
else {
delete enumNode;
return nullptr;
}
}
if (!tryConsume(curr, {Token::Type::EndOfExpression})) {
delete enumNode;
return nullptr;
}
return enumNode;
}
ASTNode *parseScope(TokenIter &curr) { ASTNode *parseScope(TokenIter &curr) {
return new ASTNodeScope(parseTillToken(curr, Token::Type::ScopeClose)); return new ASTNodeScope(parseTillToken(curr, Token::Type::ScopeClose));
} }
@ -111,12 +150,27 @@ namespace hex::lang {
if (curr[-3].keywordToken.keyword == Token::KeywordToken::Keyword::Struct) { if (curr[-3].keywordToken.keyword == Token::KeywordToken::Keyword::Struct) {
auto structAst = parseStruct(curr); auto structAst = parseStruct(curr);
if (!structAst.has_value()) { if (structAst == nullptr) {
for(auto &node : program) delete node; for(auto &node : program) delete node;
return { }; return { };
} }
program.push_back(structAst.value()); program.push_back(structAst);
}
return program;
} // Enum
if (tryConsume(curr, { Token::Type::Keyword, Token::Type::Identifier, Token::Type::Operator, Token::Type::Type, Token::Type::ScopeOpen })) {
if (curr[-5].keywordToken.keyword == Token::KeywordToken::Keyword::Enum) {
auto enumAst = parseEnum(curr);
if (enumAst == nullptr) {
for(auto &node : program) delete node;
return { };
}
program.push_back(enumAst);
} }
return program; return program;