Skip to content

Commit 7726b87

Browse files
authored
Merge pull request #425 from namannimmo10/refactor_asr4
Refactor the ASR
2 parents fb7b0e6 + 593b8c4 commit 7726b87

14 files changed

+116
-17
lines changed

src/libasr/ASR.asdl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,13 +227,22 @@ expr
227227
| LogicalConstant(bool value, ttype type)
228228

229229
| ListConstant(expr* args, ttype type)
230+
| ListLen(expr arg, ttype type, expr? value)
230231
| ListConcat(expr left, expr right, ttype type, expr? value)
231232

232233
| ArrayConstant(expr* args, ttype type)
234+
233235
| SetConstant(expr* elements, ttype type)
236+
| SetLen(expr arg, ttype type, expr? value)
237+
234238
| TupleConstant(expr* elements, ttype type)
239+
| TupleLen(expr arg, ttype type, expr? value)
240+
235241
| StringConstant(string s, ttype type)
242+
| StringLen(expr arg, ttype type, expr? value)
243+
236244
| DictConstant(expr* keys, expr* values, ttype type)
245+
| DictLen(expr arg, ttype type, expr? value)
237246
| Var(symbol v)
238247
| ArrayRef(symbol v, array_index* args, ttype type, expr? value)
239248
| DerivedRef(expr v, symbol m, ttype type, expr? value)

src/libasr/asr_utils.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,17 @@ static inline ASR::ttype_t* expr_type(const ASR::expr_t *f)
109109
case ASR::exprType::RealConstant: { return ((ASR::RealConstant_t*)f)->m_type; }
110110
case ASR::exprType::ComplexConstant: { return ((ASR::ComplexConstant_t*)f)->m_type; }
111111
case ASR::exprType::SetConstant: { return ((ASR::SetConstant_t*)f)->m_type; }
112+
case ASR::exprType::SetLen: { return ((ASR::SetLen_t*)f)->m_type; }
112113
case ASR::exprType::ListConstant: { return ((ASR::ListConstant_t*)f)->m_type; }
113114
case ASR::exprType::ListConcat: { return ((ASR::ListConcat_t*)f)->m_type; }
115+
case ASR::exprType::ListLen: { return ((ASR::ListLen_t*)f)->m_type; }
114116
case ASR::exprType::TupleConstant: { return ((ASR::TupleConstant_t*)f)->m_type; }
117+
case ASR::exprType::TupleLen: { return ((ASR::TupleLen_t*)f)->m_type; }
115118
case ASR::exprType::LogicalConstant: { return ((ASR::LogicalConstant_t*)f)->m_type; }
116119
case ASR::exprType::StringConstant: { return ((ASR::StringConstant_t*)f)->m_type; }
120+
case ASR::exprType::StringLen: { return ((ASR::StringLen_t*)f)->m_type; }
117121
case ASR::exprType::DictConstant: { return ((ASR::DictConstant_t*)f)->m_type; }
122+
case ASR::exprType::DictLen: { return ((ASR::DictLen_t*)f)->m_type; }
118123
case ASR::exprType::IntegerBOZ: { return ((ASR::IntegerBOZ_t*)f)->m_type; }
119124
case ASR::exprType::Var: { return EXPR2VAR(f)->m_type; }
120125
case ASR::exprType::ArrayRef: { return ((ASR::ArrayRef_t*)f)->m_type; }
@@ -270,6 +275,11 @@ static inline ASR::expr_t* expr_value(ASR::expr_t *f)
270275
case ASR::exprType::Var: { return EXPR2VAR(f)->m_value; }
271276
case ASR::exprType::StrOp: { return ASR::down_cast<ASR::StrOp_t>(f)->m_value; }
272277
case ASR::exprType::ImpliedDoLoop: { return ASR::down_cast<ASR::ImpliedDoLoop_t>(f)->m_value; }
278+
case ASR::exprType::StringLen: { return ASR::down_cast<ASR::StringLen_t>(f)->m_value; }
279+
case ASR::exprType::DictLen: { return ASR::down_cast<ASR::DictLen_t>(f)->m_value; }
280+
case ASR::exprType::ListLen: { return ASR::down_cast<ASR::ListLen_t>(f)->m_value; }
281+
case ASR::exprType::TupleLen: { return ASR::down_cast<ASR::TupleLen_t>(f)->m_value; }
282+
case ASR::exprType::SetLen: { return ASR::down_cast<ASR::SetLen_t>(f)->m_value; }
273283
case ASR::exprType::ComplexRe: { return ASR::down_cast<ASR::ComplexRe_t>(f)->m_value; }
274284
case ASR::exprType::ComplexIm: { return ASR::down_cast<ASR::ComplexIm_t>(f)->m_value; }
275285
case ASR::exprType::ArrayConstant: // Drop through
@@ -280,6 +290,7 @@ static inline ASR::expr_t* expr_value(ASR::expr_t *f)
280290
case ASR::exprType::TupleConstant: // Drop through
281291
case ASR::exprType::DictConstant: // Drop through
282292
case ASR::exprType::SetConstant: // Drop through
293+
case ASR::exprType::ListConstant: // Drop through
283294
case ASR::exprType::StringConstant:{ // For all Constants
284295
return f;
285296
}

