Skip to content

Commit 973c500

Browse files
kmr-srbhubaidsk
andauthored
Support string repeat with non constant integer (#2675)
* Support string repeat with non-constant integer * Tests: Add tests * Set character `a_len` to -1 Co-authored-by: Shaikh Ubaid <shaikhubaid769@gmail.com> * Simplify conditional check to `else` * Handle negative integers for string repeat * Tests: Update test --------- Co-authored-by: Shaikh Ubaid <shaikhubaid769@gmail.com>
1 parent 3ccdfdb commit 973c500

File tree

3 files changed

+38
-4
lines changed

3 files changed

+38
-4
lines changed

integration_tests/test_str_01.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from lpython import i32
2+
13
def f():
24
x: str
35
x = "ok"
@@ -58,9 +60,38 @@ def test_str_repeat():
5860
assert a*3 == "XyzXyzXyz"
5961
assert a*2*3 == "XyzXyzXyzXyzXyzXyz"
6062
assert 3*a*3 == "XyzXyzXyzXyzXyzXyzXyzXyzXyz"
61-
assert a*-1 == ""
63+
b: str = a * -1
64+
assert b == ""
6265
assert len(a*(10**6)) == (3 * 10 ** 6)
6366

67+
# string repeat with a non-constant integer
68+
s: str = "#"
69+
n: i32 = 5
70+
71+
assert s * n == "#####"
72+
assert n * s == "#####"
73+
74+
assert "@" * n == "@@@@@"
75+
assert "@#$%" * n == "@#$%@#$%@#$%@#$%@#$%"
76+
77+
s = "@#$%"
78+
assert n * s == "@#$%@#$%@#$%@#$%@#$%"
79+
80+
n = 10 ** 6
81+
assert len(s * n) == (4 * 10 ** 6)
82+
83+
s = "$"
84+
m: i32 = 2
85+
n = 5
86+
t: str = s * m * n
87+
assert t == "$$$$$$$$$$"
88+
assert s * m * 2 == "$$$$"
89+
assert 2 * (m + n) * s == "$$$$$$$$$$$$$$"
90+
91+
t = 2 * (m + n) * "abc-"
92+
assert t == "abc-abc-abc-abc-abc-abc-abc-abc-abc-abc-abc-abc-abc-abc-"
93+
94+
6495
def test_str_join():
6596
a: str
6697
a = ","

src/libasr/runtime/lfortran_intrinsics.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2140,7 +2140,7 @@ LFORTRAN_API void _lfortran_strrepeat(char** s, int32_t n, char** dest)
21402140
char* dest_char = (char*)malloc(f_len+trmn_size);
21412141

21422142
if (s_len == 1) {
2143-
memset(dest_char, *(*s), n);
2143+
memset(dest_char, *(*s), f_len);
21442144
} else {
21452145
memcpy(dest_char, *s, s_len);
21462146
int chars_copied = s_len;

src/lpython/semantics/python_ast_to_asr.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2079,7 +2079,7 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
20792079
} else if ((right_is_int || left_is_int) && op == ASR::binopType::Mul) {
20802080
// string repeat
20812081
int64_t left_int = 0, right_int = 0, dest_len = 0;
2082-
if (right_is_int) {
2082+
if (right_is_int && ASRUtils::expr_value(right) != nullptr) {
20832083
ASR::Character_t *left_type2 = ASR::down_cast<ASR::Character_t>(
20842084
ASRUtils::type_get_past_array(left_type));
20852085
LCOMPILERS_ASSERT(ASRUtils::extract_n_dims_from_ttype(left_type) == 0);
@@ -2090,7 +2090,7 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
20902090
dest_type = ASR::down_cast<ASR::ttype_t>(
20912091
ASR::make_Character_t(al, loc, left_type2->m_kind,
20922092
dest_len, nullptr));
2093-
} else if (left_is_int) {
2093+
} else if (left_is_int && ASRUtils::expr_value(left) != nullptr) {
20942094
ASR::Character_t *right_type2 = ASR::down_cast<ASR::Character_t>(
20952095
ASRUtils::type_get_past_array(right_type));
20962096
LCOMPILERS_ASSERT(ASRUtils::extract_n_dims_from_ttype(right_type) == 0);
@@ -2101,6 +2101,9 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
21012101
dest_type = ASR::down_cast<ASR::ttype_t>(
21022102
ASR::make_Character_t(al, loc, right_type2->m_kind,
21032103
dest_len, nullptr));
2104+
} else {
2105+
dest_type = ASRUtils::TYPE(ASR::make_Character_t(al,
2106+
loc, 1, -1, nullptr));
21042107
}
21052108

21062109
if (ASRUtils::expr_value(left) != nullptr && ASRUtils::expr_value(right) != nullptr) {

0 commit comments

Comments
 (0)