Skip to content

Commit afebd21

Browse files
committed
FEAT: added a new ref! datatype like: @username
related to: Oldes/Rebol-issues#1962
1 parent 53dcfaa commit afebd21

16 files changed

+126
-5
lines changed

src/boot/types-ext.reb

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ issue * sym
4040
string 24 ser
4141
file * ser
4242
email * ser
43+
ref * ser
4344
url * ser
4445
tag * ser
4546

src/boot/types.reb

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ REBOL [
4949
string self string + f* * * [series string]
5050
file self string + f* file * [series string]
5151
email self string + f* * * [series string]
52+
ref self string + f* * * [series string]
5253
url self string + f* file * [series string]
5354
tag self string + + * * [series string]
5455

src/boot/typespec.reb

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ path ["refinements to functions, objects, files" block]
5555
percent ["special form of decimals (used mainly for layout)" scalar]
5656
port ["external series, an I/O channel" object]
5757
rebcode ["virtual machine function" block]
58+
ref ["reference" string]
5859
refinement ["variation of meaning or location" word]
5960
command ["special dispatch-based function" function]
6061
set-path ["definition of a path's value" block]

src/core/l-scan.c

+6-1
Original file line numberDiff line numberDiff line change
@@ -791,7 +791,7 @@
791791
switch (GET_LEX_VALUE(*cp)) {
792792

793793
case LEX_SPECIAL_AT: /* @username */
794-
return TOKEN_EMAIL;
794+
return TOKEN_REF;
795795

796796
case LEX_SPECIAL_PERCENT: /* %filename */
797797
cp = scan_state->end;
@@ -1455,6 +1455,11 @@ extern REBSER *Scan_Full_Block(SCAN_STATE *scan_state, REBYTE mode_char);
14551455
LABEL_SERIES(VAL_SERIES(value), "scan email");
14561456
break;
14571457

1458+
case TOKEN_REF:
1459+
Scan_Ref(bp, len, value);
1460+
LABEL_SERIES(VAL_SERIES(value), "scan ref");
1461+
break;
1462+
14581463
case TOKEN_URL:
14591464
Scan_URL(bp, len, value);
14601465
LABEL_SERIES(VAL_SERIES(value), "scan url");

src/core/l-types.c

+17
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,23 @@ bad_hex: Trap0(RE_INVALID_CHARS);
734734
}
735735

736736

737+
/***********************************************************************
738+
**
739+
*/ const REBYTE *Scan_Ref(const REBYTE *cp, REBCNT len, REBVAL *value)
740+
/*
741+
** Scan and convert ref!
742+
**
743+
***********************************************************************/
744+
{
745+
if (*cp != '@') return 0;
746+
VAL_SERIES(value) = Decode_UTF_String(cp+1, len-1, 8, FALSE);
747+
VAL_INDEX(value) = 0;
748+
VAL_SET(value, REB_REF);
749+
cp += len;
750+
return cp;
751+
}
752+
753+
737754
/***********************************************************************
738755
**
739756
*/ const REBYTE *Scan_URL(const REBYTE *cp, REBCNT len, REBVAL *value)

src/core/m-gc.c

+1
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,7 @@ static void Mark_Series(REBSER *series, REBCNT depth);
357357
case REB_URL:
358358
case REB_TAG:
359359
case REB_BITSET:
360+
case REB_REF:
360361
ser = VAL_SERIES(val);
361362
if (SERIES_WIDE(ser) > sizeof(REBUNI))
362363
Crash(RP_BAD_WIDTH, sizeof(REBUNI), SERIES_WIDE(ser), VAL_TYPE(val));

src/core/s-crc.c

+1
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ static REBCNT *CRC32_Table = 0;
209209
case REB_EMAIL:
210210
case REB_URL:
211211
case REB_TAG:
212+
case REB_REF:
212213
ret = Hash_String(VAL_BIN_DATA(val), Val_Byte_Len(val));
213214
break;
214215

src/core/s-mold.c

+49
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,50 @@ STOID Mold_All_String(REBVAL *value, REB_MOLD *mold)
594594
Post_Mold(value, mold);
595595
}
596596

