diff --git a/integration_tests/CMakeLists.txt b/integration_tests/CMakeLists.txt index 4ab3da0707..824edc5034 100644 --- a/integration_tests/CMakeLists.txt +++ b/integration_tests/CMakeLists.txt @@ -467,6 +467,8 @@ RUN(NAME test_dict_08 LABELS cpython llvm c) RUN(NAME test_dict_09 LABELS cpython llvm c) RUN(NAME test_dict_10 LABELS cpython llvm c) RUN(NAME test_dict_11 LABELS cpython llvm c) +RUN(NAME test_dict_12 LABELS cpython llvm c) +RUN(NAME test_dict_13 LABELS cpython llvm c) RUN(NAME test_dict_bool LABELS cpython llvm) RUN(NAME test_dict_increment LABELS cpython llvm) RUN(NAME test_for_loop LABELS cpython llvm c) diff --git a/integration_tests/test_dict_12.py b/integration_tests/test_dict_12.py new file mode 100644 index 0000000000..e56ac43f32 --- /dev/null +++ b/integration_tests/test_dict_12.py @@ -0,0 +1,36 @@ +from lpython import i32 + +def main(): + d: dict[str, i32] = { + '2': 2, '3': 3, + '4': 4, '5': 5, '6': 6, '7': 7, + '8': 8, '9': 9, + 'a': 10, 'b': 11, 'c': 12, 'd': 13, + 'A': 100, 'B': 110, 'C': 120, 'D': 130, + 'e': 14, 'f': 15, + 'E': 140, 'F': 150} + + assert (d['2'] == 2) + assert (d['3'] == 3) + assert (d['4'] == 4) + assert (d['5'] == 5) + assert (d['6'] == 6) + assert (d['7'] == 7) + assert (d['8'] == 8) + assert (d['9'] == 9) + + assert (d['a'] == 10) + assert (d['b'] == 11) + assert (d['c'] == 12) + assert (d['d'] == 13) + assert (d['A'] == 100) + assert (d['B'] == 110) + assert (d['C'] == 120) + assert (d['D'] == 130) + + assert (d['e'] == 14) + assert (d['f'] == 15) + assert (d['E'] == 140) + assert (d['F'] == 150) + +main() diff --git a/integration_tests/test_dict_13.py b/integration_tests/test_dict_13.py new file mode 100644 index 0000000000..670a9eb60c --- /dev/null +++ b/integration_tests/test_dict_13.py @@ -0,0 +1,43 @@ +from lpython import i32 + +I4C: dict[str, i32] = { + '0': 0, '1': 1, '2': 2, '3': 3, + '4': 4, '5': 5, '6': 6, '7': 7, + '8': 8, '9': 9, + 'a': 10, 'b': 11, 'c': 12, 'd': 13, + 'A': 10, 'B': 11, 'C': 12, 'D': 13, + 'e': 14, 'f': 15, + 'E': 14, 'F': 15} + + +def cnvi(s : str, base : i32=10) -> i32: + """Assume input has been through 'match_integer'.""" + assert base == 10 or base == 8 or base == 16 or base == 2 + result : i32 = 0 + c : str + pow_: i32 = base ** (len(s) - 1) + for c in s: + incr : i32 = pow_ * I4C[c] + result += incr + pow_ = (pow_ // base) + return result + + +if __name__ == '__main__': + print(cnvi('0b0', base=2)) + assert cnvi('0b0', base=2) == 22 + + print(cnvi('0b1', base=2)) + assert cnvi('0b1', base=2) == 23 + + print(cnvi('0b10', base=2)) + assert cnvi('0b10', base=2) == 46 + + print(cnvi('0b11', base=2)) + assert cnvi('0b11', base=2) == 47 + + print(cnvi('0b11110100111', base=2)) + assert cnvi('0b11110100111', base=2) == 24487 + + print(cnvi('0b7a7', base=16)) + assert cnvi('0b7a7', base=16) == 47015 diff --git a/src/libasr/codegen/asr_to_llvm.cpp b/src/libasr/codegen/asr_to_llvm.cpp index 7de6a1fa3a..984a55702d 100644 --- a/src/libasr/codegen/asr_to_llvm.cpp +++ b/src/libasr/codegen/asr_to_llvm.cpp @@ -1589,15 +1589,15 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor std::string key_type_code = ASRUtils::get_type_code(x_dict->m_key_type); std::string value_type_code = ASRUtils::get_type_code(x_dict->m_value_type); llvm_utils->dict_api->dict_init(key_type_code, value_type_code, const_dict, module.get(), x.n_keys); - int64_t ptr_loads_key = LLVM::is_llvm_struct(x_dict->m_key_type) ? 0 : 2; - int64_t ptr_loads_value = LLVM::is_llvm_struct(x_dict->m_value_type) ? 0 : 2; + int64_t ptr_loads_key = !LLVM::is_llvm_struct(x_dict->m_key_type); + int64_t ptr_loads_value = !LLVM::is_llvm_struct(x_dict->m_value_type); int64_t ptr_loads_copy = ptr_loads; for( size_t i = 0; i < x.n_keys; i++ ) { ptr_loads = ptr_loads_key; - visit_expr(*x.m_keys[i]); + visit_expr_wrapper(x.m_keys[i], true); llvm::Value* key = tmp; ptr_loads = ptr_loads_value; - visit_expr(*x.m_values[i]); + visit_expr_wrapper(x.m_values[i], true); llvm::Value* value = tmp; llvm_utils->dict_api->write_item(const_dict, key, value, module.get(), x_dict->m_key_type, x_dict->m_value_type, name2memidx); @@ -5138,7 +5138,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor if( x == nullptr ) { throw CodeGenError("Internal error: x is nullptr"); } - + this->visit_expr(*x); if( x->type == ASR::exprType::ArrayItem || x->type == ASR::exprType::ArraySection || diff --git a/src/libasr/codegen/llvm_utils.cpp b/src/libasr/codegen/llvm_utils.cpp index 9fc14b4251..079688af8c 100644 --- a/src/libasr/codegen/llvm_utils.cpp +++ b/src/libasr/codegen/llvm_utils.cpp @@ -783,12 +783,11 @@ namespace LCompilers { void LLVMDictSeparateChaining::deepcopy_key_value_pair_linked_list( llvm::Value* srci, llvm::Value* desti, llvm::Value* dest_key_value_pairs, - llvm::Value* src_capacity, ASR::Dict_t* dict_type, llvm::Module* module, + ASR::Dict_t* dict_type, llvm::Module* module, std::map>& name2memidx) { if( !are_iterators_set ) { src_itr = builder->CreateAlloca(llvm::Type::getInt8PtrTy(context), nullptr); dest_itr = builder->CreateAlloca(llvm::Type::getInt8PtrTy(context), nullptr); - next_ptr = builder->CreateAlloca(llvm::Type::getInt32Ty(context), nullptr); } llvm::Type* key_value_pair_type = get_key_value_pair_type(dict_type->m_key_type, dict_type->m_value_type)->getPointerTo(); LLVM::CreateStore(*builder, @@ -797,7 +796,6 @@ namespace LCompilers { LLVM::CreateStore(*builder, builder->CreateBitCast(desti, llvm::Type::getInt8PtrTy(context)), dest_itr); - LLVM::CreateStore(*builder, src_capacity, next_ptr); llvm::BasicBlock *loophead = llvm::BasicBlock::Create(context, "loop.head"); llvm::BasicBlock *loopbody = llvm::BasicBlock::Create(context, "loop.body"); llvm::BasicBlock *loopend = llvm::BasicBlock::Create(context, "loop.end"); @@ -958,9 +956,11 @@ namespace LCompilers { get_key_value_pair_type(dict_type->m_key_type, dict_type->m_value_type)->getPointerTo()); if( !are_iterators_set ) { copy_itr = builder->CreateAlloca(llvm::Type::getInt32Ty(context), nullptr); + next_ptr = builder->CreateAlloca(llvm::Type::getInt32Ty(context), nullptr); } llvm::Value* llvm_zero = llvm::ConstantInt::get(llvm::Type::getInt32Ty(context), llvm::APInt(32, 0)); LLVM::CreateStore(*builder, llvm_zero, copy_itr); + LLVM::CreateStore(*builder, src_capacity, next_ptr); llvm::Value* src_key_value_pairs = LLVM::CreateLoad(*builder, get_pointer_to_key_value_pairs(src)); llvm::BasicBlock *loophead = llvm::BasicBlock::Create(context, "loop.head"); @@ -991,7 +991,7 @@ namespace LCompilers { llvm::Value* srci = llvm_utils->create_ptr_gep(src_key_value_pairs, itr); llvm::Value* desti = llvm_utils->create_ptr_gep(dest_key_value_pairs, itr); deepcopy_key_value_pair_linked_list(srci, desti, dest_key_value_pairs, - src_capacity, dict_type, module, name2memidx); + dict_type, module, name2memidx); }, [=]() { }); llvm::Value* tmp = builder->CreateAdd( @@ -3102,7 +3102,7 @@ namespace LCompilers { context, llvm::APInt(32, 0)), i); // i = 0 llvm::AllocaInst *j = builder->CreateAlloca(pos_type, nullptr); llvm::Value* tmp = nullptr; - + llvm::BasicBlock *loophead = llvm::BasicBlock::Create(context, "loop.head"); llvm::BasicBlock *loopbody = llvm::BasicBlock::Create(context, "loop.body"); llvm::BasicBlock *loopend = llvm::BasicBlock::Create(context, "loop.end"); diff --git a/src/libasr/codegen/llvm_utils.h b/src/libasr/codegen/llvm_utils.h index 65f6460aba..3846c1b907 100644 --- a/src/libasr/codegen/llvm_utils.h +++ b/src/libasr/codegen/llvm_utils.h @@ -283,7 +283,7 @@ namespace LCompilers { llvm::Value* check_list_equality(llvm::Value* l1, llvm::Value* l2, ASR::ttype_t *item_type, llvm::LLVMContext& context, llvm::IRBuilder<>* builder, llvm::Module& module); - + void list_repeat_copy(llvm::Value* repeat_list, llvm::Value* init_list, llvm::Value* num_times, llvm::Value* init_list_len, llvm::Module* module); @@ -605,7 +605,7 @@ namespace LCompilers { llvm::Value* get_pointer_to_rehash_flag(llvm::Value* dict); void deepcopy_key_value_pair_linked_list(llvm::Value* srci, llvm::Value* desti, - llvm::Value* dest_key_value_pairs, llvm::Value* src_capacity, ASR::Dict_t* dict_type, + llvm::Value* dest_key_value_pairs, ASR::Dict_t* dict_type, llvm::Module* module, std::map>& name2memidx); void write_key_value_pair_linked_list(llvm::Value* kv_ll, llvm::Value* dict,