Git Product home page Git Product logo

Comments (21)

ISSOtm avatar ISSOtm commented on May 12, 2024 1

If #635 is merged, this would look fine:

struct Substatus [
    SubStatus1:: db
    SubStatus2:: db
    SubStatus3:: db
    SubStatus4:: db
    SubStatus5:: db
]

wPlayer:: dstruct Substatus

from rgbds.

Rangi42 avatar Rangi42 commented on May 12, 2024 1

I like that syntax; struct ... ends for definition, struct [[ ... ]] (or object or dstruct) for declaration.

from rgbds.

aaaaaa123456789 avatar aaaaaa123456789 commented on May 12, 2024 1

I should probably comment at this point that struc, at, istruc and the like are all macros in NASM :P

("What do they do", I hear? struc is the easiest to explain: it creates a discarded non-output section with an offset of zero.)

from rgbds.

AntonioND avatar AntonioND commented on May 12, 2024

I think that you can pretty much get the same effect with macros.

ELEMENT : MACRO
\1::
    DB \2
    DW \3
ENDM

    ELEMENT element1, 1, 1234
    ELEMENT element2, 1, 1234

    ld a,[element1+0] ; etc

Yes, sure, it is not very convenient to get the value of a specific field, but that's how I usually do this.

from rgbds.

pinobatch avatar pinobatch commented on May 12, 2024

Does ISSOtm/rgbds-structs do what you want?

from rgbds.

Rangi42 avatar Rangi42 commented on May 12, 2024

Sjasm has structure support similar to how rgbds-structs works.

from rgbds.

Rangi42 avatar Rangi42 commented on May 12, 2024

Here's a rough first draft for how structs might be implemented in rgbasm. I'm trying to reuse existing keywords and keep the syntax similar to what's already there. Suggestions welcome.

struct Foo begins defining a structure's members; endstruct stops that. Inside, you declare labels and allocate space with db/dw/dl/ds as if you're in a RAM section; union/nextu/endu would also be supported. This would define offset constants, rsset-style (although without affecting the value of _RS). No labels are defined and no space is allocated yet though.

Inside a RAM section, you can use dstruct Foo like the db/dw/dl/ds directives. It will then define the struct's member labels and allocate space, prefixing each label with the closest defined label above (which could be a .local one). If that above label is :: exported, so will be all the members.

struct can take a second argument like struct Foo, _ or struct Bar, _m for the separator between its prefix and each member suffix. This would make it compatible with different projects' styles of labeling.

I'm not sure about how sizeof should work yet. TBH I'd be fine without it; you can define a member at the very end of your struct for that, and then do either e.g. ld bc, NPC_Sizeof or ld bc, Player_Sizeof - Player.

Another problem: it would be nice to allow . in member names for creating local member labels (e.g. person.x, person.y, person.z), but a . isn't allowed in constant names for the offset constants.

Example 1:

struct Color
R: db
G: db
B: db ; should not get confused with register B
End:
endstruct

wColorData:
	dstruct Color
.two:
	ds 1 ; padding
	dstruct Color

This would act like:

ColorR EQU 0
ColorG EQU 1
ColorB EQU 2
; TODO: SIZEOF_Color ? #Color ? function-style SIZEOF(Color) ?

wColorData:
wColorDataR: db
wColorDataG: db
wColorDataB: db
wColorDataEnd:
.two:
	ds 1 ; padding
.twoR: db
.twoG: db
.twoB: db
.twoEnd:

Example 2:

struct NPC, _
	YPos:  dw
	XPos:  dw
	YBox:  db
	XBox:  db
	GfxID: db 2
	union
		MovementData: dl 2
	nextu
		AnimData: dl 1
		PalData:  dstruct Color
	endu
endstruct

wMapID::   ds 2
wTileset:: db
wPlayer:: dstruct NPC
wRival:   dstruct NPC

This would act like:

