Skip to content

Commit 4763277

Browse files
committed
FEAT: Including Atronix's source of struct! datatype implementation
1 parent 2fc8b88 commit 4763277

11 files changed

+1241
-13
lines changed

make/rebol3.nest

+1-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ core-files: [
109109
%core/t-pair.c
110110
%core/t-port.c
111111
%core/t-string.c
112-
; %core/t-struct.c ;not implemented
112+
%core/t-struct.c
113113
%core/t-time.c
114114
%core/t-tuple.c
115115
%core/t-typeset.c

src/boot/actions.reb

+1-1
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ remove: action [
311311

312312
change: action [
313313
{Replaces element(s); returns just past the change.}
314-
series [series! gob! port!]{At position (modified)}
314+
series [series! gob! port! struct!]{At position (modified)}
315315
value [any-type!] {The new value}
316316
/part {Limits the amount to change to a given length or position}
317317
length [number! series! pair!]

src/boot/sysobj.reb

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@ catalog: object [
3434
errors: none
3535
; Reflectors are used on boot to create *-of functions
3636
reflectors: [
37-
spec [any-function! any-object! vector! datatype!]
37+
spec [any-function! any-object! vector! datatype! struct!]
3838
body [any-function! any-object! map!]
3939
words [any-function! any-object! map! date!]
40-
values [any-object! map!]
40+
values [any-object! map! struct!]
4141
types [any-function!]
4242
title [any-function! datatype! module!]
4343
]

src/boot/types.reb

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ REBOL [
9999
gob self gob * * * * -
100100
event self event * * * * -
101101
handle self 0 - - - - -
102-
struct invalid 0 - - - - -
102+
struct self struct * * * * -
103103
library invalid 0 - - - - -
104104
utype self utype - - - - -
105105

src/core/f-series.c

+3
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,9 @@
307307
case REB_FUNCTION:
308308
return VAL_FUNC_BODY(s) - VAL_FUNC_BODY(t);
309309

310+
case REB_STRUCT:
311+
return Cmp_Struct(s, t);
312+
310313
case REB_NONE:
311314
case REB_UNSET:
312315
case REB_END:

src/core/m-gc.c

+65-4
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ REBVAL *N_watch(REBFRM *frame, REBVAL **inter_block)
111111
#endif
112112

113113
static void Mark_Series(REBSER *series, REBCNT depth);
114-
114+
static void Mark_Value(REBVAL *val, REBCNT depth);
115115

116116
/***********************************************************************
117117
**
@@ -149,6 +149,69 @@ static void Mark_Series(REBSER *series, REBCNT depth);
149149
}
150150
}
151151

152+
/***********************************************************************
153+
**
154+
*/ static void Mark_Struct_Field(REBSTU *stu, struct Struct_Field *field, REBCNT depth)
155+
/*
156+
***********************************************************************/
157+
{
158+
if (field->type == STRUCT_TYPE_STRUCT) {
159+
int len = 0;
160+
REBSER *series = NULL;
161+
162+
CHECK_MARK(field->fields, depth);
163+
CHECK_MARK(field->spec, depth);
164+
165+
series = field->fields;
166+
for (len = 0; len < series->tail; len++) {
167+
Mark_Struct_Field(stu, (struct Struct_Field *)SERIES_SKIP(series, len), depth + 1);
168+
}
169+
}
170+
else if (field->type == STRUCT_TYPE_REBVAL) {
171+
REBCNT i;
172+
ASSERT2(field->size == sizeof(REBVAL), RP_BAD_SIZE);
173+
for (i = 0; i < field->dimension; i++) {
174+
REBVAL *data = (REBVAL *)SERIES_SKIP(STRUCT_DATA_BIN(stu),
175+
STRUCT_OFFSET(stu) + field->offset + i * field->size);
176+
if (field->done) {
177+
Mark_Value(data, depth);
178+
}
179+
}
180+
}
181+
182+
/* ignore primitive datatypes */
183+
}
184+
185+
/***********************************************************************
186+
**
187+
*/ static void Mark_Struct(REBSTU *stu, REBCNT depth)
188+
/*
189+
***********************************************************************/
190+
{
191+
int len = 0;
192+
REBSER *series = NULL;
193+
if (IS_MARK_SERIES(STRUCT_DATA_BIN(stu))) return;
194+
195+
CHECK_MARK(stu->spec, depth);
196+
CHECK_MARK(stu->fields, depth);
197+
CHECK_MARK(STRUCT_DATA_BIN(stu), depth);
198+
199+
Debug_Num("mark spec: ", (int)stu->spec);
200+
Debug_Num("mark fields:", (int)stu->fields);
201+
Debug_Num("mark bin: ", (int)STRUCT_DATA_BIN(stu));
202+
203+
ASSERT2(IS_BARE_SERIES(stu->data), RP_BAD_SERIES);
204+
ASSERT2(!IS_EXT_SERIES(stu->data), RP_BAD_SERIES);
205+
ASSERT2(SERIES_TAIL(stu->data) == 1, RP_BAD_SERIES);
206+
CHECK_MARK(stu->data, depth);
207+
208+
series = stu->fields;
209+
for (len = 0; len < series->tail; len++) {
210+
struct Struct_Field *field = (struct Struct_Field *)SERIES_SKIP(series, len);
211+
Mark_Struct_Field(stu, field, depth + 1);
212+
}
213+
}
214+
152215

153216
/***********************************************************************
154217
**
@@ -426,9 +489,7 @@ static void Mark_Series(REBSER *series, REBCNT depth);
426489
break;
427490

428491
case REB_STRUCT:
429-
CHECK_MARK(VAL_STRUCT_SPEC(val), depth); // is a block
430-
CHECK_MARK(VAL_STRUCT_VALS(val), depth); // " "
431-
MARK_SERIES(VAL_STRUCT_DATA(val));
492+
Mark_Struct(&VAL_STRUCT(val), depth);
432493
break;
433494

434495
case REB_GOB:

src/core/s-mold.c

+10-1
Original file line numberDiff line numberDiff line change
@@ -1370,14 +1370,23 @@ STOID Mold_Error(REBVAL *value, REB_MOLD *mold, REBFLG molded)
13701370
Mold_Event(value, mold);
13711371
break;
13721372

1373+
case REB_STRUCT:
1374+
{
1375+
REBSER *blk;
1376+
Pre_Mold(value, mold);
1377+
blk = Struct_To_Block(&VAL_STRUCT(value));
1378+
Mold_Block_Series(mold, blk, 0, 0);
1379+
End_Mold(mold);
1380+
}
1381+
break;
1382+
13731383
case REB_HANDLE:
13741384
Mold_Handle(value, mold);
13751385
break;
13761386

13771387
case REB_REBCODE:
13781388
case REB_OP:
13791389
case REB_FRAME:
1380-
case REB_STRUCT:
13811390
case REB_LIBRARY:
13821391
case REB_UTYPE:
13831392
// Value has no printable form, so just print its name.

0 commit comments

Comments
 (0)