597+
// Same as Mold_All_String, but forcing contruction syntax like #[file ...]
598+
STOID Mold_All_Constr_String(REBVAL *value, REB_MOLD *mold)
599+
{
600+
// The string that is molded for /all option:
601+
REBVAL val;
602+
// prep...
603+
Emit(mold, "#[T ", value); // #[file! part
604+
// string...
605+
val = *value;
606+
VAL_INDEX(&val) = 0;
607+
VAL_SET(&val, REB_STRING);
608+
Mold_String_Series(&val, mold);
609+
// post...
610+
if (VAL_INDEX(value)) {
611+
Append_Byte(mold->series, ' ');
612+
Append_Int(mold->series, VAL_INDEX(value)+1);
613+
}
614+
Append_Byte(mold->series, ']');
615+
}
616+
617+
STOID Mold_Ref(REBVAL *value, REB_MOLD *mold)
618+
{
619+
if (GET_MOPT(mold, MOPT_MOLD_ALL)) goto mold_ref_all;
620+
621+
// Scan to find out what special chars the string contains?
622+
REBYTE *bp = VAL_BIN(value);
623+
REBUNI *up = (REBUNI*)bp;
624+
REBUNI c;
625+
REBCNT n;
626+
627+
for (n = VAL_INDEX(value); n < VAL_TAIL(value); n++) {
628+
c = (BYTE_SIZE(VAL_SERIES(value))) ? (REBUNI)(bp[n]) : up[n];
629+
if (c == '@') goto mold_ref_all;
630+
if (IS_LEX_WORD(c) || IS_LEX_NUMBER(c)) continue;
631+
if (c < 21 || IS_LEX_ANY_SPACE(c) || IS_LEX_DELIMIT(c)) goto mold_ref_all;
632+
}
633+
634+
Append_Byte(mold->series, '@');
635+
Insert_String(mold->series, AT_TAIL, VAL_SERIES(value), VAL_INDEX(value), VAL_LEN(value), 0);
636+
return;
637+
mold_ref_all:
638+
Mold_All_Constr_String(value, mold);
639+
}
640+
597641

598642
/***********************************************************************
599643
************************************************************************
@@ -1258,6 +1302,11 @@ STOID Mold_Error(REBVAL *value, REB_MOLD *mold, REBFLG molded)
12581302
Append_UTF8(ser, Get_Sym_Name(VAL_WORD_SYM(value)), -1);
12591303
break;
12601304

1305+
case REB_REF:
1306+
// FORM happens in top section.
1307+
Mold_Ref(value, mold);
1308+
break;
1309+
12611310
case REB_REFINEMENT:
12621311
if(molded)
12631312
Emit(mold, "/W", value);

src/core/t-string.c

+1
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ static REBSER *make_binary(REBVAL *arg, REBOOL make)
218218
case REB_EMAIL:
219219
case REB_URL:
220220
case REB_TAG:
221+
case REB_REF:
221222
// case REB_ISSUE:
222223
ser = Encode_UTF8_Value(arg, VAL_LEN(arg), 0);
223224
break;

src/core/t-word.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@
9898
return R_ARG2;
9999
}
100100
else {
101-
if (IS_STRING(arg)) {
101+
if (IS_STRING(arg) || IS_REF(arg)) {
102102
REBYTE *bp;
103103
REBCNT len;
104104
// Set sym. Rest is set below.

src/include/sys-scan.h

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ enum Value_Types {
5959
TOKEN_ISSUE,
6060
TOKEN_TAG,
6161
TOKEN_PATH,
62+
TOKEN_REF,
6263
TOKEN_REFINE,
6364
TOKEN_CONSTRUCT,
6465
TOKEN_MAP,

src/mezz/mezz-types.reb

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ to-logic: to-integer: to-decimal: to-percent: to-money: to-char: to-pair:
1717
to-tuple: to-time: to-date: to-binary: to-string: to-file: to-email: to-url: to-tag:
1818
to-bitset: to-image: to-vector: to-block: to-paren:
1919
to-path: to-set-path: to-get-path: to-lit-path: to-map: to-datatype: to-typeset:
20-
to-word: to-set-word: to-get-word: to-lit-word: to-refinement: to-issue:
20+
to-word: to-set-word: to-get-word: to-lit-word: to-ref: to-refinement: to-issue:
2121
to-command: to-closure: to-function: to-object: to-module: to-error: to-port: to-gob:
2222
to-event:
2323
none

src/tests/units/datatype-test.r3

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ Rebol [
3131
--assert found? find ["test"] series!
3232
--assert none? find reduce [integer! binary!] series!
3333
--assert ["aha"] = find reduce [integer! "aha"] series!
34+
--assert found? find any-string! ref!
3435

3536
===end-group===
3637

src/tests/units/lexer-test.r3

+11-2
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,18 @@ Rebol [
3131
===start-group=== "Email"
3232
--test-- "valid `emails`"
3333
--assert email? load {name@where}
34-
--assert email? load {@name} ;@@ https://github.com/Oldes/Rebol-issues/issues/1962
3534
--assert email? load {a@šiška}
36-
--assert email? load {@%C5%A1}
35+
36+
===end-group===
37+
38+
===start-group=== "Ref"
39+
;@@ https://github.com/Oldes/Rebol-issues/issues/1962
40+
--test-- "valid `ref!`"
41+
--assert ref? load {@name}
42+
--assert ref? load {@123}
43+
--assert ref? load {@1x2}
44+
--assert ref? load {@šiška}
45+
--assert ref? load {@%C5%A1}
3746

3847
===end-group===
3948

src/tests/units/mold-test.r3

+15
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,21 @@ Rebol [
364364
;@@ https://github.com/Oldes/Rebol-issues/issues/2406
365365
--assert "a@šiška" = mold a@šiška
366366
--assert "a@š" = mold a@%C5%A1
367+
===end-group===
368+
369+
===start-group=== "mold ref!"
370+
--test-- "mold ref"
371+
--assert "@name" = mold @name
372+
--assert "@ame" = mold next @name
373+
--assert "@šiška" = mold @šiška
374+
--assert {#[ref! "a@"]} = mold to ref! "a@"
375+
--assert {#[ref! "a^^/b"]} = mold append @a "^/b"
376+
--test-- "form ref"
377+
--assert "name" = form @name
378+
--assert "ame" = form next @name
379+
--assert "šiška" = form @šiška
380+
--assert {a@} = form to ref! "a@"
381+
--assert {a^/b} = form append @a "^/b"
367382

368383
===end-group===
369384

src/tests/units/series-test.r3

+18
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,12 @@ Rebol [
186186
--assert "←" = append "" #"^(2190)" ; wide char
187187
===end-group===
188188

189+
===start-group=== "APPEND ref!"
190+
--test-- "APPEND ref! char!"
191+
--assert @a = append @ #"a"
192+
--assert @← = append @ #"^(2190)" ; wide char
193+
===end-group===
194+
189195

190196
;@@ https://github.com/Oldes/Rebol-issues/issues/1791
191197
===start-group=== "APPEND binary!"
@@ -859,11 +865,13 @@ Rebol [
859865
--assert email? e: as email! s
860866
--assert url? u: as url! s
861867
--assert tag? t: as tag! s
868+
--assert ref? r: as ref! s
862869
append s #"o"
863870
--assert f = %hello
864871
--assert e = to-email %hello
865872
--assert u = #[url! "hello"]
866873
--assert t = <hello>
874+
--assert r = @hello
867875

868876
--test-- "AS datatype! any-block!"
869877
b: [a b]
@@ -885,6 +893,7 @@ Rebol [
885893
--assert email? e: as e@mail s
886894
--assert url? u: as #[url! ""] s
887895
--assert tag? t: as <tag> s
896+
--assert ref? r: as @ref s
888897

889898
--test-- "AS with protect"
890899
b: protect [a b]
@@ -1059,6 +1068,15 @@ Rebol [
10591068
--assert "^@" = to-string #"^(00)"
10601069
--assert "^@" = to-string #"^@"
10611070

1071+
--test-- "to-ref"
1072+
--assert @123 = to-ref 123
1073+
--assert @1.3 = to-ref 1.3
1074+
--assert @1x3 = to-ref 1x3
1075+
--assert @abc = to-ref "abc"
1076+
--assert @ščř = to-ref "ščř"
1077+
--assert @ščř = to-ref to-binary "ščř"
1078+
--assert 2 = length? to-ref #{0102} ; should this be allowed?
1079+
10621080
===end-group===
10631081

10641082

0 commit comments

Comments
 (0)