Skip to content

Commit 319531e

Browse files
committed
FEAT: add support for word! struct fields
1 parent 854e06e commit 319531e

File tree

3 files changed

+36
-1
lines changed

3 files changed

+36
-1
lines changed

src/core/t-struct.c

+28-1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ static const REBINT type_to_sym [STRUCT_TYPE_MAX] = {
5454

5555
SYM_POINTER,
5656
-1, //SYM_STRUCT
57+
SYM_WORD_TYPE,
5758
//SYM_REBVAL // unused
5859
//STRUCT_TYPE_MAX
5960
};
@@ -110,6 +111,9 @@ static get_scalar(REBSTU *stu,
110111
VAL_STRUCT_LEN(val) = field->size;
111112
}
112113
break;
114+
case STRUCT_TYPE_WORD:
115+
Set_Word(val, *(REBINT *)data, NULL, 0);
116+
break;
113117
#ifdef unused
114118
case STRUCT_TYPE_REBVAL:
115119
memcpy(val, data, sizeof(REBVAL));
@@ -232,6 +236,7 @@ static get_scalar(REBSTU *stu,
232236
} else {
233237
val = Append_Value(ser);
234238
get_scalar(stu, field, 0, val);
239+
if (IS_WORD(val)) SET_TYPE(val, REB_LIT_WORD);
235240
}
236241
}
237242
return ser;
@@ -303,6 +308,12 @@ static REBOOL assign_scalar(REBSTU *stu,
303308
Trap_Type(val);
304309
}
305310
break;
311+
case REB_WORD:
312+
if (STRUCT_TYPE_WORD != field->type) {
313+
Trap_Type(val);
314+
}
315+
i = (u64)VAL_WORD_SYM(val);
316+
break;
306317
default:
307318
Trap_Type(val);
308319
}
@@ -324,6 +335,7 @@ static REBOOL assign_scalar(REBSTU *stu,
324335
*(i32*)data = (i32)i;
325336
break;
326337
case STRUCT_TYPE_UINT32:
338+
case STRUCT_TYPE_WORD:
327339
*(u32*)data = (u32)i;
328340
break;
329341
case STRUCT_TYPE_INT64:
@@ -581,6 +593,10 @@ static REBOOL parse_field_type(struct Struct_Field *field, REBVAL *spec, REBVAL
581593
Trap_Types(RE_EXPECT_VAL, REB_BLOCK, VAL_TYPE(val));
582594
}
583595
break;
596+
case SYM_WORD_TYPE:
597+
field->type = STRUCT_TYPE_WORD;
598+
field->size = 4;
599+
break;
584600
#ifdef unused
585601
case SYM_REBVAL:
586602
field->type = STRUCT_TYPE_REBVAL;
@@ -764,7 +780,17 @@ static REBOOL parse_field_type(struct Struct_Field *field, REBVAL *spec, REBVAL
764780
for (n = 0; n < field->dimension; n ++) {
765781
memcpy(SERIES_SKIP(VAL_STRUCT_DATA_BIN(out), ((REBCNT)offset) + n * field->size), SERIES_DATA(VAL_STRUCT_DATA_BIN(init)), field->size);
766782
}
767-
} else if (field->type == STRUCT_TYPE_REBVAL) {
783+
}
784+
else if (field->type == STRUCT_TYPE_WORD) {
785+
// use word `none` as a default value
786+
REBCNT n = 0;
787+
REBCNT sym = SYM_NONE;
788+
for (n = 0; n < field->dimension; n++) {
789+
memcpy(SERIES_SKIP(VAL_STRUCT_DATA_BIN(out), ((REBCNT)offset) + n * field->size), &sym, field->size);
790+
}
791+
}
792+
else if (field->type == STRUCT_TYPE_REBVAL) {
793+
#ifdef unused
768794
REBVAL unset;
769795
REBCNT n = 0;
770796
SET_UNSET(&unset);
@@ -774,6 +800,7 @@ static REBOOL parse_field_type(struct Struct_Field *field, REBVAL *spec, REBVAL
774800
goto failed;
775801
}
776802
}
803+
#endif
777804
} else {
778805
memset(SERIES_SKIP(VAL_STRUCT_DATA_BIN(out), (REBCNT)offset), 0, field->size * field->dimension);
779806
}

src/include/reb-struct.h

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ enum {
4343

4444
STRUCT_TYPE_POINTER,
4545
STRUCT_TYPE_STRUCT,
46+
STRUCT_TYPE_WORD,
4647
STRUCT_TYPE_REBVAL,
4748
STRUCT_TYPE_MAX
4849
};

src/tests/units/struct-test.r3

+7
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Rebol [
2020
u64: make struct! [a [uint64!]]
2121
f32: make struct! [a [float!]]
2222
f64: make struct! [a [double!]]
23+
w: make struct! [a [word!]]
2324
]
2425
--assert 1 = length? i8
2526
--assert 2 = length? i16
@@ -31,6 +32,7 @@ Rebol [
3132
--assert 8 = length? u64
3233
--assert 4 = length? f32
3334
--assert 8 = length? f64
35+
--assert 4 = length? w
3436
--assert (mold i8 ) = "make struct! [a: [int8!] 0]"
3537
--assert (mold i16) = "make struct! [a: [int16!] 0]"
3638
--assert (mold i32) = "make struct! [a: [int32!] 0]"
@@ -41,6 +43,7 @@ Rebol [
4143
--assert (mold u64) = "make struct! [a: [uint64!] 0]"
4244
--assert (mold f32) = "make struct! [a: [float!] 0.0]"
4345
--assert (mold f64) = "make struct! [a: [double!] 0.0]"
46+
--assert (mold w) = "make struct! [a: [word!] 'none]"
4447
===end-group===
4548

4649

@@ -56,6 +59,7 @@ Rebol [
5659
u64x2: make struct! [a [uint64! [2]]]
5760
f32x2: make struct! [a [float! [2]]]
5861
f64x2: make struct! [a [double! [2]]]
62+
wx2: make struct! [a [word! [2]]]
5963
]
6064
--assert [a [int8! [2]]] = spec-of i8x2
6165
--assert [a [int16! [2]]] = spec-of i16x2
@@ -67,6 +71,7 @@ Rebol [
6771
--assert [a [uint64! [2]]] = spec-of u64x2
6872
--assert [a [float! [2]]] = spec-of f32x2
6973
--assert [a [double! [2]]] = spec-of f64x2
74+
--assert [a [word! [2]]] = spec-of wx2
7075

7176
--assert 2 = length? i8x2
7277
--assert 4 = length? i16x2
@@ -78,6 +83,7 @@ Rebol [
7883
--assert 16 = length? u64x2
7984
--assert 8 = length? f32x2
8085
--assert 16 = length? f64x2
86+
--assert 8 = length? wx2
8187
--assert (mold i8x2 ) = "make struct! [a: [int8! [2]] [0 0]]"
8288
--assert (mold i16x2) = "make struct! [a: [int16! [2]] [0 0]]"
8389
--assert (mold i32x2) = "make struct! [a: [int32! [2]] [0 0]]"
@@ -88,6 +94,7 @@ Rebol [
8894
--assert (mold u64x2) = "make struct! [a: [uint64! [2]] [0 0]]"
8995
--assert (mold f32x2) = "make struct! [a: [float! [2]] [0.0 0.0]]"
9096
--assert (mold f64x2) = "make struct! [a: [double! [2]] [0.0 0.0]]"
97+
--assert (mold wx2) = "make struct! [a: [word! [2]] [none none]]"
9198
===end-group===
9299

93100
i8:

0 commit comments

Comments
 (0)