Last active
September 25, 2020 08:58
-
-
Save toomasv/4b4d46eb90eb2814bc79e7bb4084f04f to your computer and use it in GitHub Desktop.
`replace` extended with `/only` refinement
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Red [ | |
Description: "`replace` extended with `/only` refinement" | |
Date: 24-Sep-2020 | |
] | |
replace: func ["Replaces values in a series, in place" | |
series [series!] "The series to be modified" | |
pattern "Specific value or parse rule pattern to match" | |
value "New value, replaces pattern in the series" | |
/all "Replace all occurrences, not just the first" | |
/deep "Replace pattern in all sub-lists as well" | |
/case "Case-sensitive replacement" | |
/only "Pattern is replaced with value as single series" | |
/local p rule s e many? len pos do-parse do-find do-change do-change2 do-insert | |
][ | |
do-parse: pick [parse/case parse] case | |
do-insert: pick [insert/only insert] only | |
do-change: pick [change/part/only change/part] only | |
if system/words/all [deep any-list? series] [ | |
pattern: to block! either word? pattern [to lit-word! pattern] [pattern] | |
do compose/deep [ | |
(do-parse) series rule: [ | |
some [ | |
s: pattern e: ( | |
to-paren compose [ | |
s: (do-change) s value e | |
unless all [return series] | |
] | |
) :s | |
| ahead any-list! into rule | skip | |
] | |
] | |
] | |
return series | |
] | |
if system/words/all [ | |
any [not any-string? :pattern tag? :pattern] | |
any-string? series | |
not block? :pattern | |
not bitset? :pattern | |
] [ | |
pattern: form pattern | |
] | |
either system/words/all [any-string? :series block? :pattern] [ | |
do-change2: pick [[change only][change]] only | |
p: compose [to pattern (do-change2) pattern (quote (value))] | |
do compose [(do-parse) series either all [[some p]] [p]] | |
] [ | |
many?: any [ | |
system/words/all [series? :pattern any-string? series] | |
binary? series | |
system/words/all [any-list? series any-list? :pattern] | |
] | |
len: either many? [length? pattern] [1] | |
do-find: pick [find/case find] case | |
either all [ | |
pos: series | |
either many? [ | |
while [pos: do compose [(do-find) pos pattern]] [ | |
pos: do compose [(do-change) pos value len] | |
] | |
] [ | |
while [pos: do compose [(do-find) pos :pattern]] [ | |
pos: do compose [(do-insert) remove pos value] | |
] | |
] | |
] [ | |
if pos: do compose [(do-find) series :pattern] [ | |
do compose [(do-change) pos value len] | |
] | |
] | |
] | |
series | |
] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment