Skip to content

Commit 8de503e

Browse files
committed
Add intrinsic list for conversion of string to list
1 parent 312a72c commit 8de503e

File tree

2 files changed

+52
-1
lines changed

2 files changed

+52
-1
lines changed

src/lpython/semantics/python_comptime_eval.h

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ struct PythonIntrinsicProcedures {
5555
{"bin", {m_builtin, &eval_bin}},
5656
{"hex", {m_builtin, &eval_hex}},
5757
{"oct", {m_builtin, &eval_oct}},
58+
{"list", {m_builtin, &eval_list}},
5859
{"complex", {m_builtin, &eval_complex}},
5960
{"_lpython_imag", {m_builtin, &eval__lpython_imag}},
6061
{"divmod", {m_builtin, &eval_divmod}},
@@ -369,6 +370,47 @@ struct PythonIntrinsicProcedures {
369370
}
370371
}
371372

373+
static ASR::expr_t *eval_list(Allocator &al, const Location &loc, Vec<ASR::expr_t*> &args) {
374+
LFORTRAN_ASSERT(ASRUtils::all_args_evaluated(args));
375+
if (args.size() > 1) {
376+
throw SemanticError("list() takes 0 or 1 argument (" +
377+
std::to_string(args.size()) + " given)", loc);
378+
}
379+
LFORTRAN_ASSERT(args.size()==1);
380+
ASR::expr_t *arg = args[0];
381+
ASR::ttype_t *type = ASRUtils::expr_type(arg);
382+
ASR::ttype_t* str_type = ASRUtils::TYPE(ASR::make_Character_t(al,
383+
loc, 1, 1, nullptr, nullptr, 0));
384+
if (ASRUtils::is_integer(*type) || ASRUtils::is_real(*type)
385+
|| ASRUtils::is_complex(*type) || ASRUtils::is_logical(*type)) {
386+
throw SemanticError("Integer, Real, Complex and Boolean are not iterable "
387+
"and cannot be converted to List", loc);
388+
} else if (ASR::is_a<ASR::List_t>(*type)) {
389+
return arg;
390+
} else if (ASRUtils::is_character(*type)) {
391+
ASR::ttype_t *list_type = ASRUtils::TYPE(ASR::make_List_t(al, loc, str_type));
392+
if (ASRUtils::expr_value(arg) != nullptr) {
393+
std::string c = ASR::down_cast<ASR::StringConstant_t>(arg)->m_s;
394+
Vec<ASR::expr_t*> list;
395+
list.reserve(al, c.length());
396+
std::string r;
397+
for (size_t i=0; i<c.length(); i++) {
398+
r.push_back(char(c[i]));
399+
list.push_back(al, ASR::down_cast<ASR::expr_t>(
400+
ASR::make_StringConstant_t(al, loc, s2c(al, r),
401+
str_type)));
402+
r.pop_back();
403+
}
404+
return ASR::down_cast<ASR::expr_t>(ASR::make_ListConstant_t(al, loc, list.p,
405+
list.size(), list_type));
406+
}
407+
} else {
408+
throw SemanticError("'" + ASRUtils::type_to_str_python(type) +
409+
"' object conversion to List is not implemented ",
410+
arg->base.loc);
411+
}
412+
}
413+
372414
static ASR::expr_t *eval_round(Allocator &al, const Location &loc, Vec<ASR::expr_t*> &args) {
373415
LFORTRAN_ASSERT(ASRUtils::all_args_evaluated(args));
374416
ASR::ttype_t *type = ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4, nullptr, 0));
@@ -758,7 +800,7 @@ struct PythonIntrinsicProcedures {
758800
ASR::ttype_t *int_type = ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4, nullptr, 0));
759801
return ASR::down_cast<ASR::expr_t>(ASR::make_IntegerConstant_t(al, loc, -1, int_type));
760802
}
761-
803+
762804
static ASR::expr_t *eval__lpython_str_startswith(Allocator &al, const Location &loc, Vec<ASR::expr_t *> &/*args*/) {
763805
// compile time action implemented on ast->asr
764806
ASR::ttype_t* res_type = ASRUtils::TYPE(ASR::make_Logical_t(al, loc,

src/runtime/lpython_builtin.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -732,3 +732,12 @@ def _lpython_str_startswith(s: str ,sub: str) -> bool:
732732
if res:
733733
res = res and (j == len(sub))
734734
return res
735+
736+
737+
def list(s: str) -> list[str]:
738+
l: list[str]
739+
l = []
740+
i: i32
741+
for i in range(len(s)):
742+
l.append(s[i])
743+
return l

0 commit comments

Comments
 (0)