Skip to content

Commit 9d5a6f9

Browse files
committed
FEAT/CHANGE: added support for case-sensitivity of map! keys
implements: Oldes/Rebol-issues#2294 With this commit maps should be compatible with Red language, where creation is case sensitive, selection is by default case insensitive unless `/case` refinement is used.
1 parent dbc5723 commit 9d5a6f9

File tree

3 files changed

+43
-9
lines changed

3 files changed

+43
-9
lines changed

src/core/t-map.c

+9-9
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@
162162
} else {
163163
while (NZ(n = hashes[hash])) {
164164
val = BLK_SKIP(series, (n-1) * wide);
165-
if (VAL_TYPE(val) == VAL_TYPE(key) && 0 == Cmp_Value(key, val, !cased)) return hash;
165+
if (VAL_TYPE(val) == VAL_TYPE(key) && 0 == Cmp_Value(key, val, cased)) return hash;
166166
hash += skip;
167167
if (hash >= len) hash -= len;
168168
}
@@ -199,15 +199,15 @@
199199

200200
val = BLK_HEAD(series);
201201
for (n = 0; n < series->tail; n += 2, val += 2) {
202-
key = Find_Key(series, series->series, val, 2, 0, 0);
202+
key = Find_Key(series, series->series, val, 2, TRUE, 0);
203203
hashes[key] = n/2+1;
204204
}
205205
}
206206

207207

208208
/***********************************************************************
209209
**
210-
*/ static REBCNT Find_Entry(REBSER *series, REBVAL *key, REBVAL *val)
210+
*/ static REBCNT Find_Entry(REBSER *series, REBVAL *key, REBVAL *val, REBOOL cased)
211211
/*
212212
** Try to find the entry in the map. If not found
213213
** and val is SET, create the entry and store the key and
@@ -231,7 +231,7 @@
231231
Rehash_Hash(series);
232232
}
233233

234-
hash = Find_Key(series, hser, key, 2, 0, 0);
234+
hash = Find_Key(series, hser, key, 2, cased, 0);
235235
hashes = (REBCNT*)hser->data;
236236
n = hashes[hash];
237237

@@ -313,7 +313,7 @@
313313
!IS_INTEGER(pvs->select) && !IS_CHAR(pvs->select))
314314
return PE_BAD_SELECT;
315315

316-
n = Find_Entry(VAL_SERIES(data), pvs->select, val);
316+
n = Find_Entry(VAL_SERIES(data), pvs->select, val, FALSE);
317317

318318
if (!n) return PE_NONE;
319319

@@ -333,7 +333,7 @@
333333

334334
val = VAL_BLK_DATA(arg);
335335
for (n = 0; n < len && NOT_END(val) && NOT_END(val+1); val += 2, n += 2) {
336-
Find_Entry(ser, val, val+1);
336+
Find_Entry(ser, val, val+1, TRUE);
337337
}
338338
}
339339

@@ -488,7 +488,7 @@
488488

489489
case A_PICK: // same as SELECT for MAP! datatype
490490
case A_SELECT:
491-
n = Find_Entry(series, arg, 0);
491+
n = Find_Entry(series, arg, 0, Find_Refines(ds, AM_SELECT_CASE) ? AM_FIND_CASE : 0);
492492
if (!n) return R_NONE;
493493
*D_RET = *VAL_BLK_SKIP(val, ((n-1)*2)+1);
494494
break;
@@ -505,11 +505,11 @@
505505
break;
506506

507507
case A_PUT:
508-
Find_Entry(series, arg, D_ARG(3));
508+
Find_Entry(series, arg, D_ARG(3), Find_Refines(ds, AM_PUT_CASE) ? AM_FIND_CASE : 0);
509509
return R_ARG3;
510510

511511
case A_POKE: // CHECK all pokes!!! to be sure they check args now !!!
512-
Find_Entry(series, arg, D_ARG(3));
512+
Find_Entry(series, arg, D_ARG(3), FALSE);
513513
*D_RET = *D_ARG(3);
514514
break;
515515

src/tests/units/map-test.r3

+33
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,39 @@ Rebol [
2828
--assert 2 = m/b
2929
--assert empty? #()
3030

31+
--test-- "case sensitivity"
32+
m: #(
33+
<a> 1 <A> 2 <ab> 3 <Ab> 4
34+
%a 5 %A 6 %ab 7 %Ab 8
35+
"a" 9 "A" 10 "ab" 11 "Ab" 12
36+
a 13 A 14 ab 15 Ab 16
37+
@a 17 @A 18 @ab 19 @Ab 20
38+
#"a" 21 #"A" 22 #{61} 23 #{41} 24
39+
)
40+
--assert 24 = length? m
41+
--assert 1 = select m <A>
42+
--assert 5 = select m %A
43+
--assert 9 = select m "A"
44+
--assert 13 = select m 'A
45+
--assert 17 = select m @A
46+
--assert 21 = select m #"A"
47+
--assert 24 = select m #{41} ; always case sensitive
48+
--assert 24 = length? m
49+
--assert 2 = select/case m <A>
50+
--assert 6 = select/case m %A
51+
--assert 10 = select/case m "A"
52+
--assert 14 = select/case m 'A
53+
--assert 18 = select/case m @A
54+
--assert 22 = select/case m #"A"
55+
--assert 24 = select/case m #{41}
56+
--assert 1 = m/(<A>)
57+
--assert 5 = m/(%A)
58+
--assert 9 = m/("A")
59+
--assert 13 = m/('A)
60+
--assert 17 = m/(@A)
61+
--assert 21 = m/(#"A")
62+
63+
3164
===end-group===
3265

3366
===start-group=== "map issues"

src/tools/make-headers.r

+1
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,7 @@ acts: load %../boot/actions.r
331331
foreach word [
332332
copy
333333
find
334+
put
334335
select
335336
insert
336337
trim

0 commit comments

Comments
 (0)