src/libasr/codegen/asr_to_llvm.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2860,6 +2860,17 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
28602860
}
28612861
}
28622862

2863+
void visit_StringLen(const ASR::StringLen_t &x) {
2864+
if (x.m_value) {
2865+
this->visit_expr_wrapper(x.m_value, true);
2866+
return;
2867+
}
2868+
this->visit_expr_wrapper(x.m_arg, true);
2869+
llvm::AllocaInst *parg = builder->CreateAlloca(character_type, nullptr);
2870+
builder->CreateStore(tmp, parg);
2871+
tmp = lfortran_str_len(parg);
2872+
}
2873+
28632874
void visit_BinOp(const ASR::BinOp_t &x) {
28642875
if( x.m_overloaded ) {
28652876
this->visit_expr(*x.m_overloaded);

src/lpython/semantics/python_ast_to_asr.cpp

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2680,6 +2680,67 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
26802680
return nullptr;
26812681
}
26822682

2683+
ASR::asr_t* handle_intrinsic_len(Allocator &al, Vec<ASR::call_arg_t> args,
2684+
const Location &loc) {
2685+
if (args.size() != 1) {
2686+
throw SemanticError("len() takes exactly one argument (" +
2687+
std::to_string(args.size()) + " given)", loc);
2688+
}
2689+
ASR::expr_t *arg = args[0].m_value;
2690+
ASR::ttype_t *type = ASRUtils::expr_type(arg);
2691+
ASR::ttype_t *to_type = ASRUtils::TYPE(ASR::make_Integer_t(al, loc,
2692+
4, nullptr, 0));
2693+
ASR::expr_t *value = nullptr;
2694+
if (ASRUtils::is_character(*type)) {
2695+
if (ASRUtils::expr_value(arg) != nullptr) {
2696+
char* c = ASR::down_cast<ASR::StringConstant_t>(
2697+
ASRUtils::expr_value(arg))->m_s;
2698+
int64_t ival = std::string(c).size();
2699+
value = ASR::down_cast<ASR::expr_t>(make_IntegerConstant_t(al,
2700+
loc, ival, to_type));
2701+
}
2702+
return (ASR::asr_t *)ASR::down_cast<ASR::expr_t>(
2703+
ASR::make_StringLen_t(al, loc, arg, to_type, value));
2704+
} else if (ASR::is_a<ASR::Set_t>(*type)) {
2705+
if (ASRUtils::expr_value(arg) != nullptr) {
2706+
int64_t ival = (int64_t)ASR::down_cast<ASR::SetConstant_t>(
2707+
ASRUtils::expr_value(arg))->n_elements;
2708+
value = ASR::down_cast<ASR::expr_t>(make_IntegerConstant_t(al,
2709+
loc, ival, to_type));
2710+
}
2711+
return (ASR::asr_t *)ASR::down_cast<ASR::expr_t>(
2712+
ASR::make_SetLen_t(al, loc, arg, to_type, value));
2713+
} else if (ASR::is_a<ASR::Tuple_t>(*type)) {
2714+
if (ASRUtils::expr_value(arg) != nullptr) {
2715+
int64_t ival = (int64_t)ASR::down_cast<ASR::TupleConstant_t>(
2716+
ASRUtils::expr_value(arg))->n_elements;
2717+
value = ASR::down_cast<ASR::expr_t>(make_IntegerConstant_t(al,
2718+
loc, ival, to_type));
2719+
}
2720+
return (ASR::asr_t *)ASR::down_cast<ASR::expr_t>(
2721+
ASR::make_TupleLen_t(al, loc, arg, to_type, value));
2722+
} else if (ASR::is_a<ASR::List_t>(*type)) {
2723+
if (ASRUtils::expr_value(arg) != nullptr) {
2724+
int64_t ival = (int64_t)ASR::down_cast<ASR::ListConstant_t>(
2725+
ASRUtils::expr_value(arg))->n_args;
2726+
value = ASR::down_cast<ASR::expr_t>(make_IntegerConstant_t(al,
2727+
loc, ival, to_type));
2728+
}
2729+
return (ASR::asr_t *)ASR::down_cast<ASR::expr_t>(
2730+
ASR::make_ListLen_t(al, loc, arg, to_type, value));
2731+
} else if (ASR::is_a<ASR::Dict_t>(*type)) {
2732+
if (ASRUtils::expr_value(arg) != nullptr) {
2733+
int64_t ival = (int64_t)ASR::down_cast<ASR::DictConstant_t>(
2734+
ASRUtils::expr_value(arg))->n_keys;
2735+
value = ASR::down_cast<ASR::expr_t>(make_IntegerConstant_t(al,
2736+
loc, ival, to_type));
2737+
}
2738+
return (ASR::asr_t *)ASR::down_cast<ASR::expr_t>(
2739+
ASR::make_DictLen_t(al, loc, arg, to_type, value));
2740+
}
2741+
throw SemanticError("len() is only supported for `str`, `set`, `dict`, `list` and `tuple`", loc);
2742+
}
2743+
26832744
void visit_Call(const AST::Call_t &x) {
26842745
std::string call_name;
26852746
Vec<ASR::call_arg_t> args;
@@ -2807,6 +2868,9 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
28072868
tmp = handle_intrinsic_float(al, args, x.base.base.loc);
28082869
}
28092870
return;
2871+
} else if (call_name == "len") {
2872+
tmp = handle_intrinsic_len(al, args, x.base.base.loc);
2873+
return;
28102874
} else {
28112875
// The function was not found and it is not intrinsic
28122876
throw SemanticError("Function '" + call_name + "' is not declared and not intrinsic",

src/lpython/semantics/python_comptime_eval.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ struct PythonIntrinsicProcedures {
3535
{"bool", {m_builtin, &eval_bool}},
3636
{"chr", {m_builtin, &eval_chr}},
3737
{"ord", {m_builtin, &eval_ord}},
38-
{"len", {m_builtin, &eval_len}},
38+
// {"len", {m_builtin, &eval_len}},
3939
{"pow", {m_builtin, &eval_pow}},
4040
// {"int", {m_builtin, &eval_int}},
4141
// {"float", {m_builtin, &eval_float}},

src/runtime/lpython_builtin.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,6 @@ def bool(c: c32) -> bool:
177177
def bool(c: c64) -> bool:
178178
return c.real != 0.0 or _lfortran_zaimag(c) != 0.0
179179

180-
181180
@interface
182181
def len(s: str) -> i32:
183182
"""

tests/constants1.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,17 @@ def test_len():
3535
a = len('')
3636
a = len('test')
3737
a = len("this is a test")
38-
# TODO(namannimmo10): These commented out tests should work
39-
# a = len((1, 2, 3))
40-
# a = len((("c", "b", 3.4), ("c", 3, 5.6)))
41-
# a = len([1, 2, 3])
42-
# a = len([[-4, -5, -6], [-1, -2, -3]])
43-
# a = len({1, 2, 3})
44-
# a = len({1: "c", 2: "b", 3: "c"})
38+
a = len((1, 2, 3))
39+
a = len((("c", "b", 3.4), ("c", 3, 5.6)))
40+
a = len([1, 2, 3])
41+
a = len([[-4, -5, -6], [-1, -2, -3]])
42+
a = len({1, 2, 3})
43+
a = len({1: "c", 2: "b", 3: "c"})
44+
l: list[i32]
45+
l = [1, 2, 3, 4]
46+
a = len(l)
47+
l.append(5)
48+
a = len(l)
4549

4650

4751
def test_bool():

tests/reference/asr-constants1-5828e8a.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
"basename": "asr-constants1-5828e8a",
33
"cmd": "lpython --show-asr --no-color {infile} -o {outfile}",
44
"infile": "tests/constants1.py",
5-
"infile_hash": "0410dc29468f90206a5c2aab56a9761c8d2ffcb239de210d3df2b14f",
5+
"infile_hash": "680bb6f62b6e7d58fdddc891954816cea0c25b9201576498f149849e",
66
"outfile": null,
77
"outfile_hash": null,
88
"stdout": "asr-constants1-5828e8a.stdout",
9-
"stdout_hash": "1c0247f92f98131fbe521af9b0e3555ad3dd5adbe8a034617bd08d86",
9+
"stdout_hash": "5de2d22da16f558bea2c729081ed44549d6639d26c8d1f2aba59c18b",
1010
"stderr": null,
1111
"stderr_hash": null,
1212
"returncode": 0

0 commit comments

Comments
 (0)