You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
FAIL "Please start defining a struct, using `define_struct`"
119
132
ENDC
120
133
121
-
field_name_from_id NB_FIELDS
122
-
; Set field name
134
+
get_nth_field_info NB_FIELDS
135
+
; Set field name (keep in mind `STRUCT_FIELD_NAME` is *itself* an EQUS!)
123
136
STRUCT_FIELD_NAME equs "\"\3\""
124
137
PURGE STRUCT_FIELD_NAME
125
138
126
-
; Set field offset
139
+
; Set field offset
127
140
STRUCT_FIELD \2 (\1)
128
-
; Alias this in a human-comprehensive manner
141
+
; Alias this in a human-comprehensive manner
129
142
STRUCT_FIELD_NAME equs "{STRUCT_NAME}_\3"
130
143
STRUCT_FIELD_NAME = STRUCT_FIELD
131
144
132
-
; Calculate field size
145
+
; Compute field size
133
146
CURRENT_RS RB 0
134
147
STRUCT_FIELD_SIZE = CURRENT_RS - STRUCT_FIELD
135
148
136
-
; Set properties
149
+
; Set properties
137
150
STRUCT_FIELD_NBEL = \1
138
151
STRUCT_FIELD_TYPE equs STRSUB("\2",2,1)
139
152
@@ -167,7 +180,7 @@ longs: MACRO
167
180
ENDM
168
181
169
182
170
-
; dstruct struct_type, var_name[, ...]
183
+
; dstruct struct_type, INSTANCE_NAME[, ...]
171
184
; Allocates space for a struct in memory
172
185
; If no further arguments are supplied, the space is simply allocated (using `ds`)
173
186
; Otherwise, the data is written to memory using the appropriate types
@@ -176,66 +189,186 @@ dstruct: MACRO
176
189
NB_FIELDS equs "\1_nb_fields"
177
190
IF !DEF(NB_FIELDS)
178
191
FAIL "Struct \1 isn't defined!"
192
+
ELIF _NARG != 2 && _NARG != NB_FIELDS +2 ; We must have either a RAM declaration (no data args) or a ROM one (RAM args + data args)
193
+
EXPECTED_NARG = 2+ NB_FIELDS
194
+
FAIL "Invalid number of arguments, expected 2 or {EXPECTED_NARG} but got {_NARG}"
195
+
ENDC
196
+
197
+
; Define the two fields required by `get_nth_field_info`
198
+
STRUCT_NAME equs "\1" ; Which struct `get_nth_field_info` should pull info about
199
+
INSTANCE_NAME equs "\2" ; The instance's base name
200
+
201
+
202
+
; RGBASM always expands `\X` macro args, so `IF _NARG > 2 && STRIN("\3", "=")` will error out when there are only 2 args
203
+
; Therefore, the condition is checked here (we can't nest the `IF`s over there because that doesn't translate well to `ELSE`)
204
+
IS_NAMED_INVOCATION = 0
205
+
IF _NARG > 2
206
+
IF STRIN("\3","=")
207
+
IS_NAMED_INVOCATION = 1
208
+
ENDC
179
209
ENDC
180
-
STRUCT_NAME equs "\1" ; Target this struct for `field_name_from_id`
181
-
VAR_NAME equs "\2"
182
210
183
-
VAR_NAME:: ; Declare the struct's root
211
+
IF IS_NAMED_INVOCATION
212
+
; This is a named instantiation, translate that to an ordered one
213
+
; This is needed because data has to be laid out in order, so some translation is needed anyways
214
+
; And finally, it's better to re-use the existing code at the cost of a single nested macro, I believe
215
+
MACRO_CALL equs "dstruct \1, \2" ; This will be used later, but define it now because `SHIFT` will be run
216
+
; In practice `SHIFT` has no effect outside of one when invoked inside of a REPT block, but I hope this behavior is changed (causes a problem elsewhere)
217
+
218
+
ARG_NUM = 3
219
+
REPT NB_FIELDS
220
+
; Find out which argument the current one is
221
+
CUR_ARG equs "\3"
222
+
; Remove all whitespace to obtain something like ".name=value" (whitespace are unnecessary and complexify parsing)
223
+
strreplace CUR_ARG," ",""
224
+
strreplace CUR_ARG,"\t",""
225
+
226
+
EQUAL_POS = STRIN("{CUR_ARG}","=")
227
+
IF EQUAL_POS == 0
228
+
FAIL "Argument #{ARG_NUM} (\3) does not contain an equal sign in this named instantiation"
229
+
ELIF STRCMP(STRSUB("{CUR_ARG}",1,1),".")
230
+
FAIL "Argument #{ARG_NUM} (\3) does not start with a period"
0 commit comments