Skip to content

Commit

Permalink
feat: add min/max methods to List and Tuple objects
Browse files Browse the repository at this point in the history
  • Loading branch information
jacopodl committed Jan 25, 2024
1 parent c46bf8b commit 5fc88e7
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 0 deletions.
40 changes: 40 additions & 0 deletions argon/vm/datatype/list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

#include <argon/vm/runtime.h>

#include <argon/vm/datatype/support/common.h>

#include <argon/vm/datatype/boolean.h>
#include <argon/vm/datatype/bounds.h>
#include <argon/vm/datatype/option.h>
Expand Down Expand Up @@ -114,6 +116,42 @@ ARGON_METHOD(list_insert, insert,
return ok ? (ArObject *) IncRef(self) : nullptr;
}

ARGON_METHOD(list_max, max,
"Returns the item with the highest value.\n"
"\n"
"- Returns: Highest value.\n"
"\n"
"# SEE\n"
"- min\n",
nullptr, false, false) {
auto *self = (List *) _self;
ArObject *max = nullptr;

std::shared_lock _(self->rwlock);

support::MaxMin(self->objects, &max, self->length, false);

return max;
}

ARGON_METHOD(list_min, min,
"Returns the item with the lowest value.\n"
"\n"
"- Returns: Lowest value.\n"
"\n"
"# SEE\n"
"- max\n",
nullptr, false, false) {
auto *self = (List *) _self;
ArObject *min = nullptr;

std::shared_lock _(self->rwlock);

support::MaxMin(self->objects, &min, self->length, true);

return min;
}

ARGON_METHOD(list_pop, pop,
"Remove and returns the item at the end of the list.\n"
"\n"
Expand Down Expand Up @@ -193,6 +231,8 @@ const FunctionDef list_methods[] = {
list_extend,
list_find,
list_insert,
list_max,
list_min,
list_pop,
list_remove,
list_reverse,
Expand Down
27 changes: 27 additions & 0 deletions argon/vm/datatype/support/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#define ARGON_VM_DATATYPE_SUPPORT_COMMON_H_

#include <argon/vm/datatype/arobject.h>
#include <argon/vm/datatype/boolean.h>
#include <argon/vm/datatype/list.h>

#include <argon/vm/datatype/support/byteops.h>
Expand Down Expand Up @@ -134,6 +135,32 @@ namespace argon::vm::datatype::support {

return (ArObject *) ret;
}

inline bool MaxMin(ArObject **list, ArObject **out, ArSize length, bool min) {
auto mode = min ? CompareMode::LE : CompareMode::GR;
*out = nullptr;

if (length == 0) {
ErrorFormat(kValueError[0], "%s on empty sequence", min ? "min" : "max");

return false;
}

ArObject *ret = *list;

for (ArSize i = 1; i < length; i++) {
auto *res = Compare(ret, list[i], mode);
if (res == nullptr)
return false;

if (res == (ArObject *) False)
ret = list[i];
}

*out = IncRef(ret);

return true;
}
}

#endif // !ARGON_VM_DATATYPE_SUPPORT_COMMON_H_
36 changes: 36 additions & 0 deletions argon/vm/datatype/tuple.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

#include <argon/vm/runtime.h>

#include <argon/vm/datatype/support/common.h>

#include <argon/vm/datatype/boolean.h>
#include <argon/vm/datatype/bounds.h>
#include <argon/vm/datatype/decimal.h>
Expand Down Expand Up @@ -47,10 +49,44 @@ ARGON_METHOD(tuple_find, find,
return (ArObject *) IntNew(-1);
}

ARGON_METHOD(tuple_max, max,
"Returns the item with the highest value.\n"
"\n"
"- Returns: Highest value.\n"
"\n"
"# SEE\n"
"- min\n",
nullptr, false, false) {
auto *self = (Tuple *) _self;
ArObject *max = nullptr;

support::MaxMin(self->objects, &max, self->length, false);

return max;
}

ARGON_METHOD(tuple_min, min,
"Returns the item with the lowest value.\n"
"\n"
"- Returns: Lowest value.\n"
"\n"
"# SEE\n"
"- max\n",
nullptr, false, false) {
auto *self = (Tuple *) _self;
ArObject *min = nullptr;

support::MaxMin(self->objects, &min, self->length, true);

return min;
}

const FunctionDef tuple_methods[] = {
tuple_tuple,

tuple_find,
tuple_max,
tuple_min,
ARGON_METHOD_SENTINEL
};

Expand Down

0 comments on commit 5fc88e7

Please sign in to comment.