diff --git a/include/lang/ast_node.hpp b/include/lang/ast_node.hpp index 54a53c0f7..256bd246f 100644 --- a/include/lang/ast_node.hpp +++ b/include/lang/ast_node.hpp @@ -333,7 +333,7 @@ namespace hex::lang { [[nodiscard]] const std::unordered_map& 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 m_entries; diff --git a/source/lang/evaluator.cpp b/source/lang/evaluator.cpp index 80c046761..4b4d57368 100644 --- a/source/lang/evaluator.cpp +++ b/source/lang/evaluator.cpp @@ -440,13 +440,17 @@ namespace hex::lang { entryPatterns.push_back({{ valueNode->getType(), valueNode->getValue() }, name }); } + auto underlyingType = dynamic_cast(node->getUnderlyingType()); + if (underlyingType == nullptr) + throwEvaluateError("enum underlying type was not ASTNodeTypeDecl. This is a bug"); + size_t size; - if (auto underlyingType = dynamic_cast(node->getUnderlyingType()); underlyingType != nullptr) - size = Token::getTypeSize(underlyingType->getType()); + if (auto builtinType = dynamic_cast(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); diff --git a/source/lang/parser.cpp b/source/lang/parser.cpp index 9bc4e208e..53e9ec2d8 100644 --- a/source/lang/parser.cpp +++ b/source/lang/parser.cpp @@ -454,6 +454,7 @@ namespace hex::lang { auto underlyingType = dynamic_cast(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(-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); } }