Skip to content

Commit

Permalink
FEAT: add support for word! struct fields
Browse files Browse the repository at this point in the history
  • Loading branch information
Oldes committed Jul 29, 2021
1 parent 854e06e commit 319531e
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 1 deletion.
29 changes: 28 additions & 1 deletion src/core/t-struct.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ static const REBINT type_to_sym [STRUCT_TYPE_MAX] = {

SYM_POINTER,
-1, //SYM_STRUCT
SYM_WORD_TYPE,
//SYM_REBVAL // unused
//STRUCT_TYPE_MAX
};
Expand Down Expand Up @@ -110,6 +111,9 @@ static get_scalar(REBSTU *stu,
VAL_STRUCT_LEN(val) = field->size;
}
break;
case STRUCT_TYPE_WORD:
Set_Word(val, *(REBINT *)data, NULL, 0);
break;
#ifdef unused
case STRUCT_TYPE_REBVAL:
memcpy(val, data, sizeof(REBVAL));
Expand Down Expand Up @@ -232,6 +236,7 @@ static get_scalar(REBSTU *stu,
} else {
val = Append_Value(ser);
get_scalar(stu, field, 0, val);
if (IS_WORD(val)) SET_TYPE(val, REB_LIT_WORD);
}
}
return ser;
Expand Down Expand Up @@ -303,6 +308,12 @@ static REBOOL assign_scalar(REBSTU *stu,
Trap_Type(val);
}
break;
case REB_WORD:
if (STRUCT_TYPE_WORD != field->type) {
Trap_Type(val);
}
i = (u64)VAL_WORD_SYM(val);
break;
default:
Trap_Type(val);
}
Expand All @@ -324,6 +335,7 @@ static REBOOL assign_scalar(REBSTU *stu,
*(i32*)data = (i32)i;
break;
case STRUCT_TYPE_UINT32:
case STRUCT_TYPE_WORD:
*(u32*)data = (u32)i;
break;
case STRUCT_TYPE_INT64:
Expand Down Expand Up @@ -581,6 +593,10 @@ static REBOOL parse_field_type(struct Struct_Field *field, REBVAL *spec, REBVAL
Trap_Types(RE_EXPECT_VAL, REB_BLOCK, VAL_TYPE(val));
}
break;
case SYM_WORD_TYPE:
field->type = STRUCT_TYPE_WORD;
field->size = 4;
break;
#ifdef unused
case SYM_REBVAL:
field->type = STRUCT_TYPE_REBVAL;
Expand Down Expand Up @@ -764,7 +780,17 @@ static REBOOL parse_field_type(struct Struct_Field *field, REBVAL *spec, REBVAL
for (n = 0; n < field->dimension; n ++) {
memcpy(SERIES_SKIP(VAL_STRUCT_DATA_BIN(out), ((REBCNT)offset) + n * field->size), SERIES_DATA(VAL_STRUCT_DATA_BIN(init)), field->size);
}
} else if (field->type == STRUCT_TYPE_REBVAL) {
}
else if (field->type == STRUCT_TYPE_WORD) {
// use word `none` as a default value
REBCNT n = 0;
REBCNT sym = SYM_NONE;
for (n = 0; n < field->dimension; n++) {
memcpy(SERIES_SKIP(VAL_STRUCT_DATA_BIN(out), ((REBCNT)offset) + n * field->size), &sym, field->size);
}
}
else if (field->type == STRUCT_TYPE_REBVAL) {
#ifdef unused
REBVAL unset;
REBCNT n = 0;
SET_UNSET(&unset);
Expand All @@ -774,6 +800,7 @@ static REBOOL parse_field_type(struct Struct_Field *field, REBVAL *spec, REBVAL
goto failed;
}
}
#endif
} else {
memset(SERIES_SKIP(VAL_STRUCT_DATA_BIN(out), (REBCNT)offset), 0, field->size * field->dimension);
}
Expand Down
1 change: 1 addition & 0 deletions src/include/reb-struct.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ enum {

STRUCT_TYPE_POINTER,
STRUCT_TYPE_STRUCT,
STRUCT_TYPE_WORD,
STRUCT_TYPE_REBVAL,
STRUCT_TYPE_MAX
};
Expand Down
7 changes: 7 additions & 0 deletions src/tests/units/struct-test.r3
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Rebol [
u64: make struct! [a [uint64!]]
f32: make struct! [a [float!]]
f64: make struct! [a [double!]]
w: make struct! [a [word!]]
]
--assert 1 = length? i8
--assert 2 = length? i16
Expand All @@ -31,6 +32,7 @@ Rebol [
--assert 8 = length? u64
--assert 4 = length? f32
--assert 8 = length? f64
--assert 4 = length? w
--assert (mold i8 ) = "make struct! [a: [int8!] 0]"
--assert (mold i16) = "make struct! [a: [int16!] 0]"
--assert (mold i32) = "make struct! [a: [int32!] 0]"
Expand All @@ -41,6 +43,7 @@ Rebol [
--assert (mold u64) = "make struct! [a: [uint64!] 0]"
--assert (mold f32) = "make struct! [a: [float!] 0.0]"
--assert (mold f64) = "make struct! [a: [double!] 0.0]"
--assert (mold w) = "make struct! [a: [word!] 'none]"
===end-group===


Expand All @@ -56,6 +59,7 @@ Rebol [
u64x2: make struct! [a [uint64! [2]]]
f32x2: make struct! [a [float! [2]]]
f64x2: make struct! [a [double! [2]]]
wx2: make struct! [a [word! [2]]]
]
--assert [a [int8! [2]]] = spec-of i8x2
--assert [a [int16! [2]]] = spec-of i16x2
Expand All @@ -67,6 +71,7 @@ Rebol [
--assert [a [uint64! [2]]] = spec-of u64x2
--assert [a [float! [2]]] = spec-of f32x2
--assert [a [double! [2]]] = spec-of f64x2
--assert [a [word! [2]]] = spec-of wx2

--assert 2 = length? i8x2
--assert 4 = length? i16x2
Expand All @@ -78,6 +83,7 @@ Rebol [
--assert 16 = length? u64x2
--assert 8 = length? f32x2
--assert 16 = length? f64x2
--assert 8 = length? wx2
--assert (mold i8x2 ) = "make struct! [a: [int8! [2]] [0 0]]"
--assert (mold i16x2) = "make struct! [a: [int16! [2]] [0 0]]"
--assert (mold i32x2) = "make struct! [a: [int32! [2]] [0 0]]"
Expand All @@ -88,6 +94,7 @@ Rebol [
--assert (mold u64x2) = "make struct! [a: [uint64! [2]] [0 0]]"
--assert (mold f32x2) = "make struct! [a: [float! [2]] [0.0 0.0]]"
--assert (mold f64x2) = "make struct! [a: [double! [2]] [0.0 0.0]]"
--assert (mold wx2) = "make struct! [a: [word! [2]] [none none]]"
===end-group===

i8:
Expand Down

0 comments on commit 319531e

Please sign in to comment.