Commit 08977a8d authored by Marius Wachtler's avatar Marius Wachtler

Imlement mechanism to iterator over a container. Implement max(iterable) and min(iterable)

parent a87fa642
......@@ -282,11 +282,40 @@ public:
}
};
class Box;
class BoxIterator : public std::iterator<std::forward_iterator_tag, Box*> {
public:
BoxIterator(Box* iter) : iter(iter), value(nullptr) {}
bool operator==(BoxIterator const& rhs) const { return (iter == rhs.iter && value == rhs.value); }
bool operator!=(BoxIterator const& rhs) const { return !(*this == rhs); }
BoxIterator& operator++();
BoxIterator operator++(int) {
BoxIterator tmp(*this);
operator++();
return tmp;
}
Box* operator*() const { return value; }
Box* operator*() { return value; }
private:
Box* iter;
Box* value;
};
extern bool TRACK_ALLOCATIONS;
class Box : public GCObject {
public:
BoxedClass* cls;
BoxIterator begin() const;
BoxIterator end() const { return BoxIterator(nullptr); }
constexpr Box(const ObjectFlavor* flavor, BoxedClass* c) __attribute__((visibility("default")))
: GCObject(flavor), cls(c) {
// if (TRACK_ALLOCATIONS) {
......@@ -297,6 +326,7 @@ public:
};
class SetattrRewriteArgs;
class SetattrRewriteArgs2;
class GetattrRewriteArgs;
......
......@@ -49,7 +49,27 @@ extern "C" Box* abs_(Box* x) {
}
}
extern "C" Box* min_(Box* o0, Box* o1) {
extern "C" Box* min1(Box* container) {
Box* minElement = nullptr;
for (Box* e : *container) {
if (!minElement) {
minElement = e;
} else {
Box* comp_result = compareInternal(minElement, e, AST_TYPE::Gt, NULL);
if (nonzero(comp_result)) {
minElement = e;
}
}
}
if (!minElement) {
fprintf(stderr, "ValueError: min() arg is an empty sequence\n");
raiseExc();
}
return minElement;
}
extern "C" Box* min2(Box* o0, Box* o1) {
Box* comp_result = compareInternal(o0, o1, AST_TYPE::Gt, NULL);
bool b = nonzero(comp_result);
if (b) {
......@@ -58,7 +78,27 @@ extern "C" Box* min_(Box* o0, Box* o1) {
return o0;
}
extern "C" Box* max_(Box* o0, Box* o1) {
extern "C" Box* max1(Box* container) {
Box* maxElement = nullptr;
for (Box* e : *container) {
if (!maxElement) {
maxElement = e;
} else {
Box* comp_result = compareInternal(maxElement, e, AST_TYPE::Lt, NULL);
if (nonzero(comp_result)) {
maxElement = e;
}
}
}
if (!maxElement) {
fprintf(stderr, "ValueError: max() arg is an empty sequence\n");
raiseExc();
}
return maxElement;
}
extern "C" Box* max2(Box* o0, Box* o1) {
Box* comp_result = compareInternal(o0, o1, AST_TYPE::Lt, NULL);
bool b = nonzero(comp_result);
if (b) {
......@@ -225,24 +265,9 @@ Box* getattr3(Box* obj, Box* _str, Box* default_value) {
}
Box* map2(Box* f, Box* container) {
static std::string _iter("__iter__");
static std::string _hasnext("__hasnext__");
static std::string _next("next");
Box* iter = callattr(container, &_iter, true, 0, NULL, NULL, NULL, NULL);
Box* rtn = new BoxedList();
while (true) {
Box* hasnext = callattr(iter, &_hasnext, true, 0, NULL, NULL, NULL, NULL);
bool hasnext_bool = nonzero(hasnext);
if (!hasnext_bool)
break;
Box* next = callattr(iter, &_next, true, 0, NULL, NULL, NULL, NULL);
Box* r = runtimeCall(f, 1, next, NULL, NULL, NULL);
listAppendInternal(rtn, r);
for (Box* e : *container) {
listAppendInternal(rtn, runtimeCall(f, 1, e, NULL, NULL, NULL));
}
return rtn;
}
......@@ -275,10 +300,17 @@ void setupBuiltins() {
builtins_module->giveAttr("hash", hash_obj);
abs_obj = new BoxedFunction(boxRTFunction((void*)abs_, NULL, 1, false));
builtins_module->giveAttr("abs", abs_obj);
min_obj = new BoxedFunction(boxRTFunction((void*)min_, NULL, 2, false));
CLFunction* min_func = boxRTFunction((void*)min1, NULL, 1, false);
addRTFunction(min_func, (void*)min2, NULL, 2, false);
min_obj = new BoxedFunction(min_func);
builtins_module->giveAttr("min", min_obj);
max_obj = new BoxedFunction(boxRTFunction((void*)max_, NULL, 2, false));
CLFunction* max_func = boxRTFunction((void*)max1, NULL, 1, false);
addRTFunction(max_func, (void*)max2, NULL, 2, false);
max_obj = new BoxedFunction(max_func);
builtins_module->giveAttr("max", max_obj);
chr_obj = new BoxedFunction(boxRTFunction((void*)chr, NULL, 1, false));
builtins_module->giveAttr("chr", chr_obj);
trap_obj = new BoxedFunction(boxRTFunction((void*)trap, NULL, 0, false));
......
......@@ -354,22 +354,9 @@ extern "C" Box* listNew1(Box* cls) {
extern "C" Box* listNew2(Box* cls, Box* container) {
assert(cls == list_cls);
static std::string _iter("__iter__");
static std::string _hasnext("__hasnext__");
static std::string _next("next");
Box* iter = callattr(container, &_iter, true, 0, NULL, NULL, NULL, NULL);
Box* rtn = new BoxedList();
while (true) {
Box* hasnext = callattr(iter, &_hasnext, true, 0, NULL, NULL, NULL, NULL);
bool hasnext_bool = nonzero(hasnext);
if (!hasnext_bool)
break;
Box* next = callattr(iter, &_next, true, 0, NULL, NULL, NULL, NULL);
listAppendInternal(rtn, next);
BoxedList* rtn = new BoxedList();
for (Box* e : *container) {
listAppendInternal(rtn, e);
}
return rtn;
}
......
......@@ -42,8 +42,6 @@ extern "C" BoxedString* str(Box* obj);
extern "C" Box* repr(Box* obj);
extern "C" BoxedInt* hash(Box* obj);
// extern "C" Box* abs_(Box* obj);
// extern "C" Box* min_(Box* o0, Box* o1);
// extern "C" Box* max_(Box* o0, Box* o1);
extern "C" Box* open1(Box* arg);
extern "C" Box* open2(Box* arg1, Box* arg2);
// extern "C" Box* chr(Box* arg);
......
......@@ -36,6 +36,26 @@ namespace pyston {
bool IN_SHUTDOWN = false;
BoxIterator& BoxIterator::operator++() {
static std::string hasnext_str("__hasnext__");
static std::string next_str("next");
Box* hasnext = callattr(iter, &hasnext_str, true, 0, NULL, NULL, NULL, NULL);
if (nonzero(hasnext)) {
value = callattr(iter, &next_str, true, 0, NULL, NULL, NULL, NULL);
} else {
iter = nullptr;
value = nullptr;
}
return *this;
}
BoxIterator Box::begin() const {
static std::string iter_str("__iter__");
Box* iter = callattr(const_cast<Box*>(this), &iter_str, true, 0, NULL, NULL, NULL, NULL);
return ++BoxIterator(iter);
}
extern "C" BoxedFunction::BoxedFunction(CLFunction* f) : HCBox(&function_flavor, function_cls), f(f) {
if (f->source) {
assert(f->source->ast);
......
# expected: fail
# - min/max on iterables
import math
print max(range(5))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment