diff --git a/lib/include/pl/core/evaluator.hpp b/lib/include/pl/core/evaluator.hpp index 6b7e2b21..b3c3a38d 100644 --- a/lib/include/pl/core/evaluator.hpp +++ b/lib/include/pl/core/evaluator.hpp @@ -303,7 +303,7 @@ namespace pl::core { void createParameterPack(const std::string &name, const std::vector &values); void createArrayVariable(const std::string &name, const ast::ASTNode *type, size_t entryCount, u64 section, bool constant = false); - std::shared_ptr createVariable(const std::string &name, const ast::ASTNodeTypeDecl *type, const std::optional &value = std::nullopt, bool outVariable = false, bool reference = false, bool templateVariable = false, bool constant = false); + std::shared_ptr createVariable(const std::string &name, const pl::core::Location &loc, const ast::ASTNodeTypeDecl *type, const std::optional &value = std::nullopt, bool outVariable = false, bool reference = false, bool templateVariable = false, bool constant = false); std::shared_ptr& getVariableByName(const std::string &name); void setVariable(const std::string &name, const Token::Literal &value); void setVariable(std::shared_ptr &pattern, const Token::Literal &value); diff --git a/lib/include/pl/core/parser.hpp b/lib/include/pl/core/parser.hpp index 978b8d30..b16cc5c9 100644 --- a/lib/include/pl/core/parser.hpp +++ b/lib/include/pl/core/parser.hpp @@ -92,6 +92,13 @@ namespace pl::core { return temp; } + template + hlp::safe_unique_ptr createWithLocation(const Location &loc, Ts&&... ts) { + auto temp = std::make_unique(std::forward(ts)...); + temp->setLocation(loc); + return temp; + } + template hlp::safe_shared_ptr createShared(Ts&&... ts) { auto temp = std::make_shared(std::forward(ts)...); @@ -287,7 +294,6 @@ namespace pl::core { if (!peek(token)) return true; - this->next(); partReset(); return false; } else diff --git a/lib/include/pl/patterns/pattern.hpp b/lib/include/pl/patterns/pattern.hpp index 1d4daba1..51d17548 100644 --- a/lib/include/pl/patterns/pattern.hpp +++ b/lib/include/pl/patterns/pattern.hpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -69,8 +70,8 @@ namespace pl::ptrn { constexpr static u64 InstantiationSectionId = 0xFFFF'FFFF'FFFF'FFFD; Pattern(core::Evaluator *evaluator, u64 offset, size_t size, u32 line) - : m_evaluator(evaluator), m_line(line), m_offset(offset), m_size(size) { - + : m_evaluator(evaluator), m_line(line), m_variableLocation(pl::core::Location::Empty()), + m_offset(offset), m_size(size) { if (evaluator != nullptr) { this->m_color = evaluator->getNextPatternColor(); this->m_manualColor = false; @@ -93,6 +94,7 @@ namespace pl::ptrn { this->m_initialized = other.m_initialized; this->m_constant = other.m_constant; this->m_variableName = other.m_variableName; + this->m_variableLocation = other.m_variableLocation; this->m_typeName = other.m_typeName; this->m_reference = other.m_reference; this->m_parent = other.m_parent; @@ -154,14 +156,19 @@ namespace pl::ptrn { return *this->m_variableName; } + pl::core::Location getVariableLocation() const { + return m_variableLocation; + } + [[nodiscard]] bool hasVariableName() const { return getEvaluator()->isStringPoolEntryValid(this->m_variableName); } - void setVariableName(const std::string &name) { + void setVariableName(const std::string &name, pl::core::Location loc = pl::core::Location()) { if (!name.empty()) { auto [it, inserted] = m_evaluator->getStringPool().emplace(name); this->m_variableName = it; + this->m_variableLocation = loc; } } @@ -633,6 +640,7 @@ namespace pl::ptrn { u32 m_line = 0; std::set::const_iterator m_variableName; + pl::core::Location m_variableLocation; std::set::const_iterator m_typeName; std::optional m_arrayIndex; diff --git a/lib/include/pl/patterns/pattern_array_static.hpp b/lib/include/pl/patterns/pattern_array_static.hpp index 4e5d004c..acda5bde 100644 --- a/lib/include/pl/patterns/pattern_array_static.hpp +++ b/lib/include/pl/patterns/pattern_array_static.hpp @@ -85,7 +85,7 @@ namespace pl::ptrn { std::shared_ptr highlightTemplate = this->m_template->clone(); - highlightTemplate->setVariableName(this->getVariableName()); + highlightTemplate->setVariableName(this->getVariableName(), this->getVariableLocation()); highlightTemplate->setOffset(this->getOffset()); const auto &children = this->m_highlightTemplates.emplace_back(std::move(highlightTemplate))->getChildren(); diff --git a/lib/include/pl/patterns/pattern_pointer.hpp b/lib/include/pl/patterns/pattern_pointer.hpp index 787d3c00..7b6ffc1d 100644 --- a/lib/include/pl/patterns/pattern_pointer.hpp +++ b/lib/include/pl/patterns/pattern_pointer.hpp @@ -75,7 +75,7 @@ namespace pl::ptrn { void setPointedAtPattern(std::shared_ptr &&pattern) { this->m_pointedAt = std::move(pattern); - this->m_pointedAt->setVariableName(fmt::format("*({})", this->getVariableName())); + this->m_pointedAt->setVariableName(fmt::format("*({})", this->getVariableName()), this->getVariableLocation()); this->m_pointedAt->setOffset(u64(this->m_pointedAtAddress)); if (this->hasOverriddenColor()) diff --git a/lib/source/pl/core/ast/ast_node_array_variable_decl.cpp b/lib/source/pl/core/ast/ast_node_array_variable_decl.cpp index b10309de..b0d8fddf 100644 --- a/lib/source/pl/core/ast/ast_node_array_variable_decl.cpp +++ b/lib/source/pl/core/ast/ast_node_array_variable_decl.cpp @@ -19,7 +19,8 @@ namespace pl::core::ast { ASTNodeArrayVariableDecl::ASTNodeArrayVariableDecl(std::string name, std::shared_ptr type, std::unique_ptr &&size, std::unique_ptr &&placementOffset, std::unique_ptr &&placementSection, bool constant) - :m_name(std::move(name)), m_type(std::move(type)), m_size(std::move(size)), m_placementOffset(std::move(placementOffset)), m_placementSection(std::move(placementSection)), m_constant(constant) { } + :m_name(std::move(name)), m_type(std::move(type)), m_size(std::move(size)), m_placementOffset(std::move(placementOffset)), m_placementSection(std::move(placementSection)), m_constant(constant) { + } ASTNodeArrayVariableDecl::ASTNodeArrayVariableDecl(const ASTNodeArrayVariableDecl &other) : ASTNode(other), Attributable(other) { this->m_name = other.m_name; @@ -230,7 +231,7 @@ namespace pl::core::ast { outputPattern = std::move(arrayPattern); } - outputPattern->setVariableName(this->m_name); + outputPattern->setVariableName(this->m_name, this->getLocation()); if (templatePattern->hasOverriddenEndian()) outputPattern->setEndian(templatePattern->getEndian()); outputPattern->setTypeName(templatePattern->getTypeName()); @@ -257,7 +258,7 @@ namespace pl::core::ast { evaluator->alignToByte(); auto arrayPattern = std::make_unique(evaluator, evaluator->getReadOffset(), 0, getLocation().line); - arrayPattern->setVariableName(this->m_name); + arrayPattern->setVariableName(this->m_name, this->getLocation()); arrayPattern->setSection(evaluator->getSectionId()); std::vector> entries; diff --git a/lib/source/pl/core/ast/ast_node_bitfield_array_variable_decl.cpp b/lib/source/pl/core/ast/ast_node_bitfield_array_variable_decl.cpp index 7d82fa32..06cbe44f 100644 --- a/lib/source/pl/core/ast/ast_node_bitfield_array_variable_decl.cpp +++ b/lib/source/pl/core/ast/ast_node_bitfield_array_variable_decl.cpp @@ -54,7 +54,7 @@ namespace pl::core::ast { auto position = evaluator->getBitwiseReadOffset(); auto arrayPattern = std::make_shared(evaluator, position.byteOffset, position.bitOffset, 0, getLocation().line); - arrayPattern->setVariableName(this->m_name); + arrayPattern->setVariableName(this->m_name, this->getLocation()); arrayPattern->setSection(evaluator->getSectionId()); arrayPattern->setReversed(evaluator->isReadOrderReversed()); @@ -65,7 +65,7 @@ namespace pl::core::ast { auto addEntries = [&](std::vector> &&patterns) { for (auto &pattern : patterns) { - pattern->setVariableName(fmt::format("[{}]", entryIndex)); + pattern->setVariableName(fmt::format("[{}]", entryIndex), pattern->getVariableLocation()); pattern->setEndian(arrayPattern->getEndian()); if (pattern->getSection() == ptrn::Pattern::MainSectionId) pattern->setSection(arrayPattern->getSection()); diff --git a/lib/source/pl/core/ast/ast_node_bitfield_field.cpp b/lib/source/pl/core/ast/ast_node_bitfield_field.cpp index e887bfec..af076def 100644 --- a/lib/source/pl/core/ast/ast_node_bitfield_field.cpp +++ b/lib/source/pl/core/ast/ast_node_bitfield_field.cpp @@ -45,7 +45,7 @@ namespace pl::core::ast { auto position = evaluator->getBitwiseReadOffsetAndIncrement(bitSize); auto pattern = this->createBitfield(evaluator, position.byteOffset, position.bitOffset, bitSize); pattern->setPadding(this->isPadding()); - pattern->setVariableName(this->getName()); + pattern->setVariableName(this->getName(), this->getLocation()); pattern->setEndian(evaluator->getDefaultEndian()); pattern->setSection(evaluator->getSectionId()); diff --git a/lib/source/pl/core/ast/ast_node_function_call.cpp b/lib/source/pl/core/ast/ast_node_function_call.cpp index 5d541cd8..ef18f449 100644 --- a/lib/source/pl/core/ast/ast_node_function_call.cpp +++ b/lib/source/pl/core/ast/ast_node_function_call.cpp @@ -96,7 +96,7 @@ namespace pl::core::ast { for (size_t i = 0; i < variables.size(); i++) { auto &[pattern, name] = variables[i]; - pattern->setVariableName(name); + pattern->setVariableName(name, pattern->getVariableLocation()); } }; diff --git a/lib/source/pl/core/ast/ast_node_function_definition.cpp b/lib/source/pl/core/ast/ast_node_function_definition.cpp index a95c8f52..ce95cd27 100644 --- a/lib/source/pl/core/ast/ast_node_function_definition.cpp +++ b/lib/source/pl/core/ast/ast_node_function_definition.cpp @@ -77,7 +77,7 @@ namespace pl::core::ast { std::vector, std::string>> originalNames; ON_SCOPE_EXIT { for (auto &[variable, name] : originalNames) { - variable->setVariableName(name); + variable->setVariableName(name, variable->getVariableLocation()); } }; for (u32 paramIndex = 0; paramIndex < this->m_params.size() && paramIndex < params.size(); paramIndex++) { @@ -89,7 +89,7 @@ namespace pl::core::ast { if (params[paramIndex].isString()) reference = false; - auto variable = ctx->createVariable(name, typeNode, params[paramIndex], false, reference); + auto variable = ctx->createVariable(name, type->getLocation(), typeNode, params[paramIndex], false, reference); if (reference && params[paramIndex].isPattern()) { auto pattern = params[paramIndex].toPattern(); @@ -100,7 +100,8 @@ namespace pl::core::ast { ctx->setVariable(name, params[paramIndex]); originalNames.emplace_back(variable, name); - variable->setVariableName(name); + + variable->setVariableName(name, type->getLocation()); ctx->setCurrentControlFlowStatement(ControlFlowStatement::None); } diff --git a/lib/source/pl/core/ast/ast_node_multi_variable_decl.cpp b/lib/source/pl/core/ast/ast_node_multi_variable_decl.cpp index 9e76bedd..fe8bd85f 100644 --- a/lib/source/pl/core/ast/ast_node_multi_variable_decl.cpp +++ b/lib/source/pl/core/ast/ast_node_multi_variable_decl.cpp @@ -32,7 +32,7 @@ namespace pl::core::ast { auto variableDecl = dynamic_cast(variable.get()); auto variableType = variableDecl->getType(); - evaluator->createVariable(variableDecl->getName(), variableType.get()); + evaluator->createVariable(variableDecl->getName(), this->getLocation(), variableType.get()); } return std::nullopt; diff --git a/lib/source/pl/core/ast/ast_node_pointer_variable_decl.cpp b/lib/source/pl/core/ast/ast_node_pointer_variable_decl.cpp index 427625b6..8e5e0b83 100644 --- a/lib/source/pl/core/ast/ast_node_pointer_variable_decl.cpp +++ b/lib/source/pl/core/ast/ast_node_pointer_variable_decl.cpp @@ -68,7 +68,7 @@ namespace pl::core::ast { sizePattern->setSection(evaluator->getSectionId()); auto pattern = std::make_shared(evaluator, pointerStartOffset, sizePattern->getSize(), getLocation().line); - pattern->setVariableName(this->m_name); + pattern->setVariableName(this->m_name, this->getLocation()); pattern->setPointerTypePattern(std::move(sizePattern)); ON_SCOPE_EXIT { diff --git a/lib/source/pl/core/ast/ast_node_rvalue.cpp b/lib/source/pl/core/ast/ast_node_rvalue.cpp index d3eb73d3..5850ee55 100644 --- a/lib/source/pl/core/ast/ast_node_rvalue.cpp +++ b/lib/source/pl/core/ast/ast_node_rvalue.cpp @@ -140,7 +140,7 @@ namespace pl::core::ast { if (auto transformFunc = evaluator->findFunction(pattern->getTransformFunction()); transformFunc.has_value()) { auto oldPatternName = pattern->getVariableName(); auto result = transformFunc->func(evaluator, { std::move(literal) }); - pattern->setVariableName(oldPatternName); + pattern->setVariableName(oldPatternName, pattern->getVariableLocation()); if (!result.has_value()) err::E0009.throwError("Transform function did not return a value.", "Try adding a 'return ;' statement in all code paths.", this->getLocation()); diff --git a/lib/source/pl/core/ast/ast_node_type_decl.cpp b/lib/source/pl/core/ast/ast_node_type_decl.cpp index 7db99ca1..e5d8deda 100644 --- a/lib/source/pl/core/ast/ast_node_type_decl.cpp +++ b/lib/source/pl/core/ast/ast_node_type_decl.cpp @@ -141,7 +141,7 @@ namespace pl::core::ast { this->m_currTemplateParameterType->setLocation(lvalue->getLocation()); - auto variable = evaluator->createVariable(lvalue->getLValueName(), this->m_currTemplateParameterType.get(), value, false, value.isPattern(), true, true); + auto variable = evaluator->createVariable(lvalue->getLValueName(), lvalue->getLocation(), this->m_currTemplateParameterType.get(), value, false, value.isPattern(), true, true); if (variable != nullptr) { variable->setInitialized(false); evaluator->setVariable(variable, value); diff --git a/lib/source/pl/core/ast/ast_node_variable_decl.cpp b/lib/source/pl/core/ast/ast_node_variable_decl.cpp index 074a5cbc..a08348a4 100644 --- a/lib/source/pl/core/ast/ast_node_variable_decl.cpp +++ b/lib/source/pl/core/ast/ast_node_variable_decl.cpp @@ -72,7 +72,7 @@ namespace pl::core::ast { if (this->m_placementOffset != nullptr && dynamic_cast(pattern.get()) != nullptr) err::E0005.throwError(fmt::format("Variables of type 'str' cannot be placed in memory.", this->m_name), { }, this->getLocation()); - pattern->setVariableName(this->m_name); + pattern->setVariableName(this->m_name, this->getLocation()); if (this->m_placementSection != nullptr) pattern->setSection(evaluator->getSectionId()); @@ -126,7 +126,8 @@ namespace pl::core::ast { auto startOffset = evaluator->getBitwiseReadOffset(); - evaluator->createVariable(this->getName(), this->getType().get(), { }, this->m_outVariable, false, false, this->m_constant); + // TODO: debug-menu: can get location here. + evaluator->createVariable(this->getName(), this->getLocation(), this->getType().get(), { }, this->m_outVariable, false, false, this->m_constant); auto &variable = evaluator->getScope(0).scope->back(); std::vector> initValues; diff --git a/lib/source/pl/core/evaluator.cpp b/lib/source/pl/core/evaluator.cpp index 4467c362..07d41ea6 100644 --- a/lib/source/pl/core/evaluator.cpp +++ b/lib/source/pl/core/evaluator.cpp @@ -271,7 +271,7 @@ namespace pl::core { pattern->setSection(section); } - pattern->setVariableName(name); + pattern->setVariableName(name, pattern->getVariableLocation()); if (this->isDebugModeEnabled()) this->getConsole().log(LogConsole::Level::Debug, fmt::format("Creating local array variable '{} {}[{}]' at heap address 0x{:X}.", pattern->getTypeName(), pattern->getVariableName(), entryCount, pattern->getOffset())); @@ -352,7 +352,7 @@ namespace pl::core { } } - std::shared_ptr Evaluator::createVariable(const std::string &name, const ast::ASTNodeTypeDecl *type, const std::optional &value, bool outVariable, bool reference, bool templateVariable, bool constant) { + std::shared_ptr Evaluator::createVariable(const std::string &name, const pl::core::Location &loc, const ast::ASTNodeTypeDecl *type, const std::optional &value, bool outVariable, bool reference, bool templateVariable, bool constant) { auto startPos = this->getBitwiseReadOffset(); ON_SCOPE_EXIT { this->setBitwiseReadOffset(startPos); }; @@ -433,7 +433,7 @@ namespace pl::core { } } - pattern->setVariableName(name); + pattern->setVariableName(name, loc); if (!reference) { pattern->setSection(sectionId); @@ -599,7 +599,7 @@ namespace pl::core { // Keep the old variable until the new one is ref-counted, so we don't delete storage. auto oldVariable = std::exchange(variablePattern, value->clone()); - variablePattern->setVariableName(name); + variablePattern->setVariableName(name, variablePattern->getVariableLocation()); variablePattern->setReference(reference); if (!reference) { @@ -647,12 +647,13 @@ namespace pl::core { auto section = pattern->getSection(); auto offset = pattern->getOffset(); auto variableName = pattern->getVariableName(); + auto variableLocation = pattern->getVariableLocation(); pattern = std::move(newPattern); pattern->setSection(section); pattern->setOffset(offset); - pattern->setVariableName(variableName); + pattern->setVariableName(variableName, variableLocation); } void Evaluator::setVariable(std::shared_ptr &pattern, const Token::Literal &variableValue) { diff --git a/lib/source/pl/core/parser.cpp b/lib/source/pl/core/parser.cpp index 2d2ab26f..a2a5d143 100644 --- a/lib/source/pl/core/parser.cpp +++ b/lib/source/pl/core/parser.cpp @@ -1700,8 +1700,9 @@ namespace pl::core { // (parseType) Identifier[(parseMathematicalExpression)] hlp::safe_unique_ptr Parser::parseMemberArrayVariable(const hlp::safe_shared_ptr &type, bool constant) { + auto &nameToken = m_curr[-2]; auto name = getValue(-2).get(); - auto memberIdentifier = std::get_if(&((m_curr[-2]).value)); + auto memberIdentifier = std::get_if(&nameToken.value); hlp::safe_unique_ptr size; @@ -1778,7 +1779,7 @@ namespace pl::core { else memberIdentifier->setType(Token::Identifier::IdentifierType::PatternVariable); } - return create(name, type.unwrapUnchecked(), std::move(size.unwrapUnchecked()), nullptr, nullptr, constant); + return createWithLocation(nameToken.location, name, type.unwrapUnchecked(), std::move(size.unwrapUnchecked()), nullptr, nullptr, constant); } // (parseType) *Identifier : (parseType) @@ -2147,6 +2148,7 @@ namespace pl::core { } else if (const auto identifierOffset = parseCompoundAssignment(tkn::Literal::Identifier); identifierOffset.has_value()) member = parseFunctionVariableCompoundAssignment(getValue(*identifierOffset).get()); else if (MATCHES(optional(tkn::Keyword::Unsigned) && sequence(tkn::Literal::Identifier, tkn::Operator::Colon))) { + auto identToken = m_curr[-2]; auto fieldName = getValue(-2).get(); auto identifier = std::get_if(&((m_curr[-2]).value)); if (identifier != nullptr) @@ -2156,7 +2158,7 @@ namespace pl::core { if (bitfieldSize == nullptr) return nullptr; - member = create(fieldName, std::move(bitfieldSize)); + member = createWithLocation(identToken.location, fieldName, std::move(bitfieldSize)); } else if (sequence(tkn::Keyword::Signed, tkn::Literal::Identifier, tkn::Operator::Colon)) { auto fieldName = getValue(-2).get(); auto identifier = std::get_if(&((m_curr[-2]).value));