bass icon indicating copy to clipboard operation
bass copied to clipboard

Implement sections using MultiValueProvider

Open antis81 opened this issue 1 year ago • 2 comments

(moved from PR #42)

The Problem: All bass symbols (global and local) have to be defined in a section ("default" when no section is explicitly defined). Currently SymbolTable is unaware of this dependency and cannot always differentiate the state of a symbol.

In some cases this leads to either of

  • "max number passes" -> this is the situation with my "real-world-project"
  • "false data" -> if a section's PC and/or start evaluate to an "unfortunate" address value - e.g. negative or 0)

The basic idea of MultiValueProvider is to define an "owner" (namely a Section instance) who keeps track of all its symbols while at the same time it is ensured that symbol identifiers are unique and not "already registered" by another MultiValueProvider.

Values can be

  • None values (e.g. a "yet to be defined" section start address)
  • global constant (sub-)symbols (variables are not implemented into bass at this point - ACME implements a !set meta command and also explains where this can be used)
  • built-in (implicit identifiers such as "section.{name}.start")
  • symbols added by bass users (defining global constant/label in the document)

MVP can also be used in 2 ways:

  1. :x: Inherit class Section : public MultyValueProvider { … };
  2. :heavy_check_mark: Add as class memebr class Section { MultyValueProvider mvp_0; … };

~~Currently I don't see a use case for the second approach. Starting with the first one and see if it reveals any restrictions…~~

Decided for variant #2 because it better integrates with current code (and also - theoretically - allows for more complex features such as multiple MVP's in the same class context…)

:bulb: To enable the implementation set USE_BASS_VALUEPROVIDER in CMakeLists.txt.

Have fun experimenting! :microscope:

antis81 avatar Jul 16 '23 20:07 antis81

FYI: Will push current status and let you know when it is "done done". Very close to completing this one with "minimal invasive" approach, but requires a bit of "nasty" debugging in the details ("section_move" test throws with MVP enabled)…

antis81 avatar Jul 18 '23 18:07 antis81

As promised -> "Done Done"! (:partying_face:) The "magic" happens in this line where actually the section start is "synchronized" (copied from std::any -> int32_t) from MVP into the current SymbolTable.

FYI: The Symbol::final case can be realized with ValueSerializer, which only needs to check if a value is None (if (mvp.hasValue("section.default.start") { throw std::runtime_error("Cannot reassing a const symbol") }). Currently not implemented because exactly of what is described above. SymbolTable simply fails here… :slightly_frowning_face:

antis81 avatar Jul 19 '23 14:07 antis81