wMapID::   ds 2
wTileset:: db
wPlayer::
wPlayer_YPos::  dw
wPlayer_XPos::  dw
wPlayer_YBox::  db
wPlayer_XBox::  db
wPlayer_GfxID:: db 2
UNION
wPlayer_MovementData:: dl 2
NEXTU
wPlayer_AnimData:: dl 1
wPlayer_PalData::
wPlayer_PalDataR:: db
wPlayer_PalDataG:: db
wPlayer_PalDataB:: db
wPlayer_PalDataEnd::
ENDU
wRival:
wRival_YPos:  dw
wRival_XPos:  dw
wRival_YBox:  db
wRival_XBox:  db
wRival_GfxID: db 2
UNION
wRival_MovementData: dl 2
NEXTU
wRival_AnimData: dl 1
wRival_PalData:
wRival_PalDataR: db
wRival_PalDataG: db
wRival_PalDataB: db
wRival_PalDataEnd:
ENDU

from rgbds.

ISSOtm avatar ISSOtm commented on May 12, 2024

Honestly, end<thing> to end blocks is getting kinda ridiculous. Given that this isn't "flow" syntax, I think using something closer to real blocks would be better—if only due to less global state?

Braces are obviously ineligible, but (single) brackets are fair game. I know it would feel very different from the rest of the syntax, but it's also, in concept, nothing like it anyway.

from rgbds.

Rangi42 avatar Rangi42 commented on May 12, 2024

There's if/endc, rept/endr, macro/endm, union/endu, and load/endl. Other pairs are pushc/popc, pushs/pops, and pusho/popo. I would suggest ends instead of endstruct, but the word "ends" seems likely to be used as a name by someone already.

[[ Double brackets ]] are tentatively going to be for inline fragments, which on the one hand is unusual for multi-line constructs, but on the other hand it goes with inline [ dereferencing ] or ( grouping ).

I don't think a new block construct like this should use brace-style delimiters unless the others are being changed to do the same, like rept 42 [[ ... ]] or macro mac { ... }. Which would be a major version update.

"nothing like it anyway": eh, it reminds me of load/endl blocks, where the labels are declared in one spot but end up going in another.

from rgbds.

eievui5 avatar eievui5 commented on May 12, 2024

I prefer RGBDS Structs' use of bytes, words, and longs over db. A C-like syntax would be ideal either way

struct Structure [
    byte FieldByte
    ; or
    byte[2], FieldWord
]

Then you could do something like this:

u8 EQU byte

struct Enemy [
    u8 health
]

from rgbds.

ISSOtm avatar ISSOtm commented on May 12, 2024

Or just byte[2] FieldWord.

from rgbds.

Rangi42 avatar Rangi42 commented on May 12, 2024

Something like struct Enemy [ byte[2] FieldWord ] looks way too different from typical rgbasm syntax to me.

I'd appreciate if someone could refactor existing WRAM labels into a struct with minimal editing. Like turning this from pokecrystal:

wPlayerSubStatus1:: db
wPlayerSubStatus2:: db
wPlayerSubStatus3:: db
wPlayerSubStatus4:: db
wPlayerSubStatus5:: db

to this:

struct Substatus
SubStatus1:: db
SubStatus2:: db
SubStatus3:: db
SubStatus4:: db
SubStatus5:: db
endstruct

wPlayer:: dstruct Substatus

