Skip to content

Commit 8c111aa

Browse files
committed
FEAT: implemented values-of and words-of struct reflections
1 parent 76c8c09 commit 8c111aa

File tree

3 files changed

+70
-6
lines changed

3 files changed

+70
-6
lines changed

src/boot/sysobj.reb

+2-2
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ catalog: object [
8181
; Reflectors are used on boot to create *-of functions
8282
reflectors: [
8383
spec [any-function! any-object! vector! datatype! struct!]
84-
body [any-function! any-object! map!]
85-
words [any-function! any-object! map! date! handle!]
84+
body [any-function! any-object! map! struct!]
85+
words [any-function! any-object! map! date! handle! struct!]
8686
values [any-object! map! struct!]
8787
types [any-function!]
8888
title [any-function! datatype! module!]

src/core/t-struct.c

+53-4
Original file line numberDiff line numberDiff line change
@@ -224,18 +224,17 @@ static REBFLG get_scalar(REBSTU *stu,
224224
}
225225

226226
/* optional initialization */
227+
val = Append_Value(ser);
227228
if (field->dimension > 1) {
228229
REBSER *dim = Make_Block(1);
229230
REBCNT n = 0;
230-
val = Append_Value(ser);
231231
SET_TYPE(val, REB_BLOCK);
232232
VAL_SERIES(val) = dim;
233233
for (n = 0; n < field->dimension; n ++) {
234234
REBVAL *dv = Append_Value(dim);
235235
get_scalar(stu, field, n, dv);
236236
}
237237
} else {
238-
val = Append_Value(ser);
239238
get_scalar(stu, field, 0, val);
240239
#ifdef ALLOW_CODE_EVALUATION_INSIDE_STRUCT_CONSTRUCTION_SPEC
241240
if (IS_WORD(val)) SET_TYPE(val, REB_LIT_WORD);
@@ -245,6 +244,51 @@ static REBFLG get_scalar(REBSTU *stu,
245244
return ser;
246245
}
247246

247+
static void Get_Struct_Words(REBVAL* ret, REBSTU* stu) {
248+
REBVAL* val = NULL;
249+
REBSER* out;
250+
struct Struct_Field* field = (struct Struct_Field*)SERIES_DATA(stu->fields);
251+
REBCNT i, cnt;
252+
253+
cnt = SERIES_TAIL(stu->fields);
254+
out = Make_Block(cnt);
255+
Set_Block(ret, out);
256+
257+
for (i = 0; i < cnt; i++, field++) {
258+
val = Append_Value(out);
259+
Init_Word(val, field->sym);
260+
SET_TYPE(val, REB_WORD);
261+
}
262+
}
263+
264+
static void Get_Struct_Values(REBVAL* ret, REBSTU* stu) {
265+
REBVAL *val = NULL;
266+
REBVAL *type_blk = NULL;
267+
REBSER *out, *dim;
268+
struct Struct_Field* field = (struct Struct_Field*)SERIES_DATA(stu->fields);
269+
REBCNT i, n, cnt;
270+
271+
cnt = SERIES_TAIL(stu->fields);
272+
out = Make_Block(cnt);
273+
Set_Block(ret, out);
274+
275+
for (i = 0; i < cnt; i++, field++) {
276+
val = Append_Value(out);
277+
if (field->dimension > 1) {
278+
dim = Make_Block(field->dimension);
279+
SET_TYPE(val, REB_BLOCK);
280+
VAL_SERIES(val) = dim;
281+
for (n = 0; n < field->dimension; n++) {
282+
REBVAL* dv = Append_Value(dim);
283+
get_scalar(stu, field, n, dv);
284+
}
285+
}
286+
else {
287+
get_scalar(stu, field, 0, val);
288+
}
289+
}
290+
}
291+
248292
static REBOOL same_fields(REBSER *tgt, REBSER *src)
249293
{
250294
struct Struct_Field *tgt_fields = (struct Struct_Field *) SERIES_DATA(tgt);
@@ -1088,12 +1132,17 @@ static void init_fields(REBVAL *ret, REBVAL *spec)
10881132
{
10891133
REBINT n = VAL_WORD_CANON(arg); // zero on error
10901134
switch (n) {
1135+
case SYM_WORDS:
1136+
Get_Struct_Words(ret, &VAL_STRUCT(val));
1137+
break;
10911138
case SYM_VALUES:
1092-
SET_BINARY(ret, Copy_Series_Part(VAL_STRUCT_DATA_BIN(val), VAL_STRUCT_OFFSET(val), VAL_STRUCT_LEN(val)));
1139+
//SET_BINARY(ret, Copy_Series_Part(VAL_STRUCT_DATA_BIN(val), VAL_STRUCT_OFFSET(val), VAL_STRUCT_LEN(val)));
1140+
Get_Struct_Values(ret, &VAL_STRUCT(val));
10931141
break;
10941142
case SYM_SPEC:
1143+
case SYM_BODY:
10951144
Set_Block(ret, Clone_Block(VAL_STRUCT_SPEC(val)));
1096-
Unbind_Block(VAL_BLK(val), TRUE);
1145+
//Unbind_Block(VAL_BLK(val), TRUE); //???
10971146
break;
10981147
case SYM_ADDR:
10991148
SET_INTEGER(ret, (REBUPT)SERIES_SKIP(VAL_STRUCT_DATA_BIN(val), VAL_STRUCT_OFFSET(val)));

src/tests/units/struct-test.r3

+15
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,21 @@ Rebol [
134134
===end-group===
135135

136136

137+
===start-group=== "Struct reflection"
138+
;@@ 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
142+
--test-- "spec-of struct"
143+
--assert blk = spec-of s
144+
--test-- "words-of struct"
145+
--assert [a b c d] = words-of s
146+
--assert [a b c d] = keys-of s
147+
--test-- "values-of struct"
148+
--assert [1 -1 foo [0 0]] = values-of s
149+
===end-group===
150+
151+
137152
===start-group=== "Struct conversion"
138153
--test-- "to binary! struct!"
139154
s: make struct! [a: [uint16!] 1 b: [int32!] -1]

0 commit comments

Comments
 (0)