Skip to content

Commit 4332e1b

Browse files
committed
FEAT: implemented body-of struct reflection (returning struct's key/value pairs)
related to: Oldes/Rebol-issues#2577
1 parent 8c111aa commit 4332e1b

File tree

2 files changed

+39
-6
lines changed

2 files changed

+39
-6
lines changed

src/core/t-struct.c

+35-2
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,38 @@ static void Get_Struct_Values(REBVAL* ret, REBSTU* stu) {
289289
}
290290
}
291291

292+
static void Get_Struct_Body(REBVAL* ret, REBSTU* stu) {
293+
REBVAL* val = NULL;
294+
REBVAL* type_blk = NULL;
295+
REBSER* out, * dim;
296+
struct Struct_Field* field = (struct Struct_Field*)SERIES_DATA(stu->fields);
297+
REBCNT i, n, cnt;
298+
299+
cnt = SERIES_TAIL(stu->fields);
300+
out = Make_Block(cnt*2);
301+
Set_Block(ret, out);
302+
303+
for (i = 0; i < cnt; i++, field++) {
304+
val = Append_Value(out);
305+
Init_Word(val, field->sym);
306+
SET_TYPE(val, REB_SET_WORD);
307+
308+
val = Append_Value(out);
309+
if (field->dimension > 1) {
310+
dim = Make_Block(field->dimension);
311+
SET_TYPE(val, REB_BLOCK);
312+
VAL_SERIES(val) = dim;
313+
for (n = 0; n < field->dimension; n++) {
314+
REBVAL* dv = Append_Value(dim);
315+
get_scalar(stu, field, n, dv);
316+
}
317+
}
318+
else {
319+
get_scalar(stu, field, 0, val);
320+
}
321+
}
322+
}
323+
292324
static REBOOL same_fields(REBSER *tgt, REBSER *src)
293325
{
294326
struct Struct_Field *tgt_fields = (struct Struct_Field *) SERIES_DATA(tgt);
@@ -1140,9 +1172,10 @@ static void init_fields(REBVAL *ret, REBVAL *spec)
11401172
Get_Struct_Values(ret, &VAL_STRUCT(val));
11411173
break;
11421174
case SYM_SPEC:
1143-
case SYM_BODY:
11441175
Set_Block(ret, Clone_Block(VAL_STRUCT_SPEC(val)));
1145-
//Unbind_Block(VAL_BLK(val), TRUE); //???
1176+
break;
1177+
case SYM_BODY:
1178+
Get_Struct_Body(ret, &VAL_STRUCT(val));
11461179
break;
11471180
case SYM_ADDR:
11481181
SET_INTEGER(ret, (REBUPT)SERIES_SKIP(VAL_STRUCT_DATA_BIN(val), VAL_STRUCT_OFFSET(val)));

src/tests/units/struct-test.r3

+4-4
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,11 @@ Rebol [
136136

137137
===start-group=== "Struct reflection"
138138
;@@ https://github.com/Oldes/Rebol-issues/issues/2577
139-
s: make struct! blk: [a: [uint16!] 1 b: [int32!] -1 c: [word!] foo d [uint8! [2]]]
140-
--test-- "body-of struct"
141-
--assert blk = body-of s
139+
s: make struct! spec: [a: [uint16!] 1 b: [int32!] -1 c: [word!] foo d [uint8! [2]]]
142140
--test-- "spec-of struct"
143-
--assert blk = spec-of s
141+
--assert spec = spec-of s
142+
--test-- "body-of struct"
143+
--assert [a: 1 b: -1 c: foo d: [0 0]] = body-of s
144144
--test-- "words-of struct"
145145
--assert [a b c d] = words-of s
146146
--assert [a b c d] = keys-of s

0 commit comments

Comments
 (0)