From aece05f17345994ff4c5154a64b327f714667631 Mon Sep 17 00:00:00 2001 From: Oldes Date: Wed, 24 Mar 2021 20:35:15 +0100 Subject: [PATCH] CHANGE: have `%` to be a valid word and not an empty file related to: https://github.com/Oldes/Rebol-issues/issues/2450 --- src/core/l-scan.c | 22 +++++++++++++++++++++- src/tests/units/lexer-test.r3 | 30 ++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/core/l-scan.c b/src/core/l-scan.c index beb558eff0..059bfc9ab6 100644 --- a/src/core/l-scan.c +++ b/src/core/l-scan.c @@ -874,7 +874,13 @@ case LEX_SPECIAL_AT: /* @username */ return TOKEN_REF; - case LEX_SPECIAL_PERCENT: /* %filename */ + case LEX_SPECIAL_PERCENT: + if (IS_LEX_DELIMIT(cp[1]) && cp[1] != '"' && cp[1] != '/') { + return TOKEN_WORD; // special case for having % as a word (reminder op!) + } else if (cp[1] == ':' && IS_LEX_DELIMIT(cp[2])) { + return TOKEN_SET; + } + /* %filename */ cp = scan_state->end; if (*cp == '"') { cp = Scan_Quote(cp, scan_state); // stores result string in BUF_MOLD @@ -901,6 +907,13 @@ scan_state->end = cp+1; return TOKEN_GET; } + if (cp[1] == '%' && IS_LEX_DELIMIT(cp[2])) { + if (cp[2] == '"' || cp[2] == '/') { // no :%"" or :%/ + scan_state->end = cp + 3; + return -TOKEN_GET; + } + return TOKEN_GET; // allowed :% + } type = TOKEN_GET; cp++; /* skip ':' */ goto scanword; @@ -919,6 +932,13 @@ scan_state->end = cp+1; return TOKEN_LIT; } + if (cp[1] == '%' && IS_LEX_DELIMIT(cp[2])) { + if (cp[2] == '"' || cp[2] == '/') { // no '%"" or '%/ + scan_state->end = cp + 3; + return -TOKEN_LIT; + } + return TOKEN_LIT; // allowed '% + } } if (cp[1] == '\'') return -TOKEN_LIT; // no ''foo type = TOKEN_LIT; diff --git a/src/tests/units/lexer-test.r3 b/src/tests/units/lexer-test.r3 index e1bd65cd3b..2b1a05f2a3 100644 --- a/src/tests/units/lexer-test.r3 +++ b/src/tests/units/lexer-test.r3 @@ -46,6 +46,36 @@ Rebol [ ===end-group=== +===start-group=== "Special % word" + --test-- "valid % word cases" + --assert word? try [load {%}] + --assert word? try [load {% }] + --assert word? try [load {%^-}] + --assert word? try [first load {[%]}] + --test-- "valid % lit-word cases" + --assert lit-word? try [load {'%}] + --assert lit-word? try [load {'% }] + --assert lit-word? try [load {'%^-}] + --assert lit-word? try [first load {['%]}] + --test-- "valid % get-word cases" + --assert get-word? try [load {:%}] + --assert get-word? try [load {:% }] + --assert get-word? try [load {:%^-}] + --assert get-word? try [first load {[:%]}] + --test-- "invalid % lit-word cases" + --assert all [error? e: try [load {'%""}] e/id = 'invalid e/arg1 = "word-lit"] + --assert all [error? e: try [load {'%/}] e/id = 'invalid e/arg1 = "word-lit"] + --test-- "invalid % get-word cases" + --assert all [error? e: try [load {:%""}] e/id = 'invalid e/arg1 = "word-get"] + --assert all [error? e: try [load {:%/}] e/id = 'invalid e/arg1 = "word-get"] + --test-- "% used in object" + --assert all [ + not error? try [o: make object! [%: 1]] + 1 = o/% + ] + +===end-group=== + ===start-group=== "Email" --test-- "valid `emails`" --assert email? load {name@where}