Use C++ iterator for fragment/union "pieces" of RGBLINK sections

This commit is contained in:
Rangi
2025-10-05 15:06:17 -04:00
parent 7733ccdeb6
commit 0c9920d4a6
6 changed files with 56 additions and 24 deletions

View File

@@ -49,6 +49,39 @@ struct Section {
std::vector<Symbol> *fileSymbols; std::vector<Symbol> *fileSymbols;
std::vector<Symbol *> symbols; std::vector<Symbol *> symbols;
std::unique_ptr<Section> nextPiece; // The next fragment or union "piece" of this section std::unique_ptr<Section> nextPiece; // The next fragment or union "piece" of this section
private:
// Template class for both const and non-const iterators over the "pieces" of this section
template<typename T>
class PiecesIterable {
T *_firstPiece;
class Iterator {
T *_piece;
public:
explicit Iterator(T *piece) : _piece(piece) {}
Iterator &operator++() {
_piece = _piece->nextPiece.get();
return *this;
}
T &operator*() const { return *_piece; }
bool operator==(Iterator const &rhs) const { return _piece == rhs._piece; }
};
public:
explicit PiecesIterable(T *firstPiece) : _firstPiece(firstPiece) {}
Iterator begin() { return Iterator(_firstPiece); }
Iterator end() { return Iterator(nullptr); }
};
public:
PiecesIterable<Section> pieces() { return PiecesIterable(this); }
PiecesIterable<Section const> pieces() const { return PiecesIterable(this); }
}; };
// Execute a callback for each section currently registered. // Execute a callback for each section currently registered.

View File

@@ -223,12 +223,10 @@ void out_WriteObject() {
putLong(fileStackNodes.size(), file); putLong(fileStackNodes.size(), file);
for (auto it = fileStackNodes.begin(); it != fileStackNodes.end(); ++it) { for (auto it = fileStackNodes.begin(); it != fileStackNodes.end(); ++it) {
FileStackNode const &node = **it; writeFileStackNode(**it, file);
writeFileStackNode(node, file);
// The list is supposed to have decrementing IDs // The list is supposed to have decrementing IDs
assume(it + 1 == fileStackNodes.end() || it[1]->ID == node.ID - 1); assume(it + 1 == fileStackNodes.end() || it[1]->ID == it[0]->ID - 1);
} }
for (Symbol const *sym : objectSymbols) { for (Symbol const *sym : objectSymbols) {

View File

@@ -53,9 +53,9 @@ static void initFreeSpace() {
static void assignSection(Section &section, MemoryLocation const &location) { static void assignSection(Section &section, MemoryLocation const &location) {
// Propagate the assigned location to all UNIONs/FRAGMENTs // Propagate the assigned location to all UNIONs/FRAGMENTs
// so `jr` patches in them will have the correct offset // so `jr` patches in them will have the correct offset
for (Section *piece = &section; piece != nullptr; piece = piece->nextPiece.get()) { for (Section &piece : section.pieces()) {
piece->org = location.address; piece.org = location.address;
piece->bank = location.bank; piece.bank = location.bank;
} }
out_AddSection(section); out_AddSection(section);
} }

View File

@@ -251,8 +251,8 @@ void layout_PlaceSection(std::string const &name, bool isOptional) {
); );
} else { } else {
// SDCC areas don't have a type assigned yet, so the linker script gives them one. // SDCC areas don't have a type assigned yet, so the linker script gives them one.
for (Section *piece = section; piece != nullptr; piece = piece->nextPiece.get()) { for (Section &piece : section->pieces()) {
piece->type = activeType; piece.type = activeType;
} }
} }
} else if (section->type != activeType) { } else if (section->type != activeType) {

View File

@@ -317,13 +317,13 @@ static bool compareSymbols(SortedSymbol const &sym1, SortedSymbol const &sym2) {
template<typename F> template<typename F>
static void forEachSortedSection(SortedSections const &bankSections, F callback) { static void forEachSortedSection(SortedSections const &bankSections, F callback) {
for (Section const *sect : bankSections.zeroLenSections) { for (Section const *sect : bankSections.zeroLenSections) {
for (; sect != nullptr; sect = sect->nextPiece.get()) { for (Section const &piece : sect->pieces()) {
callback(*sect); callback(piece);
} }
} }
for (Section const *sect : bankSections.sections) { for (Section const *sect : bankSections.sections) {
for (; sect != nullptr; sect = sect->nextPiece.get()) { for (Section const &piece : sect->pieces()) {
callback(*sect); callback(piece);
} }
} }
} }
@@ -433,31 +433,32 @@ uint16_t forEachSection(SortedSections const &sectList, F callback) {
return used; return used;
} }
static void writeMapSymbols(Section const *sect) { static void writeMapSymbols(Section const &sect) {
uint16_t org = sect->org; bool announced = true;
for (Section const &piece : sect.pieces()) {
for (bool announced = true; sect != nullptr; sect = sect->nextPiece.get(), announced = false) { for (Symbol *sym : piece.symbols) {
for (Symbol *sym : sect->symbols) {
// Don't output symbols that begin with an illegal character // Don't output symbols that begin with an illegal character
if (sym->name.empty() || !startsIdentifier(sym->name[0])) { if (sym->name.empty() || !startsIdentifier(sym->name[0])) {
continue; continue;
} }
// Announce this "piece" before its contents // Announce this "piece" before its contents
if (!announced) { if (!announced) {
if (sect->modifier == SECTION_UNION) { assume(sect.modifier == piece.modifier);
if (sect.modifier == SECTION_UNION) {
fputs("\t ; Next union\n", mapFile); fputs("\t ; Next union\n", mapFile);
} else if (sect->modifier == SECTION_FRAGMENT) { } else if (sect.modifier == SECTION_FRAGMENT) {
fputs("\t ; Next fragment\n", mapFile); fputs("\t ; Next fragment\n", mapFile);
} }
announced = true; announced = true;
} }
assume(std::holds_alternative<Label>(sym->data)); assume(std::holds_alternative<Label>(sym->data));
uint32_t address = std::get<Label>(sym->data).offset + org; uint32_t address = std::get<Label>(sym->data).offset + sect.org;
// Space matches "\tSECTION: $xxxx ..." // Space matches "\tSECTION: $xxxx ..."
fprintf(mapFile, "\t $%04" PRIx32 " = ", address); fprintf(mapFile, "\t $%04" PRIx32 " = ", address);
writeSymName(sym->name, mapFile); writeSymName(sym->name, mapFile);
putc('\n', mapFile); putc('\n', mapFile);
} }
announced = false;
} }
} }
@@ -487,7 +488,7 @@ static void writeMapBank(SortedSections const &sectList, SectionType type, uint3
if (!options.noSymInMap) { if (!options.noSymInMap) {
// Also print symbols in the following "pieces" // Also print symbols in the following "pieces"
writeMapSymbols(&sect); writeMapSymbols(sect);
} }
}); });

View File

@@ -586,8 +586,8 @@ static void applyPatches(Section &section) {
return; return;
} }
for (Section *piece = &section; piece != nullptr; piece = piece->nextPiece.get()) { for (Section &piece : section.pieces()) {
applyFilePatches(*piece, section); applyFilePatches(piece, section);
} }
} }