1
0
mirror of synced 2025-01-18 17:14:13 +01:00

patterns: Fix enum constant resolution

This commit is contained in:
WerWolv 2021-09-03 02:33:45 +02:00
parent 68d72eac16
commit fcfaaacdcc
4 changed files with 38 additions and 16 deletions

View File

@ -64,7 +64,8 @@ namespace hex::lang {
ASTNode* parseFunctionCall(); ASTNode* parseFunctionCall();
ASTNode* parseStringLiteral(); ASTNode* parseStringLiteral();
std::string parseScopeResolution(); std::string parseNamespaceResolution();
ASTNode* parseScopeResolution();
ASTNode* parseRValue(ASTNodeRValue::Path &path); ASTNode* parseRValue(ASTNodeRValue::Path &path);
ASTNode* parseFactor(); ASTNode* parseFactor();
ASTNode* parseUnaryExpression(); ASTNode* parseUnaryExpression();

View File

@ -104,7 +104,6 @@ namespace hex::lang {
SquareBracketClose, SquareBracketClose,
Comma, Comma,
Dot, Dot,
ScopeResolution,
EndOfExpression, EndOfExpression,
EndOfProgram EndOfProgram
}; };
@ -260,6 +259,5 @@ namespace hex::lang {
#define SEPARATOR_SQUAREBRACKETCLOSE COMPONENT(Separator, SquareBracketClose) #define SEPARATOR_SQUAREBRACKETCLOSE COMPONENT(Separator, SquareBracketClose)
#define SEPARATOR_COMMA COMPONENT(Separator, Comma) #define SEPARATOR_COMMA COMPONENT(Separator, Comma)
#define SEPARATOR_DOT COMPONENT(Separator, Dot) #define SEPARATOR_DOT COMPONENT(Separator, Dot)
#define SEPARATOR_SCOPE_RESOLUTION COMPONENT(Separator, ScopeResolution)
#define SEPARATOR_ENDOFEXPRESSION COMPONENT(Separator, EndOfExpression) #define SEPARATOR_ENDOFEXPRESSION COMPONENT(Separator, EndOfExpression)
#define SEPARATOR_ENDOFPROGRAM COMPONENT(Separator, EndOfProgram) #define SEPARATOR_ENDOFPROGRAM COMPONENT(Separator, EndOfProgram)

View File

@ -314,9 +314,6 @@ namespace hex::lang {
} else if (c == '=') { } else if (c == '=') {
tokens.emplace_back(TOKEN(Operator, Assignment)); tokens.emplace_back(TOKEN(Operator, Assignment));
offset += 1; offset += 1;
} else if (code.substr(offset, 2) == "::") {
tokens.emplace_back(TOKEN(Separator, ScopeResolution));
offset += 2;
} else if (c == ':') { } else if (c == ':') {
tokens.emplace_back(TOKEN(Operator, Inherit)); tokens.emplace_back(TOKEN(Operator, Inherit));
offset += 1; offset += 1;

View File

@ -21,7 +21,7 @@ namespace hex::lang {
// Identifier([(parseMathematicalExpression)|<(parseMathematicalExpression),...>(parseMathematicalExpression)] // Identifier([(parseMathematicalExpression)|<(parseMathematicalExpression),...>(parseMathematicalExpression)]
ASTNode* Parser::parseFunctionCall() { ASTNode* Parser::parseFunctionCall() {
std::string functionName = parseScopeResolution(); std::string functionName = parseNamespaceResolution();
if (!MATCHES(sequence(SEPARATOR_ROUNDBRACKETOPEN))) if (!MATCHES(sequence(SEPARATOR_ROUNDBRACKETOPEN)))
throwParseError("expected '(' after function name"); throwParseError("expected '(' after function name");
@ -56,7 +56,7 @@ namespace hex::lang {
return new ASTNodeStringLiteral(getValue<std::string>(-1)); return new ASTNodeStringLiteral(getValue<std::string>(-1));
} }
std::string Parser::parseScopeResolution() { std::string Parser::parseNamespaceResolution() {
std::string name; std::string name;
while (true) { while (true) {
@ -73,6 +73,27 @@ namespace hex::lang {
return name; return name;
} }
ASTNode* Parser::parseScopeResolution() {
std::string typeName;
while (true) {
typeName += getValue<std::string>(-1);
if (MATCHES(sequence(OPERATOR_SCOPERESOLUTION, IDENTIFIER))) {
if (peek(OPERATOR_SCOPERESOLUTION, 0) && peek(IDENTIFIER, 1)) {
typeName += "::";
continue;
} else {
return new ASTNodeScopeResolution({ typeName, getValue<std::string>(-1) });
}
}
else
break;
}
throwParseError("failed to parse scope resolution. Expected 'TypeName::Identifier'");
}
// <Identifier[.]...> // <Identifier[.]...>
ASTNode* Parser::parseRValue(ASTNodeRValue::Path &path) { ASTNode* Parser::parseRValue(ASTNodeRValue::Path &path) {
if (peek(IDENTIFIER, -1)) if (peek(IDENTIFIER, -1))
@ -108,14 +129,16 @@ namespace hex::lang {
return node; return node;
} else if (MATCHES(sequence(IDENTIFIER))) { } else if (MATCHES(sequence(IDENTIFIER))) {
auto originalPos = this->m_curr; auto originalPos = this->m_curr;
parseScopeResolution(); parseNamespaceResolution();
bool isFunction = peek(SEPARATOR_ROUNDBRACKETOPEN); bool isFunction = peek(SEPARATOR_ROUNDBRACKETOPEN);
this->m_curr = originalPos; this->m_curr = originalPos;
if (isFunction) { if (isFunction) {
return TO_NUMERIC_EXPRESSION(parseFunctionCall()); return TO_NUMERIC_EXPRESSION(this->parseFunctionCall());
} } else if (peek(OPERATOR_SCOPERESOLUTION, 0)) {
else { return TO_NUMERIC_EXPRESSION(this->parseScopeResolution());
} else {
ASTNodeRValue::Path path; ASTNodeRValue::Path path;
return TO_NUMERIC_EXPRESSION(this->parseRValue(path)); return TO_NUMERIC_EXPRESSION(this->parseRValue(path));
} }
@ -431,7 +454,7 @@ namespace hex::lang {
needsSemicolon = false; needsSemicolon = false;
} else if (MATCHES(sequence(IDENTIFIER))) { } else if (MATCHES(sequence(IDENTIFIER))) {
auto originalPos = this->m_curr; auto originalPos = this->m_curr;
parseScopeResolution(); parseNamespaceResolution();
bool isFunction = peek(SEPARATOR_ROUNDBRACKETOPEN); bool isFunction = peek(SEPARATOR_ROUNDBRACKETOPEN);
this->m_curr = originalPos; this->m_curr = originalPos;
@ -598,7 +621,7 @@ namespace hex::lang {
endian = std::endian::big; endian = std::endian::big;
if (MATCHES(sequence(IDENTIFIER))) { // Custom type if (MATCHES(sequence(IDENTIFIER))) { // Custom type
std::string typeName = parseScopeResolution(); std::string typeName = parseNamespaceResolution();
if (this->m_types.contains(typeName)) if (this->m_types.contains(typeName))
return new ASTNodeTypeDecl({ }, this->m_types[typeName]->clone(), endian); return new ASTNodeTypeDecl({ }, this->m_types[typeName]->clone(), endian);
@ -768,7 +791,7 @@ namespace hex::lang {
// enum Identifier : (parseType) { <<Identifier|Identifier = (parseMathematicalExpression)[,]>...> } // enum Identifier : (parseType) { <<Identifier|Identifier = (parseMathematicalExpression)[,]>...> }
ASTNode* Parser::parseEnum() { ASTNode* Parser::parseEnum() {
auto typeName = getNamespacePrefixedName(getValue<std::string>(-2)); auto typeName = getValue<std::string>(-2);
auto underlyingType = parseType(); auto underlyingType = parseType();
if (underlyingType->getEndian().has_value()) throwParseError("underlying type may not have an endian specification", -2); if (underlyingType->getEndian().has_value()) throwParseError("underlying type may not have an endian specification", -2);
@ -779,6 +802,9 @@ namespace hex::lang {
if (this->m_types.contains(typeName)) if (this->m_types.contains(typeName))
throwParseError(hex::format("redefinition of type '{}'", typeName)); throwParseError(hex::format("redefinition of type '{}'", typeName));
if (!MATCHES(sequence(SEPARATOR_CURLYBRACKETOPEN)))
throwParseError("expected '{' after enum definition", -1);
ASTNode *lastEntry = nullptr; ASTNode *lastEntry = nullptr;
while (!MATCHES(sequence(SEPARATOR_CURLYBRACKETCLOSE))) { while (!MATCHES(sequence(SEPARATOR_CURLYBRACKETCLOSE))) {
if (MATCHES(sequence(IDENTIFIER, OPERATOR_ASSIGNMENT))) { if (MATCHES(sequence(IDENTIFIER, OPERATOR_ASSIGNMENT))) {
@ -962,7 +988,7 @@ namespace hex::lang {
else if (peek(IDENTIFIER)) { else if (peek(IDENTIFIER)) {
auto originalPos = this->m_curr; auto originalPos = this->m_curr;
this->m_curr++; this->m_curr++;
parseScopeResolution(); parseNamespaceResolution();
bool isFunction = peek(SEPARATOR_ROUNDBRACKETOPEN); bool isFunction = peek(SEPARATOR_ROUNDBRACKETOPEN);
this->m_curr = originalPos; this->m_curr = originalPos;