Skip to content

Commit 10a5b4d

Browse files
committed
FEAT: implemented copy of nested maps
related to: Oldes/Rebol-issues#1864 Oldes/Rebol-issues#2293
1 parent 8bf1f2c commit 10a5b4d

File tree

5 files changed

+37
-21
lines changed

5 files changed

+37
-21
lines changed

src/core/f-blocks.c

+10-3
Original file line numberDiff line numberDiff line change
@@ -120,12 +120,14 @@
120120
***********************************************************************/
121121
{
122122
REBVAL *val;
123+
REBSER *ser;
124+
REBU64 ts;
123125

124126
for (; index < tail; index++) {
125127

126128
val = BLK_SKIP(block, index);
127-
128-
if ((types & TYPESET(VAL_TYPE(val)) & TS_SERIES_OBJ) != 0) {
129+
ts = types & TYPESET(VAL_TYPE(val));
130+
if ((ts & TS_SERIES_OBJ) != 0) {
129131
// Replace just the series field of the value
130132
// Note that this should work for objects too (the frame).
131133
VAL_SERIES(val) = Copy_Series(VAL_SERIES(val));
@@ -135,8 +137,13 @@
135137
if ((types & CP_DEEP) != 0)
136138
Copy_Deep_Values(VAL_SERIES(val), 0, VAL_TAIL(val), types);
137139
}
138-
} else if (types & TYPESET(VAL_TYPE(val)) & TS_FUNCLOS)
140+
}
141+
else if (ts & TS_FUNCLOS) {
139142
Clone_Function(val, val);
143+
}
144+
else if (ts & TYPESET(REB_MAP)) {
145+
Set_Series(REB_MAP, val, Copy_Map(val, types));
146+
}
140147
}
141148
}
142149

src/core/t-block.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -754,7 +754,7 @@ static struct {
754754
Set_Series(
755755
VAL_TYPE(value), D_RET,
756756
D_REF(ARG_TAKE_DEEP)
757-
? Copy_Block_Values(ser, 0, len, CP_DEEP | TS_STD_SERIES)
757+
? Copy_Block_Values(ser, 0, len, CP_DEEP | TS_DEEP_COPIED)
758758
: Copy_Block_Len(ser, index, len)
759759
);
760760
}
@@ -847,7 +847,7 @@ static struct {
847847
{
848848
REBU64 types = 0;
849849
if (D_REF(ARG_COPY_DEEP)) {
850-
types |= CP_DEEP | (D_REF(ARG_COPY_TYPES) ? 0 : TS_STD_SERIES);
850+
types |= CP_DEEP | (D_REF(ARG_COPY_TYPES) ? 0 : TS_DEEP_COPIED);
851851
}
852852
if D_REF(ARG_COPY_TYPES) {
853853
arg = D_ARG(ARG_COPY_KINDS);

src/core/t-map.c

+23-15
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,24 @@
343343

344344
/***********************************************************************
345345
**
346-
*/ REBFLG MT_Map(REBVAL *out, REBVAL *data, REBCNT type)
346+
*/ REBSER *Copy_Map(REBVAL *val, REBU64 types)
347+
/*
348+
** Copy given map.
349+
**
350+
***********************************************************************/
351+
{
352+
REBSER *series;
353+
series = Make_Map(VAL_BLK_LEN(val) / 2);
354+
//COPY_BLK_PART(series, VAL_BLK_DATA(data), n);
355+
Append_Map(series, val, UNKNOWN);
356+
if (types != 0) Copy_Deep_Values(series, 0, SERIES_TAIL(series), types);
357+
Rehash_Hash(series);
358+
return series;
359+
}
360+
361+
/***********************************************************************
362+
**
363+
*/ REBFLG MT_Map(REBVAL *out, REBVAL *data, REBU64 type)
347364
/*
348365
***********************************************************************/
349366
{
@@ -355,16 +372,7 @@
355372
n = VAL_BLK_LEN(data);
356373
if (n & 1) return FALSE;
357374

358-
series = Make_Map(n/2);
359-
360-
//COPY_BLK_PART(series, VAL_BLK_DATA(data), n);
361-
Append_Map(series, data, UNKNOWN);
362-
363-
if (type != 0) Copy_Deep_Values(series, 0, SERIES_TAIL(series), type);
364-
365-
Rehash_Hash(series);
366-
367-
Set_Series(REB_MAP, out, series);
375+
Set_Series(REB_MAP, out, Copy_Map(data, type));
368376

369377
return TRUE;
370378
}
@@ -561,15 +569,15 @@
561569

562570
case A_COPY: {
563571
REBU64 types = 0;
564-
if (D_REF(ARG_COPY_DEEP)) {
565-
//puts("deep copy wanted");
566-
types |= CP_DEEP | (D_REF(ARG_COPY_TYPES) ? 0 : TS_STD_SERIES);
567-
}
568572
if D_REF(ARG_COPY_TYPES) {
569573
arg = D_ARG(ARG_COPY_KINDS);
570574
if (IS_DATATYPE(arg)) types |= TYPESET(VAL_DATATYPE(arg));
571575
else types |= VAL_TYPESET(arg);
572576
}
577+
if (D_REF(ARG_COPY_DEEP)) {
578+
//puts("deep copy wanted");
579+
types |= CP_DEEP | (D_REF(ARG_COPY_TYPES) ? types : TS_DEEP_COPIED);
580+
}
573581
if (MT_Map(D_RET, val, types)) return R_RET;
574582
Trap_Arg(val);
575583
}

src/core/t-object.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,7 @@ static REBSER *Trim_Object(REBSER *obj)
453453
REBU64 types = 0;
454454
if (D_REF(ARG_COPY_PART)) Trap0(RE_BAD_REFINES);
455455
if (D_REF(ARG_COPY_DEEP)) {
456-
types |= CP_DEEP | (D_REF(ARG_COPY_TYPES) ? 0 : TS_STD_SERIES);
456+
types |= CP_DEEP | (D_REF(ARG_COPY_TYPES) ? 0 : TS_DEEP_COPIED);
457457
}
458458
if D_REF(ARG_COPY_TYPES) {
459459
arg = D_ARG(ARG_COPY_KINDS);

src/include/sys-core.h

+1
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ enum {
163163
#define TS_STD_SERIES (TS_SERIES & ~TS_NOT_COPIED)
164164
#define TS_SERIES_OBJ ((TS_SERIES | TS_OBJECT) & ~TS_NOT_COPIED)
165165
#define TS_BLOCKS_OBJ ((TS_BLOCK | TS_OBJECT) & ~TS_NOT_COPIED)
166+
#define TS_DEEP_COPIED ((TS_SERIES | TYPESET(REB_MAP)) & ~TS_NOT_COPIED)
166167

167168
#define TS_CODE ((CP_DEEP | TS_SERIES) & ~TS_NOT_COPIED)
168169

0 commit comments

Comments
 (0)