Skip to content

Commit

Permalink
list.reserve to reserve
Browse files Browse the repository at this point in the history
  • Loading branch information
kabra1110 committed Aug 1, 2023
1 parent a649c9a commit 02d37a7
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 43 deletions.
10 changes: 5 additions & 5 deletions integration_tests/test_list_reserve.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
from lpython import i32, f64
from lpython import i32, f64, reserve

def test_list_reserve():
l1: list[i32] = []
l2: list[list[tuple[f64, str, tuple[i32, f64]]]] = []
i: i32

l1.reserve(100)
reserve(l1, 100)
for i in range(50):
l1.append(i)
assert len(l1) == i + 1

l1.reserve(150)
reserve(l1, 150)

for i in range(50):
l1.pop(0)
assert len(l1) == 49 - i

l2.reserve(100)
reserve(l2, 100)
for i in range(50):
l2.append([(f64(i * i), str(i), (i, f64(i + 1))), (f64(i), str(i), (i, f64(i)))])
assert len(l2) == i + 1

l2.reserve(150)
reserve(l2, 150)

for i in range(50):
l2.pop(0)
Expand Down
7 changes: 4 additions & 3 deletions src/libasr/codegen/asr_to_llvm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1680,7 +1680,8 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
tmp = list_api->pop_position(plist, pos, asr_el_type, module.get(), name2memidx);
}

void generate_ListReserve(ASR::expr_t* m_arg, ASR::expr_t* m_ele) {
void generate_Reserve(ASR::expr_t* m_arg, ASR::expr_t* m_ele) {
// For now, this only handles lists
ASR::ttype_t* asr_el_type = ASRUtils::get_contained_type(ASRUtils::expr_type(m_arg));
int64_t ptr_loads_copy = ptr_loads;
ptr_loads = 0;
Expand Down Expand Up @@ -1808,8 +1809,8 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
}
break;
}
case ASRUtils::IntrinsicFunctions::ListReserve: {
generate_ListReserve(x.m_args[0], x.m_args[1]);
case ASRUtils::IntrinsicFunctions::Reserve: {
generate_Reserve(x.m_args[0], x.m_args[1]);
break;
}
case ASRUtils::IntrinsicFunctions::DictKeys: {
Expand Down
41 changes: 22 additions & 19 deletions src/libasr/pass/intrinsic_function_registry.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ enum class IntrinsicFunctions : int64_t {
Partition,
ListReverse,
ListPop,
ListReserve,
Reserve,
DictKeys,
DictValues,
SetAdd,
Expand Down Expand Up @@ -103,7 +103,7 @@ inline std::string get_intrinsic_name(int x) {
INTRINSIC_NAME_CASE(Partition)
INTRINSIC_NAME_CASE(ListReverse)
INTRINSIC_NAME_CASE(ListPop)
INTRINSIC_NAME_CASE(ListReserve)
INTRINSIC_NAME_CASE(Reserve)
INTRINSIC_NAME_CASE(DictKeys)
INTRINSIC_NAME_CASE(DictValues)
INTRINSIC_NAME_CASE(SetAdd)
Expand Down Expand Up @@ -1264,51 +1264,54 @@ static inline ASR::asr_t* create_ListPop(Allocator& al, const Location& loc,

} // namespace ListPop

namespace ListReserve {
namespace Reserve {

static inline void verify_args(const ASR::IntrinsicFunction_t& x, diag::Diagnostics& diagnostics) {
ASRUtils::require_impl(x.n_args == 2, "Call to list.reserve must have exactly one argument",
ASRUtils::require_impl(x.n_args == 2, "Call to reserve must have exactly one argument",
x.base.base.loc, diagnostics);
ASRUtils::require_impl(ASR::is_a<ASR::List_t>(*ASRUtils::expr_type(x.m_args[0])),
"Argument to list.reserve must be of list type",
"First argument to reserve must be of list type",
x.base.base.loc, diagnostics);
ASRUtils::require_impl(ASR::is_a<ASR::Integer_t>(*ASRUtils::expr_type(x.m_args[1])),
"Argument to list.reserve must be an integer",
"Second argument to reserve must be an integer",
x.base.base.loc, diagnostics);
ASRUtils::require_impl(x.m_type == nullptr,
"Return type of list.reserve must be empty",
"Return type of reserve must be empty",
x.base.base.loc, diagnostics);
}

static inline ASR::expr_t *eval_list_reserve(Allocator &/*al*/,
static inline ASR::expr_t *eval_reserve(Allocator &/*al*/,
const Location &/*loc*/, Vec<ASR::expr_t*>& /*args*/) {
// TODO: To be implemented for ListConstant expression
return nullptr;
}

static inline ASR::asr_t* create_ListReserve(Allocator& al, const Location& loc,
static inline ASR::asr_t* create_Reserve(Allocator& al, const Location& loc,
Vec<ASR::expr_t*>& args,
const std::function<void (const std::string &, const Location &)> err) {
if (args.size() != 2) {
err("Call to list.reserve must have exactly one argument", loc);
err("Call to reserve must have exactly two argument", loc);
}
if (!ASR::is_a<ASR::List_t>(*ASRUtils::expr_type(args[0]))) {
err("First argument to reserve must be of list type", loc);
}
if (!ASR::is_a<ASR::Integer_t>(*ASRUtils::expr_type(args[1]))) {
err("Argument to list.reserve must be an integer", loc);
err("Second argument to reserve must be an integer", loc);
}

Vec<ASR::expr_t*> arg_values;
arg_values.reserve(al, args.size());
for( size_t i = 0; i < args.size(); i++ ) {
arg_values.push_back(al, ASRUtils::expr_value(args[i]));
}
ASR::expr_t* compile_time_value = eval_list_reserve(al, loc, arg_values);
ASR::expr_t* compile_time_value = eval_reserve(al, loc, arg_values);
return ASR::make_Expr_t(al, loc,
ASRUtils::EXPR(ASRUtils::make_IntrinsicFunction_t_util(al, loc,
static_cast<int64_t>(ASRUtils::IntrinsicFunctions::ListReserve),
static_cast<int64_t>(ASRUtils::IntrinsicFunctions::Reserve),
args.p, args.size(), 0, nullptr, compile_time_value)));
}

} // namespace ListReserve
} // namespace Reserve

namespace DictKeys {

Expand Down Expand Up @@ -3172,8 +3175,8 @@ namespace IntrinsicFunctionRegistry {
{nullptr, &DictValues::verify_args}},
{static_cast<int64_t>(ASRUtils::IntrinsicFunctions::ListPop),
{nullptr, &ListPop::verify_args}},
{static_cast<int64_t>(ASRUtils::IntrinsicFunctions::ListReserve),
{nullptr, &ListReserve::verify_args}},
{static_cast<int64_t>(ASRUtils::IntrinsicFunctions::Reserve),
{nullptr, &Reserve::verify_args}},
{static_cast<int64_t>(ASRUtils::IntrinsicFunctions::SetAdd),
{nullptr, &SetAdd::verify_args}},
{static_cast<int64_t>(ASRUtils::IntrinsicFunctions::SetRemove),
Expand Down Expand Up @@ -3256,8 +3259,8 @@ namespace IntrinsicFunctionRegistry {
"list.reverse"},
{static_cast<int64_t>(ASRUtils::IntrinsicFunctions::ListPop),
"list.pop"},
{static_cast<int64_t>(ASRUtils::IntrinsicFunctions::ListReserve),
"list.reserve"},
{static_cast<int64_t>(ASRUtils::IntrinsicFunctions::Reserve),
"reserve"},
{static_cast<int64_t>(ASRUtils::IntrinsicFunctions::DictKeys),
"dict.keys"},
{static_cast<int64_t>(ASRUtils::IntrinsicFunctions::DictValues),
Expand Down Expand Up @@ -3342,7 +3345,7 @@ namespace IntrinsicFunctionRegistry {
{"list.index", {&ListIndex::create_ListIndex, &ListIndex::eval_list_index}},
{"list.reverse", {&ListReverse::create_ListReverse, &ListReverse::eval_list_reverse}},
{"list.pop", {&ListPop::create_ListPop, &ListPop::eval_list_pop}},
{"list.reserve", {&ListReserve::create_ListReserve, &ListReserve::eval_list_reserve}},
{"reserve", {&Reserve::create_Reserve, &Reserve::eval_reserve}},
{"dict.keys", {&DictKeys::create_DictKeys, &DictKeys::eval_dict_keys}},
{"dict.values", {&DictValues::create_DictValues, &DictValues::eval_dict_values}},
{"set.add", {&SetAdd::create_SetAdd, &SetAdd::eval_set_add}},
Expand Down
17 changes: 1 addition & 16 deletions src/lpython/semantics/python_attribute_eval.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ struct AttributeHandler {
{"list@pop", &eval_list_pop},
{"list@clear", &eval_list_clear},
{"list@insert", &eval_list_insert},
{"list@reserve", &eval_list_reserve},
{"set@pop", &eval_set_pop},
{"set@add", &eval_set_add},
{"set@remove", &eval_set_remove},
Expand All @@ -42,7 +41,7 @@ struct AttributeHandler {

modify_attr_set = {"list@append", "list@remove",
"list@reverse", "list@clear", "list@insert", "list@pop",
"list@reserve", "set@pop", "set@add", "set@remove",
"set@pop", "set@add", "set@remove",
"dict@pop"};

symbolic_attribute_map = {
Expand Down Expand Up @@ -286,20 +285,6 @@ struct AttributeHandler {
return make_ListClear_t(al, loc, s);
}

static ASR::asr_t* eval_list_reserve(ASR::expr_t *s, Allocator &al, const Location &loc,
Vec<ASR::expr_t*> &args, diag::Diagnostics &/*diag*/) {
Vec<ASR::expr_t*> args_with_list;
args_with_list.reserve(al, args.size() + 1);
args_with_list.push_back(al, s);
for(size_t i = 0; i < args.size(); i++) {
args_with_list.push_back(al, args[i]);
}
ASRUtils::create_intrinsic_function create_function =
ASRUtils::IntrinsicFunctionRegistry::get_create_function("list.reserve");
return create_function(al, loc, args_with_list, [&](const std::string &msg, const Location &loc)
{ throw SemanticError(msg, loc); });
}

static ASR::asr_t* eval_set_pop(ASR::expr_t *s, Allocator &al, const Location &loc,
Vec<ASR::expr_t*> &args, diag::Diagnostics &/*diag*/) {
if (args.size() != 0) {
Expand Down
5 changes: 5 additions & 0 deletions src/runtime/lpython/lpython.py
Original file line number Diff line number Diff line change
Expand Up @@ -760,6 +760,11 @@ def __lpython(*args, **kwargs):
def bitnot(x, bitsize):
return (~x) % (2 ** bitsize)

def reserve(data_structure, n):
if isinstance(data_structure, list):
data_structure = [None] * n
# no-op

bitnot_u8 = lambda x: bitnot(x, 8)
bitnot_u16 = lambda x: bitnot(x, 16)
bitnot_u32 = lambda x: bitnot(x, 32)
Expand Down

0 comments on commit 02d37a7

Please sign in to comment.