mirror of https://github.com/exaloop/codon.git
71 lines
1.9 KiB
Python
71 lines
1.9 KiB
Python
cat_count = 0
|
|
|
|
# c/p from str.seq
|
|
def old_cat(*args):
|
|
total = 0
|
|
if staticlen(args) == 1 and hasattr(args[0], "__iter__") and hasattr(args[0], "__len__"):
|
|
for s in args[0]:
|
|
if not isinstance(s, str):
|
|
compile_error("not a string")
|
|
total += s.len
|
|
p = cobj(total)
|
|
n = 0
|
|
for s in args[0]:
|
|
str.memcpy(p + n, s.ptr, s.len)
|
|
n += s.len
|
|
return str(p, total)
|
|
elif staticlen(args) == 1 and hasattr(args[0], "__iter__"):
|
|
sz = 10
|
|
p = cobj(sz)
|
|
n = 0
|
|
for s in args[0]:
|
|
if not isinstance(s, str):
|
|
compile_error("not a string")
|
|
if n + s.len > sz:
|
|
sz = 1 + 3 * (n + s.len) // 2
|
|
pp = cobj(sz)
|
|
str.memcpy(pp, p, n)
|
|
p = pp
|
|
str.memcpy(p + n, s.ptr, s.len)
|
|
n += s.len
|
|
return str(p, n)
|
|
else:
|
|
total = 0
|
|
for i in args:
|
|
if not isinstance(i, str):
|
|
compile_error("not a string")
|
|
total += i.len
|
|
p = cobj(total)
|
|
n = 0
|
|
for i in args:
|
|
str.memcpy(p + n, i.ptr, i.len)
|
|
n += i.len
|
|
return str(p, total)
|
|
|
|
@extend
|
|
class str:
|
|
def cat(*args):
|
|
global cat_count
|
|
cat_count += 1
|
|
return old_cat(*args)
|
|
|
|
@test
|
|
def test_str_optimization():
|
|
assert 'hello ' + 'world' == "hello world" # no opt: just adding 2 strs
|
|
assert cat_count == 0
|
|
# assert 'a' + 'b' + 'c' == 'abc' # superseded by string statics
|
|
# assert cat_count == 1
|
|
assert 'a' * 2 == 'aa' # no opt: mul instead of add
|
|
assert cat_count == 0
|
|
# assert 'a' + ('b' + 'c') == 'abc'
|
|
# assert cat_count == 2
|
|
# assert 'a' + ('b' + ('c' + 'd')) == 'abcd'
|
|
# assert cat_count == 3
|
|
|
|
a = 'a'
|
|
b = 'b'
|
|
c = 'c'
|
|
assert (a*2 + b*3 + c*4) == 'aabbbcccc'
|
|
assert cat_count == 1
|
|
test_str_optimization()
|