rgbds icon indicating copy to clipboard operation
rgbds copied to clipboard

[Feature request] A predeclared EQUS symbol for "the current global label"

Open Rangi42 opened this issue 4 years ago • 17 comments

For instance, _GLOBAL or _SCOPE. This would be undefined if there is no current globally scoped label.

This would be useful to avoid repeating names. I've had multiple use cases for code like this:

Foobar:: mac Foobar

In this case mac might be defining more labels that use Foobar as a prefix or suffix. I like to avoid having mac do \1:: to declare the main label itself, since that makes Foobar's definition harder to find.

Or, mac could be mentioning Foobar in some error message. This is useful for macros that don't declare any code/data/labels, but just check assertions about what's already there, like data table lengths or verifying that certain related symbols are defined.

Rangi42 avatar Mar 02 '21 01:03 Rangi42

I'm not a fan of this, tbh. The redundancy is fine, imo, and adding this would mean creating/deleting/updating an extra symbol on every label creation. Plus, given that RGBASM strings are managed so poorly, either defining a label within an EQUS would UAF, or we'd leak crazy amount of memory.

Closing due to the latter reason. May be worth re-opening later, if there's still a need for it.

ISSOtm avatar Mar 02 '21 10:03 ISSOtm

I was expecting this wouldn't need to be updated eagerly, but could reuse whatever access local labels have to their current global scope, only when _GLOBAL/_SCOPE/whatever is evaluated.

I might open a PR if I can get it working without UAF or excessive memory allocation. If not, that's a good reason to close this.

Rangi42 avatar Mar 02 '21 13:03 Rangi42

If it's not updated eagerly, how would it handle the lack of scope?

ISSOtm avatar Mar 02 '21 13:03 ISSOtm

I had in mind using strCallback like __FILE__.

Rangi42 avatar Mar 02 '21 14:03 Rangi42

There's a need for this (see duplicate #1156) unless #1157 is implemented. How do I go about requesting a reopen?

EDIT: I guess I could work around this by writing a preprocessor that redefs __SCOPE__ whenever the global label changes.

pinobatch avatar Aug 17 '23 03:08 pinobatch

Note the previous discussion in PR #776. Given that we don't have some expanded multi-level scope system actually worked out, and there'd still be the concept of a top-level current scope even if we did, I'd still like to see __SCOPE__ added.

Rangi42 avatar Aug 17 '23 04:08 Rangi42

As soon as multi-level scopes are implemented, what constitutes "the current scope" becomes murky: is it

  • the top level,
  • the last label that was defined,
  • or the parent thereof?

Even the __LABEL__ suggested in #1158 would be unclear--at a glance, I'd expect it to be option 2.

I recognise the interest in this feature (see my own macros), but I do not want it implemented in a way that will block multi-level scopes, which is another feature that has garnered interest.

ISSOtm avatar Aug 17 '23 07:08 ISSOtm

I'd say that "the last label" and "the last top-level label" are separate concepts and could warrant separate definitions. And those are very well defined.

aaaaaa123456789 avatar Aug 17 '23 07:08 aaaaaa123456789

Alternative syntax proposed in https://github.com/gbdev/rgbds/issues/506#issuecomment-610909266: . refers to the topmost label. By continuity:

Mult: ; hl = h * e
    ld d, 0
    sla h
    sbc a, a
    and e
    ld l, a
    ld c, 7
.loop
    add hl, hl
    jr nc, ..bitNotSet
    add hl, de
..bitNotSet
    dec c
    jr nz, .loop
    ; At this point:
    ;  - `.` refers to `Mult`
    ;  - `..` refers to `.loop`
    ;  - `...` refers to `..bitNotSet`
    ;  - `....` is undefined
    ret

I like that it meshes well with nested scopes, also that it's consistent with the declaration syntax, but less that it's kind of cryptic. Thoughts?

ISSOtm avatar Aug 17 '23 08:08 ISSOtm

I'd say that's valid for nested scopes, or for when you need to extract a label at a specific level (something that is currently a valid concern already, as we have two levels as it stands). But this doesn't solve the issue of "last label defined", since you'd have to know the level of that label, so that should be separate.

aaaaaa123456789 avatar Aug 17 '23 08:08 aaaaaa123456789

What's the use case for "last label defined"? All I can think of is "offset from a label in the same section", and . is sufficient for that.

ISSOtm avatar Aug 17 '23 08:08 ISSOtm

What's the use case for "last label defined"? All I can think of is "offset from a label in the same section", and . is sufficient for that.

Any macro that shows a message to the user, for instance. (Also, if we're talking about labels being declarable outside their parents' scopes, . might not be in the same section.)

aaaaaa123456789 avatar Aug 17 '23 09:08 aaaaaa123456789

A macro showing a message to the user seems more likely to want to print the top-level label than any local, imo.

. should be in the same section (and defined earlier) for code, which is where I'd see the use case. (Alternatively, STARTOF(SECTION(@))?)

ISSOtm avatar Aug 17 '23 09:08 ISSOtm

The case brought up in #1157 relates to local RAM labels associated to a function (in ROM, naturally), so those would obviously be in separate sections.

aaaaaa123456789 avatar Aug 17 '23 09:08 aaaaaa123456789

Yes, but I don't see why you'd want the offset between those and something in the ROM section.

ISSOtm avatar Aug 17 '23 09:08 ISSOtm

You wouldn't. You'd want the offset between your current address and something, and if your current address is in RAM and . is not, that offset is nonconstant.

aaaaaa123456789 avatar Aug 17 '23 09:08 aaaaaa123456789

Between the current address and something in the same section should be covered by @ - STARTOF(SECTION(@))?

ISSOtm avatar Aug 17 '23 09:08 ISSOtm