(That does raise the issue of, "wPlayer is a pretty generic label to define there, people might want it as the prefix to more than one struct." For that the rgbds-structs syntax of dstruct Substatus, wPlayer is better, and there's a parallel between "struct Name, Infix" and "dstruct Name, Prefix".)

from rgbds.

eievui5 avatar eievui5 commented on May 12, 2024

I'm worried about the readability of that. There isn't much point in implementing structs if they're going to be that similar, since you might as well just use macros.

Our goal should be to break the mold a bit, since RGBDS Structs already does most of this.

from rgbds.

Rangi42 avatar Rangi42 commented on May 12, 2024

That looks alright to me. Maybe use double brackets so they stand out more? Presumably it would support union inside. I'd also go with rgbds-structs' dstruct Substatus, wPlayer as said above.

from rgbds.

ISSOtm avatar ISSOtm commented on May 12, 2024

I don't like that syntax because it fails to convey which is the type and which is the name.

Besides, we'd probably also want initializer syntax for ROM data.

PlayerData: struct Substatus [
    0, 1, 2, 3, 4, ; Allow trailing commas
]

EnemyData: struct Substatus [
    Substatus1 = 8, Substatus2 = 7, Substatus3 = 6, Substatus4 = 5, Substatus5 = 4
]

PeonData: struct Substatus [
    Substatus4 = NPC_SUBSTAT4 ; Commas or newlines, or both
    Substatus2 = HIGH(PEON_CONST), Substatus3 = LOW(PEON_CONST),

    ... = 0 ; Syntax for default init...

    Substatus1 = 69 ; ...not necessarily last
]

(RGBDS-structs has a more clunky syntax for initializers, since it's constrained by macro syntax.)

from rgbds.

Rangi42 avatar Rangi42 commented on May 12, 2024

(I edited those wLabels to LabelData, it was confusing at first because they're not WRAM.)

Agreed that a ROM initializer syntax would be useful too. Although I think dstruct should be used for that, so struct defines a new kind of structure, and dstruct uses an existing structure whether in ROM or in RAM.

from rgbds.

eievui5 avatar eievui5 commented on May 12, 2024

This was being discussed again in the discord so I figured I'd contribute my own idea for syntax:

STRUCT NPC
  Name:  ds 16 ; Allocate 16 bytes for a name string
  Health: db 10 ; Default of 10 health, allocate one byte
  Logic: far_pointer $0000 ; Supports macros too!
ENDS

SECTION "ROM definition", ROM0
NewNPC: object NPC [
  Name: "<=16 Letter Name" ; Even if this string is <16 characters, the ds will pad it.
  ; Health is left out, so it just defaults to 10
]

BrokenNPC: object NPC [
  Name: "This name is way too long!!!" ; Error/Warning because the string is too large
]

SECTION "RAM definition", WRAM0
RamNPC: object NPC
  ; Nothing further is needed, RAM will just go off of the default values.

This will allow the use of macros and doesn't require the user to initialize every value if they don't need to.

from rgbds.

Rangi42 avatar Rangi42 commented on May 12, 2024

Syntax from WLA-DX for comparison:

.STRUCT water
    name   ds 8
    age    db
    weight dw
.ENDST

.DSTRUCT waterdrop INSTANCEOF water VALUES
    name:   .db "tingle"
    age:    .db 40
    weight: .dw 120
.ENDST

.STRUCT drop_pair
    waterdrops: instanceof water 2
.ENDST

.DSTRUCT drops INSTANCEOF drop_pair VALUES
    waterdrops.1:        .db "qwertyui" 40
                         .dw 120
    waterdrops.2.name:   .db "tingle"
    waterdrops.2.age:    .db 40
    waterdrops.2.weight: .dw 12
.ENDST

from rgbds.

Rangi42 avatar Rangi42 commented on May 12, 2024

And syntax from NASM:

struc   mytype 
  mt_long:      resd    1 
  mt_word:      resw    1 
  mt_byte:      resb    1 
  mt_str:       resb    32
endstruc

mystruc: 
    istruc mytype 
        at mt_long, dd      123456 
        at mt_word, dw      1024 
        at mt_byte, db      'x' 
        at mt_str,  db      'hello, world', 13, 10, 0 
    iend

from rgbds.

Rangi42 avatar Rangi42 commented on May 12, 2024

And from ca65:

.struct Point
      xcoord  .word
      ycoord  .word
.endstruct

P1:      .tag    Point
P2:      .tag    Point

from rgbds.

Rangi42 avatar Rangi42 commented on May 12, 2024

If we come across a third use case, maybe I'll push to actually implement DISCARD.

Edit: Hmm. I think even with DISCARDable sections, we couldn't write a macro to work that way: it can't iterate over all the labels in a section and use them as locals inside another label (e.g. you type field: ds 3 after a struct NPC, then when you do dstruct Jane, NPC it would define Jane.field). You would have to run macros for each label at the point of definition, and then the invisible section isn't actually gaining you anything since you can't use label syntax (have to do bytes 3, field as rgbds-structs already does).

from rgbds.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.