gbdev/rgbds

Associate sizes with labels, and add a new way to delimit those sizes

Rangi42 opened this issue · 3 comments

People often think of labels as starting chunks of code/data of a particular size. Examples:

AddNTimes::
; Add bc * a to hl.
	and a
	ret z
.loop
	add hl, bc
	dec a
	jr nz, .loop
	ret
; SIZEOF(AddNTimes) is conceptually 7
; SIZEOF(AddNTimes.loop) is arguably conceptually 4
wFoo:: ds 3
    ds 4 ; unused
wBar:: dw
; SIZEOF(wFoo) is conceptually 3
; SIZEOF(wBar) is conceptually 2

However, there's no way to get SIZEOF(Label) in rgbasm because it's not actually a well-defined concept.

A common heuristic for SIZEOF(GlobalLabel) is "how many bytes til the next global label", but that doesn't always work, as in the wFoo example above.

This isn't proposing any definite solutions yet, but exploring what such a solution could be, if any.

One use case for such a solution would be accurately reporting labels in emulators. You could see ld a, [wFourBytes + 3] instead of ld a, [$c103]. And it could lead to .sym output that's better able to be input for tools like mgbdis, which add :size metadata to symbols.

Something that might work is, using the "distance til next label" heuristic as the default, but allowing the user to end it early.

An ENDSCOPE keyword, or ENDSCOPE <arg> for local labels, would return the current label scope to being nothing. (This is fine; you can continue declaring space/outputting data without a top-level label.)

For example:

AddNTimes::
; Add bc * a to hl.
	and a
	ret z
.loop
	add hl, bc
	dec a
	jr nz, .loop
	ENDSCOPE .loop
	ret
ENDSCOPE

	nop ; unused

TheNextFunction:
	ret

assert SIZEOF(AddNTimes) == 7
assert SIZEOF(AddNTimes.loop) == 4
assert SIZEOF(TheNextFunction) == 1
wFoo:: ds 3
ENDSCOPE wFoo
    ds 4 ; unused
wBar:: dw

assert SIZEOF(wFoo) == 3
assert SIZEOF(wBar) == 2

I am firmly opposed to a ENDSCOPE keyword as cluttering metadata.

As for "size of X" semantics, what is the size of any of these?

MACRO far_ptr
    DW ; Address.
    DB ; Bank.
ENDM

PlayerActor:
wActor0:
.y  DB
.x  DB
.gfx
    far_ptr

I'd argue that there are too many possible interpretations, and that the default behaviour would have to be too complex, that this should not be integrated into RGBASM at all.

...You're right. I could imagine more keyword functionality to control a label's "size", but it would end up being less convenient than LabelEnd - Label.