At the time I was determined to make an ideal library that would replace strings and lists with sequences, similar to how things are in Python, but I kind of lost interest and wanted to work on more important issues instead. I was also worried that it might be too inefficient for general use, which was discouraging.
I was never planning to release the code in this way, but at this point, I'm not sure if I will ever revisit it. I just thought some of you might find it useful or interesting in some way. I must warn you that these functions are very different from the built-in ones, and once you try them, you might not want to go back!
You should be able to figure this out without documentation. Just know that both the start and length arguments can be negative and that they do NOT correspond to the Start and End args of the built-in text functions. It should become clear once you test things out.
#define islist(x) istype(x,/list)
#define setpositionstemplate \
if(length > 0){\
.--;\
if(start < 0){\
startpos = seqlen + start + 1;\
if(. >= -1){\
endpos = seqlen}\
else{\
endpos = seqlen + . + 1}}\
else{\
startpos = start;\
if(. >= seqlen){\
endpos = seqlen}\
else{\
endpos = .}}}\
else if(length < 0){\
.++;\
if(start > 0){\
startpos = start;\
if(. <= 1){\
endpos = 1}\
else{\
endpos = .}}\
else{\
startpos = seqlen + start + 1;\
if(. <= -seqlen){\
endpos = 1}\
else{\
endpos = seqlen + . + 1}}}\
else{\
if(start > 0){\
startpos = start;\
endpos = seqlen}\
else{\
startpos = seqlen + start + 1;\
endpos = 1}}
proc
find(sequence, val, start = 1, length = 0)
if(!(length(sequence) && start)) return 0
var
seqlen = length(sequence)
vallen = length("[val]")
startpos
endpos
if(abs(start) > seqlen) return 0
. = start + length
setpositionstemplate
if(istext(sequence))
if(!(vallen in 1 to seqlen)) return 0
if(startpos <= endpos)
. = findtextEx(sequence, "[val]", startpos, endpos + 1)
else
if(vallen > (startpos - endpos + 1)) return 0
for(var/pos in startpos - vallen to endpos step -1)
. = findtextEx(sequence, "[val]", pos, startpos + 1)
if(.) return
else if(islist(sequence))
if(startpos <= endpos)
. = sequence:Find(val, startpos, endpos + 1)
else
for(var/pos in startpos to endpos step -1)
if(sequence[pos] == val)
return pos
. = 0
else . = 0
findNoCase(sequence, val, start = 1, length = 0)
if(!(length(sequence) && start)) return 0
var
seqlen = length(sequence)
vallen = length("[val]")
startpos
endpos
if(abs(start) > seqlen) return 0
. = start + length
setpositionstemplate
if(istext(sequence))
if(!(vallen in 1 to seqlen)) return 0
if(startpos <= endpos)
. = findtext(sequence, "[val]", startpos, endpos + 1)
else
if(vallen > (startpos - endpos + 1)) return 0
for(var/pos in startpos - vallen to endpos step -1)
. = findtext(sequence, "[val]", pos, startpos + 1)
if(.) return
else if(islist(sequence))
if(istext(val))
if(startpos <= endpos)
for(var/pos in startpos to endpos)
. = sequence[pos]
if(istext(.) && (length(.) == vallen) && findtext(., val))
return pos
. = 0
else
for(var/pos in startpos to endpos step -1)
. = sequence[pos]
if(istext(.) && (length(.) == vallen) && findtext(., val))
return pos
. = 0
else
if(startpos <= endpos)
. = sequence:Find(val, startpos, endpos + 1)
else
for(var/pos in startpos to endpos step -1)
if(sequence[pos] == val)
return pos
. = 0
else . = 0
copy(sequence, start = 1, length = 0)
if(!(length(sequence) && start)) return null
var
seqlen = length(sequence)
startpos
endpos
if(abs(start) > seqlen) return null
. = start + length
setpositionstemplate
if(istext(sequence))
if(startpos <= endpos)
. = copytext(sequence, startpos, endpos + 1)
else
. = copytext(sequence, endpos, startpos + 1)
else if(islist(sequence))
if(startpos <= endpos)
. = sequence:Copy(startpos, endpos + 1)
else
. = sequence:Copy(endpos, startpos + 1)
else . = null
cut(sequence, start = 1, length = 0)
if(!(length(sequence) && start)) return null
var
seqlen = length(sequence)
startpos
endpos
if(abs(start) > seqlen) return null
. = start + length
setpositionstemplate
if(istext(sequence))
if(startpos <= endpos)
. = copytext(sequence, 1, startpos) + copytext(sequence, endpos + 1)
else
. = copytext(sequence, 1, endpos) + copytext(sequence, startpos + 1)
else if(islist(sequence))
var/list/lst = sequence
if(startpos <= endpos)
lst.Cut(startpos, endpos + 1)
else
lst.Cut(endpos, startpos + 1)
. = lst
else . = null
add()
for(var/a in args)
. += a
A large portion of the code was repetitive, so I had used the preprocessor to wrap it up. It was like redirecting a river to flow in another direction. DM can be a stubborn language, and sometimes you have to be a stubborn developer to make it work the way you want.
You may use this however you want.