Skip to content

Commit 547f357

Browse files
committed
FEAT: optimized parse when checking ref! and tag! datatypes
1 parent 9817d01 commit 547f357

File tree

2 files changed

+20
-24
lines changed

2 files changed

+20
-24
lines changed

src/core/u-parse.c

+13-24
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ void Print_Parse_Index(REBCNT type, REBVAL *rules, REBSER *series, REBCNT index)
210210
case REB_FILE:
211211
case REB_URL:
212212
case REB_EMAIL:
213+
case REB_REF:
213214
index = Find_Str_Str(series, 0, index, SERIES_TAIL(series), 1, VAL_SERIES(item), VAL_INDEX(item), VAL_LEN(item), flags);
214215
break;
215216

@@ -228,11 +229,7 @@ void Print_Parse_Index(REBCNT type, REBVAL *rules, REBSER *series, REBCNT index)
228229
break;
229230
*/
230231
case REB_TAG:
231-
case REB_REF:
232-
// case REB_ISSUE:
233-
// !! Can be optimized (w/o COPY)
234-
ser = Copy_Form_Value(item, 0);
235-
index = Find_Str_Str(series, 0, index, SERIES_TAIL(series), 1, ser, 0, ser->tail, flags);
232+
index = Find_Str_Tag(series, 0, index, SERIES_TAIL(series), 1, VAL_SERIES(item), VAL_INDEX(item), VAL_LEN(item), flags);
236233
break;
237234

238235
case REB_NONE:
@@ -426,14 +423,10 @@ void Print_Parse_Index(REBCNT type, REBVAL *rules, REBSER *series, REBCNT index)
426423
if (ch1 == ch2) goto found1;
427424
}
428425
else if (IS_TAG(item)) {
429-
ch2 = '<';
430-
if (ch1 == ch2) {
431-
// adapted from function Parse_To :-)
432-
REBSER *ser;
433-
ser = Copy_Form_Value(item, 0);
434-
i = Find_Str_Str(series, 0, index, series->tail, 1, ser, 0, ser->tail, AM_FIND_MATCH | parse->flags);
426+
if (ch1 == '<') {
427+
i = Find_Str_Tag(series, 0, index, series->tail, 1, VAL_SERIES(item), VAL_INDEX(item), VAL_LEN(item), AM_FIND_MATCH | parse->flags);
435428
if (i != NOT_FOUND) {
436-
if (is_thru) i += ser->tail;
429+
if (is_thru) i += VAL_LEN(item) + 2;
437430
index = i;
438431
goto found;
439432
}
@@ -533,18 +526,10 @@ void Print_Parse_Index(REBCNT type, REBVAL *rules, REBSER *series, REBCNT index)
533526
}
534527
else {
535528
// "str"
536-
if (ANY_BINSTR(item)) {
537-
if (!IS_STRING(item) && !IS_BINARY(item)) {
538-
// !!! Can this be optimized not to use COPY?
539-
// O: It would require Find_Str_Tag, Find_Str_Ref
540-
ser = Copy_Form_Value(item, 0);
541-
i = Find_Str_Str(series, 0, index, series->tail, 1, ser, 0, ser->tail, HAS_CASE(parse));
542-
if (i != NOT_FOUND && is_thru) i += ser->tail;
543-
}
544-
else {
545-
i = Find_Str_Str(series, 0, index, series->tail, 1, VAL_SERIES(item), VAL_INDEX(item), VAL_LEN(item), HAS_CASE(parse));
546-
if (i != NOT_FOUND && is_thru) i += VAL_LEN(item);
547-
}
529+
//O: not using ANY_BINSTR as TAG is now handled separately
530+
if (VAL_TYPE(item) >= REB_BINARY && VAL_TYPE(item) < REB_TAG) {
531+
i = Find_Str_Str(series, 0, index, series->tail, 1, VAL_SERIES(item), VAL_INDEX(item), VAL_LEN(item), HAS_CASE(parse));
532+
if (i != NOT_FOUND && is_thru) i += VAL_LEN(item);
548533
}
549534
// #"A"
550535
else if (IS_CHAR(item)) {
@@ -556,6 +541,10 @@ void Print_Parse_Index(REBCNT type, REBVAL *rules, REBSER *series, REBCNT index)
556541
i = Find_Str_Bitset(series, 0, index, series->tail, 1, VAL_BITSET(item), HAS_CASE(parse));
557542
if (i != NOT_FOUND && is_thru) i++;
558543
}
544+
else if (IS_TAG(item)) {
545+
i = Find_Str_Tag(series, 0, index, series->tail, 1, VAL_SERIES(item), VAL_INDEX(item), VAL_LEN(item), HAS_CASE(parse));
546+
if (i != NOT_FOUND && is_thru) i += VAL_LEN(item) + 2;
547+
}
559548
else
560549
Trap1(RE_PARSE_RULE, item - 1);
561550
}

src/tests/units/parse-test.r3

+7
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,13 @@ Rebol [
4141
e: try [parse "foo" [thru 1.2]]
4242
e/id = 'parse-rule
4343
]
44+
--test--- "TO/THRU with tag!"
45+
--assert parse "<a>" [thru <a>]
46+
--assert parse "a<a>" [thru [<a>]]
47+
--assert parse "a<a>" [to <a> 3 skip]
48+
--assert parse "a<a>" [to [<a>] to end]
49+
--assert parse "a<a>" [thru [<b> | <a>]]
50+
--assert all [parse "11<b>xx</b>22" [thru <b> copy x to </b> to end] x = "xx"]
4451
===end-group===
4552

4653

0 commit comments

Comments
 (0)