Skip to content

Commit a84486a

Browse files
authored
Merge branch 'main' into detect-unhashable-type
2 parents 34658ba + 4921160 commit a84486a

File tree

61 files changed

+1389
-1234
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+1389
-1234
lines changed

integration_tests/test_gruntz.py

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from lpython import S
2-
from sympy import Symbol, log, E, Pow
2+
from sympy import Symbol, log, E, Pow, exp
33

44
def mmrv(e: S, x: S) -> list[S]:
55
empty_list : list[S] = []
@@ -13,22 +13,29 @@ def mmrv(e: S, x: S) -> list[S]:
1313
list2: list[S] = mmrv(arg0, x)
1414
return list2
1515
elif e.func == Pow:
16-
if e.args[0] != E:
17-
e1: S = S(1)
16+
base: S = e.args[0]
17+
exponent: S = e.args[1]
18+
one: S = S(1)
19+
if base != E:
20+
newe_exponent: S = S(1)
1821
newe: S = e
1922
while newe.func == Pow:
20-
b1: S = newe.args[0]
21-
e1 = e1 * newe.args[1]
22-
newe = b1
23-
if b1 == S(1):
23+
newe_base: S = newe.args[0]
24+
newe_args1: S = newe.args[1]
25+
newe_exponent = newe_exponent * newe_args1
26+
newe = newe_base
27+
if newe_base == one:
2428
return empty_list
25-
if not e1.has(x):
26-
list3: list[S] = mmrv(b1, x)
29+
if not newe_exponent.has(x):
30+
list3: list[S] = mmrv(newe_base, x)
2731
return list3
2832
else:
2933
# TODO as noted in #2526
3034
pass
3135
else:
36+
if exponent.func == log:
37+
list4: list[S] = mmrv(exponent.args[0], x)
38+
return list4
3239
# TODO
3340
pass
3441
else:
@@ -63,4 +70,11 @@ def test_mrv():
6370
assert ele3 == x
6471
assert len(ans4) == 1
6572

73+
# Case 5
74+
ans5: list[S] = mmrv(exp(log(x)), x)
75+
ele4: S = ans5[0]
76+
print(ele4)
77+
assert ele4 == x
78+
assert len(ans5) == 1
79+
6680
test_mrv()

integration_tests/test_str_attributes.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,31 @@ def is_numeric():
472472
assert "".isnumeric() == False
473473
assert "ab2%3".isnumeric() == False
474474

475+
def center():
476+
s: str = "test"
477+
assert s.center(8,'*') == "**test**"
478+
assert s.center(11) == " test "
479+
assert s.center(2) == "test"
480+
assert s.center(4) == "test"
481+
assert s.center(9,'/') == "///test//"
482+
483+
def expandtabs():
484+
s: str = '01\t012\t0123\t01234'
485+
assert s.expandtabs() == "01 012 0123 01234"
486+
assert s.expandtabs(4) == "01 012 0123 01234"
487+
assert s.expandtabs(-1) == "01012012301234"
488+
s = '\t'
489+
assert s.expandtabs() == " "
490+
s = ''
491+
assert s.expandtabs() == ""
492+
s = '\tThis\ris\na\ttest'
493+
assert s.expandtabs(4) == " This\ris\na test"
494+
s = '\t\t\t'
495+
assert s.expandtabs(2) == " "
496+
s = 'test\ttest'
497+
assert s.expandtabs(0) == "testtest"
498+
assert s.expandtabs(-5) == "testtest"
499+
475500
def check():
476501
capitalize()
477502
lower()
@@ -492,6 +517,8 @@ def check():
492517
is_space()
493518
is_alnum()
494519
is_numeric()
520+
center()
521+
expandtabs()
495522

496523

497524
check()

