1
0
mirror of synced 2024-11-24 15:50:16 +01:00

Fixed enum parse/evaluate error and crash

This commit is contained in:
WerWolv 2021-01-10 17:14:38 +01:00
parent c71c610eba
commit ad40c53eb2
3 changed files with 13 additions and 8 deletions

View File

@ -333,7 +333,7 @@ namespace hex::lang {
[[nodiscard]] const std::unordered_map<std::string, ASTNode*>& getEntries() const { return this->m_entries; }
void addEntry(const std::string &name, ASTNode* expression) { this->m_entries.insert({ name, expression }); }
[[nodiscard]] const ASTNode *getUnderlyingType() const { return this->m_underlyingType; }
[[nodiscard]] ASTNode *getUnderlyingType() { return this->m_underlyingType; }
private:
std::unordered_map<std::string, ASTNode*> m_entries;

View File

@ -440,13 +440,17 @@ namespace hex::lang {
entryPatterns.push_back({{ valueNode->getType(), valueNode->getValue() }, name });
}
auto underlyingType = dynamic_cast<ASTNodeTypeDecl*>(node->getUnderlyingType());
if (underlyingType == nullptr)
throwEvaluateError("enum underlying type was not ASTNodeTypeDecl. This is a bug");
size_t size;
if (auto underlyingType = dynamic_cast<const ASTNodeBuiltinType*>(node->getUnderlyingType()); underlyingType != nullptr)
size = Token::getTypeSize(underlyingType->getType());
if (auto builtinType = dynamic_cast<ASTNodeBuiltinType*>(underlyingType->getType()); builtinType != nullptr)
size = Token::getTypeSize(builtinType->getType());
else
throwEvaluateError("invalid enum underlying type");
return new PatternDataEnum(startOffset, size, entryPatterns);
return new PatternDataEnum(startOffset, size, entryPatterns);;
}
PatternData* Evaluator::evaluateBitfield(ASTNodeBitfield *node) {
@ -711,7 +715,7 @@ namespace hex::lang {
delete result;
}
this->m_endianStack.pop_back();
this->m_endianStack.clear();
}
} catch (EvaluateError &e) {
this->m_consoleLog.emplace_back(ConsoleLogLevel::Error, e);

View File

@ -454,6 +454,7 @@ namespace hex::lang {
auto underlyingType = dynamic_cast<ASTNodeTypeDecl*>(parseType(-2));
if (underlyingType == nullptr) throwParseError("failed to parse type", -2);
if (underlyingType->getEndian().has_value()) throwParseError("underlying type may not have an endian specification", -2);
const auto enumNode = new ASTNodeEnum(underlyingType);
ScopeExit enumGuard([&]{ delete enumNode; });
@ -471,7 +472,7 @@ namespace hex::lang {
ASTNode *valueExpr;
auto name = getValue<std::string>(-1);
if (enumNode->getEntries().empty())
lastEntry = TO_NUMERIC_EXPRESSION(new ASTNodeIntegerLiteral({ Token::ValueType::Unsigned8Bit, u8(0) }));
valueExpr = lastEntry = TO_NUMERIC_EXPRESSION(new ASTNodeIntegerLiteral({ Token::ValueType::Unsigned8Bit, u8(0) }));
else
valueExpr = new ASTNodeNumericExpression(lastEntry->clone(), new ASTNodeIntegerLiteral({ Token::ValueType::Any, s32(1) }), Token::Operator::Plus);
@ -480,13 +481,13 @@ namespace hex::lang {
else if (MATCHES(sequence(SEPARATOR_ENDOFPROGRAM)))
throwParseError("unexpected end of program", -2);
else
throwParseError("invalid union member", 0);
throwParseError("invalid enum entry", -1);
if (!MATCHES(sequence(SEPARATOR_COMMA))) {
if (MATCHES(sequence(SEPARATOR_CURLYBRACKETCLOSE)))
break;
else
throwParseError("missing ',' between enum entries", 0);
throwParseError("missing ',' between enum entries", -1);
}
}