diff --git a/integration_tests/CMakeLists.txt b/integration_tests/CMakeLists.txt index d546f14bff..60e9022e8c 100644 --- a/integration_tests/CMakeLists.txt +++ b/integration_tests/CMakeLists.txt @@ -290,6 +290,7 @@ RUN(NAME test_builtin_round LABELS cpython llvm c) RUN(NAME test_builtin_divmod LABELS cpython llvm c) RUN(NAME test_math1 LABELS cpython llvm c) RUN(NAME test_math_02 LABELS cpython llvm) +RUN(NAME test_pass_compare LABELS cpython llvm) RUN(NAME test_c_interop_01 LABELS cpython llvm c) RUN(NAME test_c_interop_02 LABELS cpython llvm c EXTRAFILES test_c_interop_02b.c) diff --git a/integration_tests/test_pass_compare.py b/integration_tests/test_pass_compare.py new file mode 100644 index 0000000000..f98dee1416 --- /dev/null +++ b/integration_tests/test_pass_compare.py @@ -0,0 +1,61 @@ +from ltypes import i32 + + +def f(): + a11: tuple[i32, i32] + b11: tuple[i32, i32] + a11 = (1, 2) + b11 = (1, 2) + assert a11 == b11 + c11: tuple[i32, i32] + c11 = (1, 3) + assert a11 != c11 and c11 != b11 + a: tuple[tuple[i32, i32], str, bool] + b: tuple[tuple[i32, i32], str, bool] + a = (a11, 'ok', True) + b = (b11, 'ok', True) + assert a == b + b = (b11, 'notok', True) + assert a != b + + +def g(): + a11: list[i32] + b11: list[i32] + a11 = [1, 2, 3, 4] + b11 = [1, 2, 3, 4] + assert a11 == b11 + a11.append(5) + assert a11 != b11 + c11: list[i32] = [] + assert a11 != c11 + + d11: list[str] = ['a', 'b', '^', '*'] + e11: list[str] = ['a', 'b', '^'] + assert d11 != e11 + e11.append('*') + assert d11 == e11 + + f11: list[tuple[i32, i32]] = [] + x: tuple[i32, i32] + i: i32 + for i in range(10): + x = (i, i+2) + f11.append(x) + + g11: list[tuple[i32, i32]] = [] + for i in range(9): + x = (i, i+2) + g11.append(x) + assert g11 != f11 + x = (9, 11) + g11.append(x) + assert g11 == f11 + + +def check(): + f() + g() + + +check() diff --git a/src/libasr/ASR.asdl b/src/libasr/ASR.asdl index 56e2fdd25e..634f5fa98d 100644 --- a/src/libasr/ASR.asdl +++ b/src/libasr/ASR.asdl @@ -251,12 +251,14 @@ expr | ListConstant(expr* args, ttype type) | ListLen(expr arg, ttype type, expr? value) | ListConcat(expr left, expr right, ttype type, expr? value) + | ListCompare(expr left, cmpop op, expr right, ttype type, expr? value) | SetConstant(expr* elements, ttype type) | SetLen(expr arg, ttype type, expr? value) | TupleConstant(expr* elements, ttype type) | TupleLen(expr arg, ttype type, expr value) + | TupleCompare(expr left, cmpop op, expr right, ttype type, expr? value) | StringConstant(string s, ttype type) | StringConcat(expr left, expr right, ttype type, expr? value) diff --git a/src/libasr/CMakeLists.txt b/src/libasr/CMakeLists.txt index d764506043..bb11494283 100644 --- a/src/libasr/CMakeLists.txt +++ b/src/libasr/CMakeLists.txt @@ -54,6 +54,7 @@ set(SRC pass/update_array_dim_intrinsic_calls.cpp pass/pass_array_by_data.cpp pass/pass_list_expr.cpp + pass/pass_compare.cpp asr_verify.cpp asr_utils.cpp diff --git a/src/libasr/codegen/asr_to_llvm.cpp b/src/libasr/codegen/asr_to_llvm.cpp index 68e9b91657..2f8685b781 100644 --- a/src/libasr/codegen/asr_to_llvm.cpp +++ b/src/libasr/codegen/asr_to_llvm.cpp @@ -6042,6 +6042,10 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor target_type = get_type_from_ttype_t_util(arg_type); break ; } + case (ASR::ttypeType::Tuple) : { + target_type = get_type_from_ttype_t_util(arg_type); + break ; + } default : throw CodeGenError("Type " + ASRUtils::type_to_str(arg_type) + " not implemented yet."); } diff --git a/src/libasr/pass/pass_compare.cpp b/src/libasr/pass/pass_compare.cpp new file mode 100644 index 0000000000..f971c0dd6f --- /dev/null +++ b/src/libasr/pass/pass_compare.cpp @@ -0,0 +1,476 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +namespace LFortran { + +using ASR::down_cast; + +/* + * This ASR pass handles TupleCompare. + */ + + +class CompareExprReplacer : public ASR::BaseExprReplacer +{ +private: + + Allocator& al; + ASR::TranslationUnit_t &unit; + std::map &compare_func_map; + +public: + CompareExprReplacer(Allocator &al_, ASR::TranslationUnit_t &unit_, + std::map &compare_func_map_) : + al(al_), unit(unit_), + compare_func_map(compare_func_map_) + { } + + + #define create_args(x, type, symtab, vec_exprs) { \ + ASR::symbol_t* arg = ASR::down_cast( \ + ASR::make_Variable_t(al, loc, symtab, \ + s2c(al, x), nullptr, 0, ASR::intentType::In, nullptr, nullptr, \ + ASR::storage_typeType::Default, type, \ + ASR::abiType::Source, ASR::accessType::Public, \ + ASR::presenceType::Required, false)); \ + ASR::expr_t* arg_expr = ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg)); \ + vec_exprs.push_back(al, arg_expr); \ + symtab->add_symbol(x, arg); \ + } + + ASR::symbol_t* get_tuple_compare_func(Location& loc, + SymbolTable*& scope, ASR::ttype_t *t) { + std::string type_name = ASRUtils::type_to_str_python(t); + if (compare_func_map.find(type_name) == compare_func_map.end()) { + create_tuple_compare(loc, scope, t); + } + return compare_func_map[type_name]; + } + + ASR::symbol_t* get_list_compare_func(Location& loc, + SymbolTable*& scope, ASR::ttype_t *t) { + std::string type_name = ASRUtils::type_to_str_python(t); + if (compare_func_map.find(type_name) == compare_func_map.end()) { + create_list_compare(loc, scope, t); + } + return compare_func_map[type_name]; + } + + ASR::expr_t* compare_helper(Location& loc, + SymbolTable*& global_scope, ASR::expr_t *left, ASR::expr_t *rig, + ASR::ttype_t *type) { + ASR::ttype_t* bool_type = ASRUtils::TYPE(ASR::make_Logical_t( + al, loc, 4, nullptr, 0)); + switch (type->type) { + case ASR::ttypeType::Integer: { + return ASRUtils::EXPR(ASR::make_IntegerCompare_t(al, + loc, left, ASR::cmpopType::Eq, rig, bool_type, nullptr)); + } + case ASR::ttypeType::Real: { + return ASRUtils::EXPR(ASR::make_RealCompare_t(al, + loc, left, ASR::cmpopType::Eq, rig, bool_type, nullptr)); + } + case ASR::ttypeType::Character: { + return ASRUtils::EXPR(ASR::make_StringCompare_t(al, + loc, left, ASR::cmpopType::Eq, rig, bool_type, nullptr)); + } + case ASR::ttypeType::Complex: { + return ASRUtils::EXPR(ASR::make_ComplexCompare_t(al, + loc, left, ASR::cmpopType::Eq, rig, bool_type, nullptr)); + } + case ASR::ttypeType::Logical: { + return ASRUtils::EXPR(ASR::make_LogicalCompare_t(al, + loc, left, ASR::cmpopType::Eq, rig, bool_type, nullptr)); + } + case ASR::ttypeType::Tuple: { + ASR::symbol_t *fn = get_tuple_compare_func(loc, global_scope, type); + Vec args; + args.reserve(al, 2); + ASR::call_arg_t call_arg; + call_arg.loc = left->base.loc; + call_arg.m_value = left; + args.push_back(al, call_arg); + call_arg.loc = rig->base.loc; + call_arg.m_value = rig; + args.push_back(al, call_arg); + + return ASRUtils::EXPR(ASR::make_FunctionCall_t(al, loc, + fn, nullptr, args.p, args.n, + bool_type, nullptr, nullptr)); + } + case ASR::ttypeType::List: { + ASR::symbol_t *fn = get_list_compare_func(loc, global_scope, type); + Vec args; + args.reserve(al, 2); + ASR::call_arg_t call_arg; + call_arg.loc = left->base.loc; + call_arg.m_value = left; + args.push_back(al, call_arg); + call_arg.loc = rig->base.loc; + call_arg.m_value = rig; + args.push_back(al, call_arg); + + return ASRUtils::EXPR(ASR::make_FunctionCall_t(al, loc, + fn, nullptr, args.p, args.n, + bool_type, nullptr, nullptr)); + } + default: { + LFORTRAN_ASSERT(false); + } + } + } + + void create_tuple_compare(Location& loc, + SymbolTable*& global_scope, ASR::ttype_t* type) { + /* + def _lcompilers_tuple_compare(a: tuple[], b: tuple[]) -> bool: + res: bool = True + for i in range(len(a)): + res &= a[i]==b[i] + return res + */ + SymbolTable* tup_compare_symtab = al.make_new(global_scope); + std::string tuple_type_name = ASRUtils::type_to_str_python(type); + ASR::Tuple_t *tuple_type = ASR::down_cast(type); + + std::string fn_name = global_scope->get_unique_name("_lcompilers_tuple_compare_" + tuple_type_name); + ASR::ttype_t* int_type = ASRUtils::TYPE(ASR::make_Integer_t( + al, loc, 4, nullptr, 0)); + ASR::ttype_t* bool_type = ASRUtils::TYPE(ASR::make_Logical_t( + al, loc, 4, nullptr, 0)); + + Vec arg_exprs; + arg_exprs.reserve(al, 2); + + Vec body; + body.reserve(al, 2 + tuple_type->n_type); + + // Declare arguments + create_args("a", type, tup_compare_symtab, arg_exprs) + create_args("b", type, tup_compare_symtab, arg_exprs) + + // Declare `result` + ASR::symbol_t* arg = ASR::down_cast( + ASR::make_Variable_t(al, loc, tup_compare_symtab, + s2c(al, "result"), nullptr, 0, ASR::intentType::ReturnVar, nullptr, nullptr, + ASR::storage_typeType::Default, bool_type, + ASR::abiType::Source, ASR::accessType::Public, + ASR::presenceType::Required, false)); + ASR::expr_t* result = ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg)); + tup_compare_symtab->add_symbol("result", arg); + + + ASR::expr_t* value = ASRUtils::EXPR(ASR::make_LogicalConstant_t(al, + loc, true, bool_type)); + // Initialize `result` with `True` + ASR::stmt_t* init_stmt = ASRUtils::STMT(ASR::make_Assignment_t(al, loc, + result, value, nullptr)); + body.push_back(al, init_stmt); + + for (size_t i=0; in_type; i++) { + ASR::expr_t *pos_i = ASRUtils::EXPR(ASR::make_IntegerConstant_t(al, loc, i, int_type)); + ASR::expr_t *a_i = ASRUtils::EXPR(ASR::make_TupleItem_t(al, loc, arg_exprs[0], pos_i, + tuple_type->m_type[i], nullptr)); + ASR::expr_t *b_i = ASRUtils::EXPR(ASR::make_TupleItem_t(al, loc, arg_exprs[1], pos_i, + tuple_type->m_type[i], nullptr)); + ASR::expr_t *cmp_i = compare_helper(loc, global_scope, a_i, b_i, tuple_type->m_type[i]); + ASR::expr_t *cmp_and = ASRUtils::EXPR(ASR::make_LogicalBinOp_t(al, loc, + result, ASR::logicalbinopType::And, cmp_i, bool_type, nullptr)); + ASR::stmt_t *t = ASRUtils::STMT(ASR::make_Assignment_t(al, loc, + result, cmp_and, nullptr)); + body.push_back(al, t); + } + + // Return + body.push_back(al, ASRUtils::STMT(ASR::make_Return_t(al, loc))); + + ASR::asr_t *fn = ASR::make_Function_t( + al, loc, + /* a_symtab */ tup_compare_symtab, + /* a_name */ s2c(al, fn_name), + nullptr, 0, + /* a_args */ arg_exprs.p, + /* n_args */ arg_exprs.n, + /* a_body */ body.p, + /* n_body */ body.n, + /* a_return_var */ result, + ASR::abiType::Source, + ASR::accessType::Public, ASR::deftypeType::Implementation, + nullptr, + false, false, false, false, false, + nullptr, 0, + nullptr, 0, + false); + ASR::symbol_t *fn_sym = ASR::down_cast(fn); + global_scope->add_symbol(fn_name, fn_sym); + compare_func_map[tuple_type_name] = fn_sym; + } + + /* + This function replaces `TupleCompare` with a `FunctionCall` which returns + the True if both the Tuples are equal or else returns False. + Converts: + a: tuple[i32, i32] + b: tuple[i32, i32] + assert a == b + + to: + a: tuple[i32, i32] + b: tuple[i32, i32] + assert _lcompilers_tuple_compare(a, b) + */ + void replace_TupleCompare(const ASR::TupleCompare_t* x) { + Location loc = x->base.base.loc; + ASR::ttype_t* bool_type = ASRUtils::TYPE(ASR::make_Logical_t( + al, loc, 4, nullptr, 0)); + Vec args; + args.reserve(al, 2); + ASR::call_arg_t call_arg; + call_arg.loc = x->m_left->base.loc; + call_arg.m_value = x->m_left; + args.push_back(al, call_arg); + call_arg.loc = x->m_right->base.loc; + call_arg.m_value = x->m_right; + args.push_back(al, call_arg); + ASR::symbol_t *fn_sym = get_tuple_compare_func(unit.base.base.loc, + unit.m_global_scope, ASRUtils::expr_type(x->m_left)); + *current_expr = ASRUtils::EXPR(ASR::make_FunctionCall_t(al, loc, + fn_sym, nullptr, args.p, args.n, bool_type, nullptr, nullptr)); + if (x->m_op == ASR::cmpopType::NotEq) { + *current_expr = ASRUtils::EXPR(ASR::make_LogicalNot_t(al, loc, + *current_expr, bool_type, nullptr)); + } + } + + + void _create_list_compare_while_loop(Location &loc, SymbolTable* symtab, + ASR::expr_t* a, ASR::expr_t *b, ASR::expr_t *len, + ASR::expr_t* result, + Vec& body, ASR::ttype_t* item_type) { + Vec idx_vars; + PassUtils::create_idx_vars(idx_vars, 1, loc, al, symtab); + ASR::ttype_t* bool_type = ASRUtils::TYPE(ASR::make_Logical_t( + al, loc, 4, nullptr, 0)); + ASR::ttype_t* int_type = ASRUtils::TYPE(ASR::make_Integer_t( + al, loc, 4, nullptr, 0)); + ASR::expr_t *const_zero = ASRUtils::EXPR(ASR::make_IntegerConstant_t( + al, loc, 0, int_type)); + ASR::expr_t *const_one = ASRUtils::EXPR(ASR::make_IntegerConstant_t( + al, loc, 1, int_type)); + ASR::stmt_t* _tmp = ASRUtils::STMT(ASR::make_Assignment_t( + al, loc, idx_vars[0], const_zero, nullptr)); + body.push_back(al, _tmp); + + + ASR::expr_t* loop_test = ASRUtils::EXPR(ASR::make_IntegerCompare_t( + al, loc, len, ASR::cmpopType::Gt, idx_vars[0], bool_type, nullptr)); + + Vec loop_body; + loop_body.reserve(al, 2); + + ASR::expr_t *a_i = ASRUtils::EXPR(ASR::make_ListItem_t(al, loc, a, idx_vars[0], + item_type, nullptr)); + ASR::expr_t *b_i = ASRUtils::EXPR(ASR::make_ListItem_t(al, loc, b, idx_vars[0], + item_type, nullptr)); + ASR::expr_t *cmp_i = compare_helper(loc, symtab, a_i, b_i, item_type); + ASR::expr_t *cmp_and = ASRUtils::EXPR(ASR::make_LogicalBinOp_t(al, loc, + result, ASR::logicalbinopType::And, cmp_i, bool_type, nullptr)); + _tmp = ASRUtils::STMT(ASR::make_Assignment_t(al, loc, + result, cmp_and, nullptr)); + loop_body.push_back(al, _tmp); + + _tmp = ASRUtils::STMT(ASR::make_Assignment_t( + al, loc, idx_vars[0], ASRUtils::EXPR(ASR::make_IntegerBinOp_t( + al, loc, idx_vars[0], ASR::binopType::Add, const_one, + int_type, nullptr)), nullptr)); + loop_body.push_back(al, _tmp); + + _tmp = ASRUtils::STMT(ASR::make_WhileLoop_t( + al, loc, loop_test, loop_body.p, loop_body.n)); + body.push_back(al, _tmp); + } + + void create_list_compare(Location& loc, + SymbolTable*& global_scope, ASR::ttype_t* type) { + /* + def _lcompilers_list_compare(a: list[], b: list[]) -> bool: + res: bool = True + a_len = len(a) + b_len = len(b) + if a_len != b_len: + return False + i: i32 + for i in range(len(a)): + res &= a[i]==b[i] + return res + */ + SymbolTable* list_compare_symtab = al.make_new(global_scope); + std::string list_type_name = ASRUtils::type_to_str_python(type); + ASR::List_t *list_type = ASR::down_cast(type); + + std::string fn_name = global_scope->get_unique_name("_lcompilers_list_compare_" + list_type_name); + ASR::ttype_t* int_type = ASRUtils::TYPE(ASR::make_Integer_t( + al, loc, 4, nullptr, 0)); + ASR::ttype_t* bool_type = ASRUtils::TYPE(ASR::make_Logical_t( + al, loc, 4, nullptr, 0)); + + Vec arg_exprs; + arg_exprs.reserve(al, 2); + + Vec body; + body.reserve(al, 5); + + // Declare arguments + create_args("a", type, list_compare_symtab, arg_exprs) + create_args("b", type, list_compare_symtab, arg_exprs) + + ASR::expr_t *a_len = ASRUtils::EXPR(ASR::make_ListLen_t(al, loc, + arg_exprs[0], int_type, nullptr)); + ASR::expr_t *b_len = ASRUtils::EXPR(ASR::make_ListLen_t(al, loc, + arg_exprs[1], int_type, nullptr)); + + // Declare `result` + ASR::symbol_t* res_arg = ASR::down_cast( + ASR::make_Variable_t(al, loc, list_compare_symtab, + s2c(al, "result"), nullptr, 0, ASR::intentType::ReturnVar, nullptr, nullptr, + ASR::storage_typeType::Default, bool_type, + ASR::abiType::Source, ASR::accessType::Public, + ASR::presenceType::Required, false)); + ASR::expr_t* result = ASRUtils::EXPR(ASR::make_Var_t(al, loc, res_arg)); + list_compare_symtab->add_symbol("result", res_arg); + + ASR::expr_t* value = ASRUtils::EXPR(ASR::make_LogicalConstant_t(al, + loc, true, bool_type)); + + // Initialize `result` with `True` + ASR::stmt_t* _tmp = ASRUtils::STMT(ASR::make_Assignment_t(al, loc, + result, value, nullptr)); + body.push_back(al, _tmp); + + { + ASR::expr_t* a_test = ASRUtils::EXPR(ASR::make_IntegerCompare_t( + al, loc, a_len, ASR::cmpopType::NotEq, b_len, + bool_type, nullptr)); + + Vec if_body; + if_body.reserve(al, 2); + value = ASRUtils::EXPR(ASR::make_LogicalConstant_t(al, + loc, false, bool_type)); + ASR::stmt_t* if_body_stmt = ASRUtils::STMT(ASR::make_Assignment_t( + al, loc, result, value, nullptr)); + if_body.push_back(al, if_body_stmt); + + // Return + if_body.push_back(al, ASRUtils::STMT(ASR::make_Return_t(al, loc))); + + _tmp = ASRUtils::STMT(ASR::make_If_t(al, loc, a_test, + if_body.p, if_body.n, nullptr, 0)); + body.push_back(al, _tmp); + } + + _create_list_compare_while_loop(loc, global_scope, + arg_exprs[0], arg_exprs[1], a_len, result, + body, list_type->m_type); + + // Return + body.push_back(al, ASRUtils::STMT(ASR::make_Return_t(al, loc))); + + ASR::asr_t *fn = ASR::make_Function_t( + al, loc, + /* a_symtab */ list_compare_symtab, + /* a_name */ s2c(al, fn_name), + nullptr, 0, + /* a_args */ arg_exprs.p, + /* n_args */ arg_exprs.n, + /* a_body */ body.p, + /* n_body */ body.n, + /* a_return_var */ result, + ASR::abiType::Source, + ASR::accessType::Public, ASR::deftypeType::Implementation, + nullptr, + false, false, false, false, false, + nullptr, 0, + nullptr, 0, + false); + ASR::symbol_t *fn_sym = ASR::down_cast(fn); + global_scope->add_symbol(fn_name, fn_sym); + compare_func_map[list_type_name] = fn_sym; + } + + /* + This function replaces `ListCompare` with a `FunctionCall` which returns + the True if both the lists are equal or else returns False. + Converts: + a: list[i32] + b: list[i32] + assert a == b + + to: + a: list[i32] + b: list[i32] + assert _lcompilers_list_compare(a, b) + */ + void replace_ListCompare(const ASR::ListCompare_t* x) { + Location loc = x->base.base.loc; + ASR::ttype_t* bool_type = ASRUtils::TYPE(ASR::make_Logical_t( + al, loc, 4, nullptr, 0)); + Vec args; + args.reserve(al, 2); + ASR::call_arg_t call_arg; + call_arg.loc = x->m_left->base.loc; + call_arg.m_value = x->m_left; + args.push_back(al, call_arg); + call_arg.loc = x->m_right->base.loc; + call_arg.m_value = x->m_right; + args.push_back(al, call_arg); + ASR::symbol_t *fn_sym = get_list_compare_func(unit.base.base.loc, + unit.m_global_scope, ASRUtils::expr_type(x->m_left)); + *current_expr = ASRUtils::EXPR(ASR::make_FunctionCall_t(al, loc, + fn_sym, nullptr, args.p, args.n, bool_type, nullptr, nullptr)); + if (x->m_op == ASR::cmpopType::NotEq) { + *current_expr = ASRUtils::EXPR(ASR::make_LogicalNot_t(al, loc, + *current_expr, bool_type, nullptr)); + } + } + +}; + +class CompareExprVisitor : public ASR::CallReplacerOnExpressionsVisitor +{ +private: + + CompareExprReplacer replacer; + std::map compare_func_map; + +public: + + CompareExprVisitor(Allocator& al_, ASR::TranslationUnit_t &unit_) : + replacer(al_, unit_, compare_func_map) + { } + + void call_replacer() { + replacer.current_expr = current_expr; + replacer.replace_expr(*current_expr); + } + +}; + +void pass_compare(Allocator &al, ASR::TranslationUnit_t &unit, + const LCompilers::PassOptions& /*pass_options*/) { + CompareExprVisitor v(al, unit); + v.visit_TranslationUnit(unit); + PassUtils::UpdateDependenciesVisitor u(al); + u.visit_TranslationUnit(unit); +} + + +} // namespace LFortran diff --git a/src/libasr/pass/pass_compare.h b/src/libasr/pass/pass_compare.h new file mode 100644 index 0000000000..fd59ae2d7a --- /dev/null +++ b/src/libasr/pass/pass_compare.h @@ -0,0 +1,14 @@ +#ifndef LIBASR_PASS_COMPARE_H +#define LIBASR_PASS_COMPARE_H + +#include +#include + +namespace LFortran { + + void pass_compare(Allocator &al, ASR::TranslationUnit_t &unit, + const LCompilers::PassOptions& /*pass_options*/); + +} // namespace LFortran + +#endif // LIBASR_PASS_COMPARE_H diff --git a/src/libasr/pass/pass_manager.h b/src/libasr/pass/pass_manager.h index 6d8c9b3f32..6bddd46df6 100644 --- a/src/libasr/pass/pass_manager.h +++ b/src/libasr/pass/pass_manager.h @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -79,7 +80,8 @@ namespace LCompilers { {"array_dim_intrinsics_update", &LFortran::pass_update_array_dim_intrinsic_calls}, {"pass_list_expr", &LFortran::pass_list_expr}, {"pass_array_by_data", &LFortran::pass_array_by_data}, - {"subroutine_from_function", &LFortran::pass_create_subroutine_from_function} + {"subroutine_from_function", &LFortran::pass_create_subroutine_from_function}, + {"pass_compare", &LFortran::pass_compare} }; bool is_fast; @@ -126,7 +128,8 @@ namespace LCompilers { "forall", "select_case", "inline_function_calls", - "unused_functions" + "unused_functions", + "pass_compare" }; _with_optimization_passes = { diff --git a/src/lpython/semantics/python_ast_to_asr.cpp b/src/lpython/semantics/python_ast_to_asr.cpp index 545b635200..f6ab880f4e 100644 --- a/src/lpython/semantics/python_ast_to_asr.cpp +++ b/src/lpython/semantics/python_ast_to_asr.cpp @@ -5109,6 +5109,21 @@ class BodyVisitor : public CommonVisitor { } tmp = ASR::make_StringCompare_t(al, x.base.base.loc, left, asr_op, right, type, value); + } else if (ASR::is_a(*dest_type)) { + if (asr_op != ASR::cmpopType::Eq && asr_op != ASR::cmpopType::NotEq) { + throw SemanticError("Only Equal and Not-equal operators are supported for Tuples", + x.base.base.loc); + } + tmp = ASR::make_TupleCompare_t(al, x.base.base.loc, left, asr_op, right, type, value); + } else if (ASR::is_a(*dest_type)) { + if (asr_op != ASR::cmpopType::Eq && asr_op != ASR::cmpopType::NotEq) { + throw SemanticError("Only Equal and Not-equal operators are supported for Tuples", + x.base.base.loc); + } + tmp = ASR::make_ListCompare_t(al, x.base.base.loc, left, asr_op, right, type, value); + } else { + throw SemanticError("Compare not supported for type: " + ASRUtils::type_to_str_python(dest_type), + x.base.base.loc); } if (overloaded != nullptr) { diff --git a/tests/list1.py b/tests/list1.py index 1c40dad565..62a71cd9ae 100644 --- a/tests/list1.py +++ b/tests/list1.py @@ -25,3 +25,9 @@ def test_List(): d = a.pop(2) a += [4, 5] a = [6, 7] + a + + a11: list[i32] + b11: list[i32] + a11 = [1, 2] + b11 = [3, 4] + assert a11 == b11 diff --git a/tests/reference/asr-list1-770ba33.json b/tests/reference/asr-list1-770ba33.json index 06ec72fd2c..ce42ef8d5f 100644 --- a/tests/reference/asr-list1-770ba33.json +++ b/tests/reference/asr-list1-770ba33.json @@ -2,11 +2,11 @@ "basename": "asr-list1-770ba33", "cmd": "lpython --show-asr --no-color {infile} -o {outfile}", "infile": "tests/list1.py", - "infile_hash": "4c857d1e852be3d5d49027d17478d3d52a27c66656fd876a004d8b8b", + "infile_hash": "9d6b3f1a83a585d5a7a5e50ff5e1ddd15705fce268208d0cc2749514", "outfile": null, "outfile_hash": null, "stdout": "asr-list1-770ba33.stdout", - "stdout_hash": "adb191d97b45e0ba5957d75510638cb272a5e26d5c3c4b227d9a9bd9", + "stdout_hash": "bb4f1bf6c45bb32adc5c76731dcf8e8bff7561d58b0a1c0ec86bda47", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-list1-770ba33.stdout b/tests/reference/asr-list1-770ba33.stdout index e8a66a247b..aa673bc3f2 100644 --- a/tests/reference/asr-list1-770ba33.stdout +++ b/tests/reference/asr-list1-770ba33.stdout @@ -1 +1 @@ -(TranslationUnit (SymbolTable 1 {main_program: (Program (SymbolTable 3 {}) main_program [] []), test_List: (Function (SymbolTable 2 {a: (Variable 2 a [] Local () () Default (List (Integer 4 [])) Source Public Required .false.), b: (Variable 2 b [] Local () () Default (List (Character 1 -2 () [])) Source Public Required .false.), c: (Variable 2 c [] Local () () Default (List (List (Integer 4 []))) Source Public Required .false.), d: (Variable 2 d [] Local () () Default (Integer 4 []) Source Public Required .false.), e: (Variable 2 e [] Local () () Default (List (List (Character 1 -2 () []))) Source Public Required .false.)}) test_List [] [] [(= (Var 2 a) (ListConstant [(IntegerConstant 1 (Integer 4 [])) (IntegerConstant 2 (Integer 4 [])) (IntegerConstant 3 (Integer 4 []))] (List (Integer 4 []))) ()) (= (Var 2 a) (ListConstant [(IntegerUnaryMinus (IntegerConstant 3 (Integer 4 [])) (Integer 4 []) (IntegerConstant -3 (Integer 4 []))) (IntegerUnaryMinus (IntegerConstant 2 (Integer 4 [])) (Integer 4 []) (IntegerConstant -2 (Integer 4 []))) (IntegerUnaryMinus (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) (IntegerConstant -1 (Integer 4 [])))] (List (Integer 4 []))) ()) (= (Var 2 b) (ListConstant [(StringConstant "a" (Character 1 1 () [])) (StringConstant "b" (Character 1 1 () [])) (StringConstant "c" (Character 1 1 () []))] (List (Character 1 1 () []))) ()) (= (Var 2 c) (ListConstant [(ListConstant [(IntegerConstant 1 (Integer 4 [])) (IntegerConstant 2 (Integer 4 [])) (IntegerConstant 3 (Integer 4 []))] (List (Integer 4 []))) (ListConstant [(IntegerConstant 4 (Integer 4 [])) (IntegerConstant 5 (Integer 4 [])) (IntegerConstant 6 (Integer 4 []))] (List (Integer 4 [])))] (List (List (Integer 4 [])))) ()) (= (Var 2 d) (ListItem (Var 2 a) (IntegerConstant 2 (Integer 4 [])) (Integer 4 []) ()) ()) (= (Var 2 e) (ListConstant [(ListConstant [(StringConstant "a" (Character 1 1 () [])) (StringConstant "b" (Character 1 1 () [])) (StringConstant "c" (Character 1 1 () []))] (List (Character 1 1 () []))) (ListConstant [(StringConstant "d" (Character 1 1 () [])) (StringConstant "e" (Character 1 1 () []))] (List (Character 1 1 () [])))] (List (List (Character 1 1 () [])))) ()) (ListAppend (Var 2 a) (IntegerConstant 10 (Integer 4 []))) (ListRemove (Var 2 a) (IntegerConstant 1 (Integer 4 []))) (ListInsert (Var 2 a) (IntegerConstant 2 (Integer 4 [])) (IntegerConstant 13 (Integer 4 []))) (= (Var 2 a) (ListSection (Var 2 a) ((IntegerConstant 0 (Integer 4 [])) (IntegerConstant 2 (Integer 4 [])) ()) (List (Integer 4 [])) ()) ()) (= (Var 2 d) (ListPop (Var 2 a) (IntegerConstant -1 (Integer 4 [])) (Integer 4 []) ()) ()) (= (Var 2 d) (ListPop (Var 2 a) (IntegerConstant 2 (Integer 4 [])) (Integer 4 []) ()) ()) (= (Var 2 a) (ListConcat (Var 2 a) (ListConstant [(IntegerConstant 4 (Integer 4 [])) (IntegerConstant 5 (Integer 4 []))] (List (Integer 4 []))) (List (Integer 4 [])) ()) ()) (= (Var 2 a) (ListConcat (ListConstant [(IntegerConstant 6 (Integer 4 [])) (IntegerConstant 7 (Integer 4 []))] (List (Integer 4 []))) (Var 2 a) (List (Integer 4 [])) ()) ())] () Source Public Implementation () .false. .false. .false. .false. .false. [] [] .false.)}) []) +(TranslationUnit (SymbolTable 1 {main_program: (Program (SymbolTable 3 {}) main_program [] []), test_List: (Function (SymbolTable 2 {a: (Variable 2 a [] Local () () Default (List (Integer 4 [])) Source Public Required .false.), a11: (Variable 2 a11 [] Local () () Default (List (Integer 4 [])) Source Public Required .false.), b: (Variable 2 b [] Local () () Default (List (Character 1 -2 () [])) Source Public Required .false.), b11: (Variable 2 b11 [] Local () () Default (List (Integer 4 [])) Source Public Required .false.), c: (Variable 2 c [] Local () () Default (List (List (Integer 4 []))) Source Public Required .false.), d: (Variable 2 d [] Local () () Default (Integer 4 []) Source Public Required .false.), e: (Variable 2 e [] Local () () Default (List (List (Character 1 -2 () []))) Source Public Required .false.)}) test_List [] [] [(= (Var 2 a) (ListConstant [(IntegerConstant 1 (Integer 4 [])) (IntegerConstant 2 (Integer 4 [])) (IntegerConstant 3 (Integer 4 []))] (List (Integer 4 []))) ()) (= (Var 2 a) (ListConstant [(IntegerUnaryMinus (IntegerConstant 3 (Integer 4 [])) (Integer 4 []) (IntegerConstant -3 (Integer 4 []))) (IntegerUnaryMinus (IntegerConstant 2 (Integer 4 [])) (Integer 4 []) (IntegerConstant -2 (Integer 4 []))) (IntegerUnaryMinus (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) (IntegerConstant -1 (Integer 4 [])))] (List (Integer 4 []))) ()) (= (Var 2 b) (ListConstant [(StringConstant "a" (Character 1 1 () [])) (StringConstant "b" (Character 1 1 () [])) (StringConstant "c" (Character 1 1 () []))] (List (Character 1 1 () []))) ()) (= (Var 2 c) (ListConstant [(ListConstant [(IntegerConstant 1 (Integer 4 [])) (IntegerConstant 2 (Integer 4 [])) (IntegerConstant 3 (Integer 4 []))] (List (Integer 4 []))) (ListConstant [(IntegerConstant 4 (Integer 4 [])) (IntegerConstant 5 (Integer 4 [])) (IntegerConstant 6 (Integer 4 []))] (List (Integer 4 [])))] (List (List (Integer 4 [])))) ()) (= (Var 2 d) (ListItem (Var 2 a) (IntegerConstant 2 (Integer 4 [])) (Integer 4 []) ()) ()) (= (Var 2 e) (ListConstant [(ListConstant [(StringConstant "a" (Character 1 1 () [])) (StringConstant "b" (Character 1 1 () [])) (StringConstant "c" (Character 1 1 () []))] (List (Character 1 1 () []))) (ListConstant [(StringConstant "d" (Character 1 1 () [])) (StringConstant "e" (Character 1 1 () []))] (List (Character 1 1 () [])))] (List (List (Character 1 1 () [])))) ()) (ListAppend (Var 2 a) (IntegerConstant 10 (Integer 4 []))) (ListRemove (Var 2 a) (IntegerConstant 1 (Integer 4 []))) (ListInsert (Var 2 a) (IntegerConstant 2 (Integer 4 [])) (IntegerConstant 13 (Integer 4 []))) (= (Var 2 a) (ListSection (Var 2 a) ((IntegerConstant 0 (Integer 4 [])) (IntegerConstant 2 (Integer 4 [])) ()) (List (Integer 4 [])) ()) ()) (= (Var 2 d) (ListPop (Var 2 a) (IntegerConstant -1 (Integer 4 [])) (Integer 4 []) ()) ()) (= (Var 2 d) (ListPop (Var 2 a) (IntegerConstant 2 (Integer 4 [])) (Integer 4 []) ()) ()) (= (Var 2 a) (ListConcat (Var 2 a) (ListConstant [(IntegerConstant 4 (Integer 4 [])) (IntegerConstant 5 (Integer 4 []))] (List (Integer 4 []))) (List (Integer 4 [])) ()) ()) (= (Var 2 a) (ListConcat (ListConstant [(IntegerConstant 6 (Integer 4 [])) (IntegerConstant 7 (Integer 4 []))] (List (Integer 4 []))) (Var 2 a) (List (Integer 4 [])) ()) ()) (= (Var 2 a11) (ListConstant [(IntegerConstant 1 (Integer 4 [])) (IntegerConstant 2 (Integer 4 []))] (List (Integer 4 []))) ()) (= (Var 2 b11) (ListConstant [(IntegerConstant 3 (Integer 4 [])) (IntegerConstant 4 (Integer 4 []))] (List (Integer 4 []))) ()) (Assert (ListCompare (Var 2 a11) Eq (Var 2 b11) (Logical 4 []) ()) ())] () Source Public Implementation () .false. .false. .false. .false. .false. [] [] .false.)}) []) diff --git a/tests/reference/asr-tuple1-09972ab.json b/tests/reference/asr-tuple1-09972ab.json index 823a8d71e5..40d13a3425 100644 --- a/tests/reference/asr-tuple1-09972ab.json +++ b/tests/reference/asr-tuple1-09972ab.json @@ -2,11 +2,11 @@ "basename": "asr-tuple1-09972ab", "cmd": "lpython --show-asr --no-color {infile} -o {outfile}", "infile": "tests/tuple1.py", - "infile_hash": "f02acdb1d699677006d588559df9554308f77a2d171bfec71ed41c41", + "infile_hash": "aed9320f34b5eec1d9ce30d9ef28abeaf9c1faaf421d87b34148ae04", "outfile": null, "outfile_hash": null, "stdout": "asr-tuple1-09972ab.stdout", - "stdout_hash": "f36c338c57271124a9dbd7ae5d8eeeb918bdd173140f481014b9e722", + "stdout_hash": "046230771c97d377cfffb5758f3ac02c32b741984a3bf601b2f0c1dd", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-tuple1-09972ab.stdout b/tests/reference/asr-tuple1-09972ab.stdout index b82626897f..bf5630c4f6 100644 --- a/tests/reference/asr-tuple1-09972ab.stdout +++ b/tests/reference/asr-tuple1-09972ab.stdout @@ -1 +1 @@ -(TranslationUnit (SymbolTable 1 {main_program: (Program (SymbolTable 3 {}) main_program [] []), test_Tuple: (Function (SymbolTable 2 {a1: (Variable 2 a1 [] Local () () Default (Tuple [(Integer 4 []) (Integer 4 []) (Integer 4 [])]) Source Public Required .false.), a2: (Variable 2 a2 [] Local () () Default (Tuple [(Character 1 -2 () []) (Character 1 -2 () []) (Character 1 -2 () [])]) Source Public Required .false.), a3: (Variable 2 a3 [] Local () () Default (Tuple [(Integer 4 []) (Integer 4 []) (Real 4 []) (Character 1 -2 () [])]) Source Public Required .false.), a4: (Variable 2 a4 [] Local () () Default (Tuple [(Tuple [(Integer 4 []) (Integer 4 []) (Integer 4 [])]) (Tuple [(Integer 4 []) (Integer 4 []) (Integer 4 [])])]) Source Public Required .false.), a5: (Variable 2 a5 [] Local () () Default (Tuple [(Tuple [(Character 1 -2 () []) (Character 1 -2 () []) (Real 4 [])]) (Tuple [(Character 1 -2 () []) (Integer 4 []) (Real 4 [])])]) Source Public Required .false.), b0: (Variable 2 b0 [] Local () () Default (Integer 4 []) Source Public Required .false.), b1: (Variable 2 b1 [] Local () () Default (Integer 4 []) Source Public Required .false.), float_mem: (Variable 2 float_mem [] Local () () Default (Real 4 []) Source Public Required .false.), float_mem1: (Variable 2 float_mem1 [] Local () () Default (Real 4 []) Source Public Required .false.), float_mem2: (Variable 2 float_mem2 [] Local () () Default (Real 4 []) Source Public Required .false.)}) test_Tuple [] [] [(= (Var 2 a1) (TupleConstant [(IntegerConstant 1 (Integer 4 [])) (IntegerConstant 2 (Integer 4 [])) (IntegerConstant 3 (Integer 4 []))] (Tuple [(Integer 4 []) (Integer 4 []) (Integer 4 [])])) ()) (= (Var 2 a1) (TupleConstant [(IntegerUnaryMinus (IntegerConstant 3 (Integer 4 [])) (Integer 4 []) (IntegerConstant -3 (Integer 4 []))) (IntegerUnaryMinus (IntegerConstant 2 (Integer 4 [])) (Integer 4 []) (IntegerConstant -2 (Integer 4 []))) (IntegerUnaryMinus (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) (IntegerConstant -1 (Integer 4 [])))] (Tuple [(Integer 4 []) (Integer 4 []) (Integer 4 [])])) ()) (= (Var 2 a2) (TupleConstant [(StringConstant "a" (Character 1 1 () [])) (StringConstant "b" (Character 1 1 () [])) (StringConstant "c" (Character 1 1 () []))] (Tuple [(Character 1 1 () []) (Character 1 1 () []) (Character 1 1 () [])])) ()) (= (Var 2 float_mem) (Cast (RealConstant 0.450000 (Real 8 [])) RealToReal (Real 4 []) (RealConstant 0.450000 (Real 4 []))) ()) (= (Var 2 a3) (TupleConstant [(IntegerUnaryMinus (IntegerConstant 2 (Integer 4 [])) (Integer 4 []) (IntegerConstant -2 (Integer 4 []))) (IntegerUnaryMinus (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) (IntegerConstant -1 (Integer 4 []))) (Var 2 float_mem) (StringConstant "d" (Character 1 1 () []))] (Tuple [(Integer 4 []) (Integer 4 []) (Real 4 []) (Character 1 1 () [])])) ()) (= (Var 2 a4) (TupleConstant [(TupleConstant [(IntegerConstant 1 (Integer 4 [])) (IntegerConstant 2 (Integer 4 [])) (IntegerConstant 3 (Integer 4 []))] (Tuple [(Integer 4 []) (Integer 4 []) (Integer 4 [])])) (TupleConstant [(IntegerConstant 4 (Integer 4 [])) (IntegerConstant 5 (Integer 4 [])) (IntegerConstant 6 (Integer 4 []))] (Tuple [(Integer 4 []) (Integer 4 []) (Integer 4 [])]))] (Tuple [(Tuple [(Integer 4 []) (Integer 4 []) (Integer 4 [])]) (Tuple [(Integer 4 []) (Integer 4 []) (Integer 4 [])])])) ()) (= (Var 2 float_mem1) (Cast (RealConstant 3.400000 (Real 8 [])) RealToReal (Real 4 []) (RealConstant 3.400000 (Real 4 []))) ()) (= (Var 2 float_mem2) (Cast (RealConstant 5.600000 (Real 8 [])) RealToReal (Real 4 []) (RealConstant 5.600000 (Real 4 []))) ()) (= (Var 2 a5) (TupleConstant [(TupleConstant [(StringConstant "a" (Character 1 1 () [])) (StringConstant "b" (Character 1 1 () [])) (Var 2 float_mem1)] (Tuple [(Character 1 1 () []) (Character 1 1 () []) (Real 4 [])])) (TupleConstant [(StringConstant "c" (Character 1 1 () [])) (IntegerConstant 3 (Integer 4 [])) (Var 2 float_mem2)] (Tuple [(Character 1 1 () []) (Integer 4 []) (Real 4 [])]))] (Tuple [(Tuple [(Character 1 1 () []) (Character 1 1 () []) (Real 4 [])]) (Tuple [(Character 1 1 () []) (Integer 4 []) (Real 4 [])])])) ()) (= (Var 2 b0) (TupleItem (Var 2 a1) (IntegerConstant 0 (Integer 4 [])) (Integer 4 []) ()) ()) (= (TupleConstant [(Var 2 b0) (Var 2 b1)] (Tuple [(Integer 4 []) (Integer 4 [])])) (TupleConstant [(TupleItem (Var 2 a1) (IntegerConstant 2 (Integer 4 [])) (Integer 4 []) ()) (TupleItem (Var 2 a1) (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) ())] (Tuple [(Integer 4 []) (Integer 4 [])])) ())] () Source Public Implementation () .false. .false. .false. .false. .false. [] [] .false.)}) []) +(TranslationUnit (SymbolTable 1 {main_program: (Program (SymbolTable 3 {}) main_program [] []), test_Tuple: (Function (SymbolTable 2 {a1: (Variable 2 a1 [] Local () () Default (Tuple [(Integer 4 []) (Integer 4 []) (Integer 4 [])]) Source Public Required .false.), a11: (Variable 2 a11 [] Local () () Default (Tuple [(Integer 4 []) (Integer 4 [])]) Source Public Required .false.), a2: (Variable 2 a2 [] Local () () Default (Tuple [(Character 1 -2 () []) (Character 1 -2 () []) (Character 1 -2 () [])]) Source Public Required .false.), a3: (Variable 2 a3 [] Local () () Default (Tuple [(Integer 4 []) (Integer 4 []) (Real 4 []) (Character 1 -2 () [])]) Source Public Required .false.), a4: (Variable 2 a4 [] Local () () Default (Tuple [(Tuple [(Integer 4 []) (Integer 4 []) (Integer 4 [])]) (Tuple [(Integer 4 []) (Integer 4 []) (Integer 4 [])])]) Source Public Required .false.), a5: (Variable 2 a5 [] Local () () Default (Tuple [(Tuple [(Character 1 -2 () []) (Character 1 -2 () []) (Real 4 [])]) (Tuple [(Character 1 -2 () []) (Integer 4 []) (Real 4 [])])]) Source Public Required .false.), b0: (Variable 2 b0 [] Local () () Default (Integer 4 []) Source Public Required .false.), b1: (Variable 2 b1 [] Local () () Default (Integer 4 []) Source Public Required .false.), b11: (Variable 2 b11 [] Local () () Default (Tuple [(Integer 4 []) (Integer 4 [])]) Source Public Required .false.), float_mem: (Variable 2 float_mem [] Local () () Default (Real 4 []) Source Public Required .false.), float_mem1: (Variable 2 float_mem1 [] Local () () Default (Real 4 []) Source Public Required .false.), float_mem2: (Variable 2 float_mem2 [] Local () () Default (Real 4 []) Source Public Required .false.)}) test_Tuple [] [] [(= (Var 2 a1) (TupleConstant [(IntegerConstant 1 (Integer 4 [])) (IntegerConstant 2 (Integer 4 [])) (IntegerConstant 3 (Integer 4 []))] (Tuple [(Integer 4 []) (Integer 4 []) (Integer 4 [])])) ()) (= (Var 2 a1) (TupleConstant [(IntegerUnaryMinus (IntegerConstant 3 (Integer 4 [])) (Integer 4 []) (IntegerConstant -3 (Integer 4 []))) (IntegerUnaryMinus (IntegerConstant 2 (Integer 4 [])) (Integer 4 []) (IntegerConstant -2 (Integer 4 []))) (IntegerUnaryMinus (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) (IntegerConstant -1 (Integer 4 [])))] (Tuple [(Integer 4 []) (Integer 4 []) (Integer 4 [])])) ()) (= (Var 2 a2) (TupleConstant [(StringConstant "a" (Character 1 1 () [])) (StringConstant "b" (Character 1 1 () [])) (StringConstant "c" (Character 1 1 () []))] (Tuple [(Character 1 1 () []) (Character 1 1 () []) (Character 1 1 () [])])) ()) (= (Var 2 float_mem) (Cast (RealConstant 0.450000 (Real 8 [])) RealToReal (Real 4 []) (RealConstant 0.450000 (Real 4 []))) ()) (= (Var 2 a3) (TupleConstant [(IntegerUnaryMinus (IntegerConstant 2 (Integer 4 [])) (Integer 4 []) (IntegerConstant -2 (Integer 4 []))) (IntegerUnaryMinus (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) (IntegerConstant -1 (Integer 4 []))) (Var 2 float_mem) (StringConstant "d" (Character 1 1 () []))] (Tuple [(Integer 4 []) (Integer 4 []) (Real 4 []) (Character 1 1 () [])])) ()) (= (Var 2 a4) (TupleConstant [(TupleConstant [(IntegerConstant 1 (Integer 4 [])) (IntegerConstant 2 (Integer 4 [])) (IntegerConstant 3 (Integer 4 []))] (Tuple [(Integer 4 []) (Integer 4 []) (Integer 4 [])])) (TupleConstant [(IntegerConstant 4 (Integer 4 [])) (IntegerConstant 5 (Integer 4 [])) (IntegerConstant 6 (Integer 4 []))] (Tuple [(Integer 4 []) (Integer 4 []) (Integer 4 [])]))] (Tuple [(Tuple [(Integer 4 []) (Integer 4 []) (Integer 4 [])]) (Tuple [(Integer 4 []) (Integer 4 []) (Integer 4 [])])])) ()) (= (Var 2 float_mem1) (Cast (RealConstant 3.400000 (Real 8 [])) RealToReal (Real 4 []) (RealConstant 3.400000 (Real 4 []))) ()) (= (Var 2 float_mem2) (Cast (RealConstant 5.600000 (Real 8 [])) RealToReal (Real 4 []) (RealConstant 5.600000 (Real 4 []))) ()) (= (Var 2 a5) (TupleConstant [(TupleConstant [(StringConstant "a" (Character 1 1 () [])) (StringConstant "b" (Character 1 1 () [])) (Var 2 float_mem1)] (Tuple [(Character 1 1 () []) (Character 1 1 () []) (Real 4 [])])) (TupleConstant [(StringConstant "c" (Character 1 1 () [])) (IntegerConstant 3 (Integer 4 [])) (Var 2 float_mem2)] (Tuple [(Character 1 1 () []) (Integer 4 []) (Real 4 [])]))] (Tuple [(Tuple [(Character 1 1 () []) (Character 1 1 () []) (Real 4 [])]) (Tuple [(Character 1 1 () []) (Integer 4 []) (Real 4 [])])])) ()) (= (Var 2 b0) (TupleItem (Var 2 a1) (IntegerConstant 0 (Integer 4 [])) (Integer 4 []) ()) ()) (= (TupleConstant [(Var 2 b0) (Var 2 b1)] (Tuple [(Integer 4 []) (Integer 4 [])])) (TupleConstant [(TupleItem (Var 2 a1) (IntegerConstant 2 (Integer 4 [])) (Integer 4 []) ()) (TupleItem (Var 2 a1) (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) ())] (Tuple [(Integer 4 []) (Integer 4 [])])) ()) (= (Var 2 a11) (TupleConstant [(IntegerConstant 1 (Integer 4 [])) (IntegerConstant 2 (Integer 4 []))] (Tuple [(Integer 4 []) (Integer 4 [])])) ()) (= (Var 2 b11) (TupleConstant [(IntegerConstant 1 (Integer 4 [])) (IntegerConstant 2 (Integer 4 []))] (Tuple [(Integer 4 []) (Integer 4 [])])) ()) (Assert (TupleCompare (Var 2 a11) Eq (Var 2 b11) (Logical 4 []) ()) ())] () Source Public Implementation () .false. .false. .false. .false. .false. [] [] .false.)}) []) diff --git a/tests/reference/ast-list1-9ce2da0.json b/tests/reference/ast-list1-9ce2da0.json index 22f79d6214..8149dcf161 100644 --- a/tests/reference/ast-list1-9ce2da0.json +++ b/tests/reference/ast-list1-9ce2da0.json @@ -2,11 +2,11 @@ "basename": "ast-list1-9ce2da0", "cmd": "lpython --show-ast --no-color {infile} -o {outfile}", "infile": "tests/list1.py", - "infile_hash": "4c857d1e852be3d5d49027d17478d3d52a27c66656fd876a004d8b8b", + "infile_hash": "9d6b3f1a83a585d5a7a5e50ff5e1ddd15705fce268208d0cc2749514", "outfile": null, "outfile_hash": null, "stdout": "ast-list1-9ce2da0.stdout", - "stdout_hash": "ed4674200beb3089b0bbde32b6dc299e110c41a1e48ef3d19cc11a5f", + "stdout_hash": "17a1a6a86b913cbe96c4e0a731e2647fffc92b2ad058771fce0158dc", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/ast-list1-9ce2da0.stdout b/tests/reference/ast-list1-9ce2da0.stdout index d1f326c13c..12e6c46d99 100644 --- a/tests/reference/ast-list1-9ce2da0.stdout +++ b/tests/reference/ast-list1-9ce2da0.stdout @@ -1 +1 @@ -(Module [(FunctionDef test_List ([] [] [] [] [] [] []) [(AnnAssign (Name a Store) (Subscript (Name list Load) (Name i32 Load) Load) () 1) (Assign [(Name a Store)] (List [(ConstantInt 1 ()) (ConstantInt 2 ()) (ConstantInt 3 ())] Load) ()) (Assign [(Name a Store)] (List [(UnaryOp USub (ConstantInt 3 ())) (UnaryOp USub (ConstantInt 2 ())) (UnaryOp USub (ConstantInt 1 ()))] Load) ()) (AnnAssign (Name b Store) (Subscript (Name list Load) (Name str Load) Load) () 1) (Assign [(Name b Store)] (List [(ConstantStr "a" ()) (ConstantStr "b" ()) (ConstantStr "c" ())] Load) ()) (AnnAssign (Name c Store) (Subscript (Name list Load) (Subscript (Name list Load) (Name i32 Load) Load) Load) () 1) (Assign [(Name c Store)] (List [(List [(ConstantInt 1 ()) (ConstantInt 2 ()) (ConstantInt 3 ())] Load) (List [(ConstantInt 4 ()) (ConstantInt 5 ()) (ConstantInt 6 ())] Load)] Load) ()) (AnnAssign (Name d Store) (Name i32 Load) () 1) (Assign [(Name d Store)] (Subscript (Name a Load) (ConstantInt 2 ()) Load) ()) (AnnAssign (Name e Store) (Subscript (Name list Load) (Subscript (Name list Load) (Name str Load) Load) Load) () 1) (Assign [(Name e Store)] (List [(List [(ConstantStr "a" ()) (ConstantStr "b" ()) (ConstantStr "c" ())] Load) (List [(ConstantStr "d" ()) (ConstantStr "e" ())] Load)] Load) ()) (Expr (Call (Attribute (Name a Load) append Load) [(ConstantInt 10 ())] [])) (Expr (Call (Attribute (Name a Load) remove Load) [(ConstantInt 1 ())] [])) (Expr (Call (Attribute (Name a Load) insert Load) [(ConstantInt 2 ()) (ConstantInt 13 ())] [])) (Assign [(Name a Store)] (Subscript (Name a Load) (Slice (ConstantInt 0 ()) (ConstantInt 2 ()) ()) Load) ()) (Assign [(Name d Store)] (Call (Attribute (Name a Load) pop Load) [] []) ()) (Assign [(Name d Store)] (Call (Attribute (Name a Load) pop Load) [(ConstantInt 2 ())] []) ()) (AugAssign (Name a Store) Add (List [(ConstantInt 4 ()) (ConstantInt 5 ())] Load)) (Assign [(Name a Store)] (BinOp (List [(ConstantInt 6 ()) (ConstantInt 7 ())] Load) Add (Name a Load)) ())] [] () ())] []) +(Module [(FunctionDef test_List ([] [] [] [] [] [] []) [(AnnAssign (Name a Store) (Subscript (Name list Load) (Name i32 Load) Load) () 1) (Assign [(Name a Store)] (List [(ConstantInt 1 ()) (ConstantInt 2 ()) (ConstantInt 3 ())] Load) ()) (Assign [(Name a Store)] (List [(UnaryOp USub (ConstantInt 3 ())) (UnaryOp USub (ConstantInt 2 ())) (UnaryOp USub (ConstantInt 1 ()))] Load) ()) (AnnAssign (Name b Store) (Subscript (Name list Load) (Name str Load) Load) () 1) (Assign [(Name b Store)] (List [(ConstantStr "a" ()) (ConstantStr "b" ()) (ConstantStr "c" ())] Load) ()) (AnnAssign (Name c Store) (Subscript (Name list Load) (Subscript (Name list Load) (Name i32 Load) Load) Load) () 1) (Assign [(Name c Store)] (List [(List [(ConstantInt 1 ()) (ConstantInt 2 ()) (ConstantInt 3 ())] Load) (List [(ConstantInt 4 ()) (ConstantInt 5 ()) (ConstantInt 6 ())] Load)] Load) ()) (AnnAssign (Name d Store) (Name i32 Load) () 1) (Assign [(Name d Store)] (Subscript (Name a Load) (ConstantInt 2 ()) Load) ()) (AnnAssign (Name e Store) (Subscript (Name list Load) (Subscript (Name list Load) (Name str Load) Load) Load) () 1) (Assign [(Name e Store)] (List [(List [(ConstantStr "a" ()) (ConstantStr "b" ()) (ConstantStr "c" ())] Load) (List [(ConstantStr "d" ()) (ConstantStr "e" ())] Load)] Load) ()) (Expr (Call (Attribute (Name a Load) append Load) [(ConstantInt 10 ())] [])) (Expr (Call (Attribute (Name a Load) remove Load) [(ConstantInt 1 ())] [])) (Expr (Call (Attribute (Name a Load) insert Load) [(ConstantInt 2 ()) (ConstantInt 13 ())] [])) (Assign [(Name a Store)] (Subscript (Name a Load) (Slice (ConstantInt 0 ()) (ConstantInt 2 ()) ()) Load) ()) (Assign [(Name d Store)] (Call (Attribute (Name a Load) pop Load) [] []) ()) (Assign [(Name d Store)] (Call (Attribute (Name a Load) pop Load) [(ConstantInt 2 ())] []) ()) (AugAssign (Name a Store) Add (List [(ConstantInt 4 ()) (ConstantInt 5 ())] Load)) (Assign [(Name a Store)] (BinOp (List [(ConstantInt 6 ()) (ConstantInt 7 ())] Load) Add (Name a Load)) ()) (AnnAssign (Name a11 Store) (Subscript (Name list Load) (Name i32 Load) Load) () 1) (AnnAssign (Name b11 Store) (Subscript (Name list Load) (Name i32 Load) Load) () 1) (Assign [(Name a11 Store)] (List [(ConstantInt 1 ()) (ConstantInt 2 ())] Load) ()) (Assign [(Name b11 Store)] (List [(ConstantInt 3 ()) (ConstantInt 4 ())] Load) ()) (Assert (Compare (Name a11 Load) Eq [(Name b11 Load)]) ())] [] () ())] []) diff --git a/tests/reference/ast-tuple1-2fb5396.json b/tests/reference/ast-tuple1-2fb5396.json index 46d346ce87..8e2207c1ee 100644 --- a/tests/reference/ast-tuple1-2fb5396.json +++ b/tests/reference/ast-tuple1-2fb5396.json @@ -2,11 +2,11 @@ "basename": "ast-tuple1-2fb5396", "cmd": "lpython --show-ast --no-color {infile} -o {outfile}", "infile": "tests/tuple1.py", - "infile_hash": "f02acdb1d699677006d588559df9554308f77a2d171bfec71ed41c41", + "infile_hash": "aed9320f34b5eec1d9ce30d9ef28abeaf9c1faaf421d87b34148ae04", "outfile": null, "outfile_hash": null, "stdout": "ast-tuple1-2fb5396.stdout", - "stdout_hash": "a1311140dfac80fb2cf1467efa724948b4b58e164cad56440f8d2f2e", + "stdout_hash": "bc73bf5b72859d4177c36b3d062b7a12489017a09541be328d9ad727", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/ast-tuple1-2fb5396.stdout b/tests/reference/ast-tuple1-2fb5396.stdout index 956415ca2b..190e743047 100644 --- a/tests/reference/ast-tuple1-2fb5396.stdout +++ b/tests/reference/ast-tuple1-2fb5396.stdout @@ -1 +1 @@ -(Module [(ImportFrom ltypes [(i32 ()) (f32 ())] 0) (FunctionDef test_Tuple ([] [] [] [] [] [] []) [(AnnAssign (Name a1 Store) (Subscript (Name tuple Load) (Tuple [(Name i32 Load) (Name i32 Load) (Name i32 Load)] Load) Load) () 1) (Assign [(Name a1 Store)] (Tuple [(ConstantInt 1 ()) (ConstantInt 2 ()) (ConstantInt 3 ())] Load) ()) (Assign [(Name a1 Store)] (Tuple [(UnaryOp USub (ConstantInt 3 ())) (UnaryOp USub (ConstantInt 2 ())) (UnaryOp USub (ConstantInt 1 ()))] Load) ()) (AnnAssign (Name a2 Store) (Subscript (Name tuple Load) (Tuple [(Name str Load) (Name str Load) (Name str Load)] Load) Load) () 1) (Assign [(Name a2 Store)] (Tuple [(ConstantStr "a" ()) (ConstantStr "b" ()) (ConstantStr "c" ())] Load) ()) (AnnAssign (Name a3 Store) (Subscript (Name tuple Load) (Tuple [(Name i32 Load) (Name i32 Load) (Name f32 Load) (Name str Load)] Load) Load) () 1) (AnnAssign (Name float_mem Store) (Name f32 Load) () 1) (Assign [(Name float_mem Store)] (Call (Name f32 Load) [(ConstantFloat 0.450000 ())] []) ()) (Assign [(Name a3 Store)] (Tuple [(UnaryOp USub (ConstantInt 2 ())) (UnaryOp USub (ConstantInt 1 ())) (Name float_mem Load) (ConstantStr "d" ())] Load) ()) (AnnAssign (Name a4 Store) (Subscript (Name tuple Load) (Tuple [(Subscript (Name tuple Load) (Tuple [(Name i32 Load) (Name i32 Load) (Name i32 Load)] Load) Load) (Subscript (Name tuple Load) (Tuple [(Name i32 Load) (Name i32 Load) (Name i32 Load)] Load) Load)] Load) Load) () 1) (Assign [(Name a4 Store)] (Tuple [(Tuple [(ConstantInt 1 ()) (ConstantInt 2 ()) (ConstantInt 3 ())] Load) (Tuple [(ConstantInt 4 ()) (ConstantInt 5 ()) (ConstantInt 6 ())] Load)] Load) ()) (AnnAssign (Name a5 Store) (Subscript (Name tuple Load) (Tuple [(Subscript (Name tuple Load) (Tuple [(Name str Load) (Name str Load) (Name f32 Load)] Load) Load) (Subscript (Name tuple Load) (Tuple [(Name str Load) (Name i32 Load) (Name f32 Load)] Load) Load)] Load) Load) () 1) (AnnAssign (Name float_mem1 Store) (Name f32 Load) () 1) (AnnAssign (Name float_mem2 Store) (Name f32 Load) () 1) (Assign [(Name float_mem1 Store)] (Call (Name f32 Load) [(ConstantFloat 3.400000 ())] []) ()) (Assign [(Name float_mem2 Store)] (Call (Name f32 Load) [(ConstantFloat 5.600000 ())] []) ()) (Assign [(Name a5 Store)] (Tuple [(Tuple [(ConstantStr "a" ()) (ConstantStr "b" ()) (Name float_mem1 Load)] Load) (Tuple [(ConstantStr "c" ()) (ConstantInt 3 ()) (Name float_mem2 Load)] Load)] Load) ()) (AnnAssign (Name b0 Store) (Name i32 Load) () 1) (AnnAssign (Name b1 Store) (Name i32 Load) () 1) (Assign [(Name b0 Store)] (Subscript (Name a1 Load) (ConstantInt 0 ()) Load) ()) (Assign [(Tuple [(Name b0 Store) (Name b1 Store)] Store)] (Tuple [(Subscript (Name a1 Load) (ConstantInt 2 ()) Load) (Subscript (Name a1 Load) (ConstantInt 1 ()) Load)] Load) ())] [] () ())] []) +(Module [(ImportFrom ltypes [(i32 ()) (f32 ())] 0) (FunctionDef test_Tuple ([] [] [] [] [] [] []) [(AnnAssign (Name a1 Store) (Subscript (Name tuple Load) (Tuple [(Name i32 Load) (Name i32 Load) (Name i32 Load)] Load) Load) () 1) (Assign [(Name a1 Store)] (Tuple [(ConstantInt 1 ()) (ConstantInt 2 ()) (ConstantInt 3 ())] Load) ()) (Assign [(Name a1 Store)] (Tuple [(UnaryOp USub (ConstantInt 3 ())) (UnaryOp USub (ConstantInt 2 ())) (UnaryOp USub (ConstantInt 1 ()))] Load) ()) (AnnAssign (Name a2 Store) (Subscript (Name tuple Load) (Tuple [(Name str Load) (Name str Load) (Name str Load)] Load) Load) () 1) (Assign [(Name a2 Store)] (Tuple [(ConstantStr "a" ()) (ConstantStr "b" ()) (ConstantStr "c" ())] Load) ()) (AnnAssign (Name a3 Store) (Subscript (Name tuple Load) (Tuple [(Name i32 Load) (Name i32 Load) (Name f32 Load) (Name str Load)] Load) Load) () 1) (AnnAssign (Name float_mem Store) (Name f32 Load) () 1) (Assign [(Name float_mem Store)] (Call (Name f32 Load) [(ConstantFloat 0.450000 ())] []) ()) (Assign [(Name a3 Store)] (Tuple [(UnaryOp USub (ConstantInt 2 ())) (UnaryOp USub (ConstantInt 1 ())) (Name float_mem Load) (ConstantStr "d" ())] Load) ()) (AnnAssign (Name a4 Store) (Subscript (Name tuple Load) (Tuple [(Subscript (Name tuple Load) (Tuple [(Name i32 Load) (Name i32 Load) (Name i32 Load)] Load) Load) (Subscript (Name tuple Load) (Tuple [(Name i32 Load) (Name i32 Load) (Name i32 Load)] Load) Load)] Load) Load) () 1) (Assign [(Name a4 Store)] (Tuple [(Tuple [(ConstantInt 1 ()) (ConstantInt 2 ()) (ConstantInt 3 ())] Load) (Tuple [(ConstantInt 4 ()) (ConstantInt 5 ()) (ConstantInt 6 ())] Load)] Load) ()) (AnnAssign (Name a5 Store) (Subscript (Name tuple Load) (Tuple [(Subscript (Name tuple Load) (Tuple [(Name str Load) (Name str Load) (Name f32 Load)] Load) Load) (Subscript (Name tuple Load) (Tuple [(Name str Load) (Name i32 Load) (Name f32 Load)] Load) Load)] Load) Load) () 1) (AnnAssign (Name float_mem1 Store) (Name f32 Load) () 1) (AnnAssign (Name float_mem2 Store) (Name f32 Load) () 1) (Assign [(Name float_mem1 Store)] (Call (Name f32 Load) [(ConstantFloat 3.400000 ())] []) ()) (Assign [(Name float_mem2 Store)] (Call (Name f32 Load) [(ConstantFloat 5.600000 ())] []) ()) (Assign [(Name a5 Store)] (Tuple [(Tuple [(ConstantStr "a" ()) (ConstantStr "b" ()) (Name float_mem1 Load)] Load) (Tuple [(ConstantStr "c" ()) (ConstantInt 3 ()) (Name float_mem2 Load)] Load)] Load) ()) (AnnAssign (Name b0 Store) (Name i32 Load) () 1) (AnnAssign (Name b1 Store) (Name i32 Load) () 1) (Assign [(Name b0 Store)] (Subscript (Name a1 Load) (ConstantInt 0 ()) Load) ()) (Assign [(Tuple [(Name b0 Store) (Name b1 Store)] Store)] (Tuple [(Subscript (Name a1 Load) (ConstantInt 2 ()) Load) (Subscript (Name a1 Load) (ConstantInt 1 ()) Load)] Load) ()) (AnnAssign (Name a11 Store) (Subscript (Name tuple Load) (Tuple [(Name i32 Load) (Name i32 Load)] Load) Load) () 1) (AnnAssign (Name b11 Store) (Subscript (Name tuple Load) (Tuple [(Name i32 Load) (Name i32 Load)] Load) Load) () 1) (Assign [(Name a11 Store)] (Tuple [(ConstantInt 1 ()) (ConstantInt 2 ())] Load) ()) (Assign [(Name b11 Store)] (Tuple [(ConstantInt 1 ()) (ConstantInt 2 ())] Load) ()) (Assert (Compare (Name a11 Load) Eq [(Name b11 Load)]) ())] [] () ())] []) diff --git a/tests/tuple1.py b/tests/tuple1.py index 0a5aa4a89b..dd43c364de 100644 --- a/tests/tuple1.py +++ b/tests/tuple1.py @@ -27,3 +27,9 @@ def test_Tuple(): b1: i32 b0 = a1[0] b0, b1 = a1[2], a1[1] + + a11: tuple[i32, i32] + b11: tuple[i32, i32] + a11 = (1, 2) + b11 = (1, 2) + assert a11 == b11