Fixed enum parse/evaluate error and crash
This commit is contained in:
parent
c71c610eba
commit
ad40c53eb2
@ -333,7 +333,7 @@ namespace hex::lang {
|
|||||||
[[nodiscard]] const std::unordered_map<std::string, ASTNode*>& getEntries() const { return this->m_entries; }
|
[[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 }); }
|
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:
|
private:
|
||||||
std::unordered_map<std::string, ASTNode*> m_entries;
|
std::unordered_map<std::string, ASTNode*> m_entries;
|
||||||
|
@ -440,13 +440,17 @@ namespace hex::lang {
|
|||||||
entryPatterns.push_back({{ valueNode->getType(), valueNode->getValue() }, name });
|
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;
|
size_t size;
|
||||||
if (auto underlyingType = dynamic_cast<const ASTNodeBuiltinType*>(node->getUnderlyingType()); underlyingType != nullptr)
|
if (auto builtinType = dynamic_cast<ASTNodeBuiltinType*>(underlyingType->getType()); builtinType != nullptr)
|
||||||
size = Token::getTypeSize(underlyingType->getType());
|
size = Token::getTypeSize(builtinType->getType());
|
||||||
else
|
else
|
||||||
throwEvaluateError("invalid enum underlying type");
|
throwEvaluateError("invalid enum underlying type");
|
||||||
|
|
||||||
return new PatternDataEnum(startOffset, size, entryPatterns);
|
return new PatternDataEnum(startOffset, size, entryPatterns);;
|
||||||
}
|
}
|
||||||
|
|
||||||
PatternData* Evaluator::evaluateBitfield(ASTNodeBitfield *node) {
|
PatternData* Evaluator::evaluateBitfield(ASTNodeBitfield *node) {
|
||||||
@ -711,7 +715,7 @@ namespace hex::lang {
|
|||||||
delete result;
|
delete result;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->m_endianStack.pop_back();
|
this->m_endianStack.clear();
|
||||||
}
|
}
|
||||||
} catch (EvaluateError &e) {
|
} catch (EvaluateError &e) {
|
||||||
this->m_consoleLog.emplace_back(ConsoleLogLevel::Error, e);
|
this->m_consoleLog.emplace_back(ConsoleLogLevel::Error, e);
|
||||||
|
@ -454,6 +454,7 @@ namespace hex::lang {
|
|||||||
|
|
||||||
auto underlyingType = dynamic_cast<ASTNodeTypeDecl*>(parseType(-2));
|
auto underlyingType = dynamic_cast<ASTNodeTypeDecl*>(parseType(-2));
|
||||||
if (underlyingType == nullptr) throwParseError("failed to parse type", -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);
|
const auto enumNode = new ASTNodeEnum(underlyingType);
|
||||||
ScopeExit enumGuard([&]{ delete enumNode; });
|
ScopeExit enumGuard([&]{ delete enumNode; });
|
||||||
@ -471,7 +472,7 @@ namespace hex::lang {
|
|||||||
ASTNode *valueExpr;
|
ASTNode *valueExpr;
|
||||||
auto name = getValue<std::string>(-1);
|
auto name = getValue<std::string>(-1);
|
||||||
if (enumNode->getEntries().empty())
|
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
|
else
|
||||||
valueExpr = new ASTNodeNumericExpression(lastEntry->clone(), new ASTNodeIntegerLiteral({ Token::ValueType::Any, s32(1) }), Token::Operator::Plus);
|
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)))
|
else if (MATCHES(sequence(SEPARATOR_ENDOFPROGRAM)))
|
||||||
throwParseError("unexpected end of program", -2);
|
throwParseError("unexpected end of program", -2);
|
||||||
else
|
else
|
||||||
throwParseError("invalid union member", 0);
|
throwParseError("invalid enum entry", -1);
|
||||||
|
|
||||||
if (!MATCHES(sequence(SEPARATOR_COMMA))) {
|
if (!MATCHES(sequence(SEPARATOR_COMMA))) {
|
||||||
if (MATCHES(sequence(SEPARATOR_CURLYBRACKETCLOSE)))
|
if (MATCHES(sequence(SEPARATOR_CURLYBRACKETCLOSE)))
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
throwParseError("missing ',' between enum entries", 0);
|
throwParseError("missing ',' between enum entries", -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user