src/lpython/semantics/python_ast_to_asr.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6933,6 +6933,59 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
69336933
value.m_value = args[2].m_value;
69346934
fn_args.push_back(al, value);
69356935
}
6936+
} else if(attr_name == "center") {
6937+
if (args.size() != 1 && args.size() != 2) {
6938+
throw SemanticError("str.center() takes one or two argument",
6939+
loc);
6940+
}
6941+
ASR::expr_t *arg_value = args[0].m_value;
6942+
ASR::ttype_t *arg_value_type = ASRUtils::expr_type(arg_value);
6943+
if (!ASRUtils::is_integer(*arg_value_type)) {
6944+
throw SemanticError("str.center() argument 1 must be integer", loc);
6945+
}
6946+
6947+
fn_call_name = "_lpython_str_center";
6948+
ASR::call_arg_t str;
6949+
str.loc = loc;
6950+
str.m_value = s_var;
6951+
6952+
ASR::call_arg_t value;
6953+
value.loc = loc;
6954+
value.m_value = args[0].m_value;
6955+
fn_args.push_back(al, str);
6956+
fn_args.push_back(al, value);
6957+
6958+
if(args.size() == 2){
6959+
ASR::expr_t *arg_value = args[1].m_value;
6960+
ASR::ttype_t *arg_value_type = ASRUtils::expr_type(arg_value);
6961+
if (!ASRUtils::is_character(*arg_value_type)) {
6962+
throw SemanticError("str.center() argument 2 must be str", loc);
6963+
}
6964+
value.m_value = args[1].m_value;
6965+
fn_args.push_back(al, value);
6966+
}
6967+
} else if(attr_name == "expandtabs") {
6968+
if(args.size() > 1) {
6969+
throw SemanticError("str.expandtabs() takes at most one argument.", loc);
6970+
}
6971+
fn_call_name = "_lpython_str_expandtabs";
6972+
ASR::call_arg_t str;
6973+
str.loc = loc;
6974+
str.m_value = s_var;
6975+
fn_args.push_back(al, str);
6976+
6977+
if(args.size() == 1){
6978+
ASR::expr_t *arg_value = args[0].m_value;
6979+
ASR::ttype_t *arg_value_type = ASRUtils::expr_type(arg_value);
6980+
if (!ASRUtils::is_integer(*arg_value_type)) {
6981+
throw SemanticError("str.expandtabs() argument must be integer", loc);
6982+
}
6983+
6984+
ASR::call_arg_t value;
6985+
value.loc = loc;
6986+
value.m_value = args[0].m_value;
6987+
fn_args.push_back(al, value);
6988+
}
69366989
} else if(attr_name.size() > 2 && attr_name[0] == 'i' && attr_name[1] == 's') {
69376990
/*
69386991
String Validation Methods i.e all "is" based functions are handled here

src/lpython/semantics/python_comptime_eval.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,9 @@ struct PythonIntrinsicProcedures {
100100
{"_lpython_str_isupper", {m_builtin, &not_implemented}},
101101
{"_lpython_str_isdecimal", {m_builtin, &not_implemented}},
102102
{"_lpython_str_isascii", {m_builtin, &not_implemented}},
103-
{"_lpython_str_isspace", {m_builtin, &not_implemented}}
103+
{"_lpython_str_isspace", {m_builtin, &not_implemented}},
104+
{"_lpython_str_center", {m_builtin, &not_implemented}},
105+
{"_lpython_str_expandtabs", {m_builtin, &not_implemented}}
104106
};
105107
}
106108

src/runtime/lpython_builtin.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,6 +1085,65 @@ def _lpython_str_isspace(s: str) -> bool:
10851085
return False
10861086
return True
10871087

1088+
@overload
1089+
def _lpython_str_center(s: str, width: i32, fillchar: str) -> str:
1090+
"""
1091+
Return centered in a string of length width.
1092+
Padding is done using the specified fillchar (default is an ASCII space).
1093+
The original string is returned if width is less than or equal to len(s).
1094+
"""
1095+
if(len(fillchar) != 1):
1096+
raise TypeError("The fill character must be exactly one character long")
1097+
str_len: i32 = len(s)
1098+
if width <= str_len:
1099+
return s
1100+
width -= str_len
1101+
result: str = ""
1102+
left_padding: i32 = i32(width/2) + _mod(width,2)
1103+
i: i32
1104+
for i in range(left_padding):
1105+
result += fillchar
1106+
right_padding: i32 = width - left_padding
1107+
result += s
1108+
for i in range(right_padding):
1109+
result += fillchar
1110+
return result
1111+
1112+
@overload
1113+
def _lpython_str_center(s: str, width: i32) -> str:
1114+
return _lpython_str_center(s, width, ' ')
1115+
1116+
@overload
1117+
def _lpython_str_expandtabs(s: str, tabsize: i32) -> str:
1118+
"""
1119+
Return a copy of the string where all tab characters are replaced
1120+
by one or more spaces, depending on the current column and the given tab size.
1121+
"""
1122+
if len(s) == 0:
1123+
return s
1124+
col: i32 = 0
1125+
result: str = ""
1126+
c: str
1127+
for c in s:
1128+
if c == '\t':
1129+
if tabsize > 0:
1130+
i: i32
1131+
iterations: i32 = tabsize - _mod(col,tabsize)
1132+
for i in range(iterations):
1133+
result += ' '
1134+
col = 0
1135+
elif c == '\n' or c == '\r':
1136+
result += c
1137+
col = 0
1138+
else:
1139+
result += c
1140+
col += 1
1141+
return result
1142+
1143+
@overload
1144+
def _lpython_str_expandtabs(s: str) -> str:
1145+
return _lpython_str_expandtabs(s, 8)
1146+
10881147
def list(s: str) -> list[str]:
10891148
l: list[str] = []
10901149
i: i32

tests/reference/asr-array_01_decl-39cf894.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"outfile": null,
77
"outfile_hash": null,
88
"stdout": "asr-array_01_decl-39cf894.stdout",
9-
"stdout_hash": "34c5f9983e43e6b5c65f021792e415f0c2e4fe5135c6435eb5322719",
9+
"stdout_hash": "292194a8fe4110a90c90bbcbf94f66b70f82978e14108ded75104711",
1010
"stderr": null,
1111
"stderr_hash": null,
1212
"returncode": 0

0 commit comments

Comments
 (0)