diff --git a/libs/core/core.cpp b/libs/core/core.cpp index b575ca41..dffb6b2c 100644 --- a/libs/core/core.cpp +++ b/libs/core/core.cpp @@ -153,15 +153,19 @@ namespace Array_ { //% int length(RefCollection *c) { return c->length(); } //% + void setLength(RefCollection *c, int newLength) { c->setLength(newLength); } + //% void push(RefCollection *c, uint32_t x) { c->push(x); } //% uint32_t pop(RefCollection *c) { return c->pop(); } //% uint32_t getAt(RefCollection *c, int x) { return c->getAt(x); } //% - void removeAt(RefCollection *c, int x) { c->removeAt(x); } + void setAt(RefCollection *c, int x, uint32_t y) { c->setAt(x, y); } //% - void setAt(RefCollection *c, int x, uint32_t y) { c->setAt(x, y); } + uint32_t removeAt(RefCollection *c, int x) { return c->removeAt(x); } + //% + void insertAt(RefCollection *c, int x, uint32_t value) { c->insertAt(x, value); } //% int indexOf(RefCollection *c, uint32_t x, int start) { return c->indexOf(x, start); } //% diff --git a/libs/core/pxt.cpp b/libs/core/pxt.cpp index 400e5dbc..2f8c67cb 100644 --- a/libs/core/pxt.cpp +++ b/libs/core/pxt.cpp @@ -246,6 +246,25 @@ namespace pxt { return; } + void Segment::ensure(uint16_t newSize) + { + if (newSize < size) + { + return; + } + growByMin(newSize); + } + + void Segment::setLength(uint32_t newLength) + { + if (newLength > size) + { + ensure(length); + } + length = newLength; + return; + } + void Segment::push(uint32_t value) { this->set(length, value); @@ -269,17 +288,64 @@ namespace pxt { return 0; } - void Segment::remove(uint32_t i) + //this function removes an element at index i and shifts the rest of the elements to + //left to fill the gap + uint32_t Segment::remove(uint32_t i) { #ifdef DEBUG_BUILD - printf("In Segment::remove\n"); + printf("In Segment::remove index:%u\n", i); this->print(); #endif if (i < length) { - data[i] = Segment::MissingValue; + //value to return + uint32_t ret = data[i]; + if (i + 1 < length) + { + //Move the rest of the elements to fill in the gap. + memmove(data + i, data + i + 1, (length - i - 1) * sizeof(uint32_t)); + } + length--; + data[length] = Segment::MissingValue; +#ifdef DEBUG_BUILD + printf("After Segment::remove index:%u\n", i); + this->print(); +#endif + return ret; } - return; + error(ERR_OUT_OF_BOUNDS); + return 0; + } + + //this function inserts element value at index i by shifting the rest of the elements right. + void Segment::insert(uint32_t i, uint32_t value) + { +#ifdef DEBUG_BUILD + printf("In Segment::insert index:%u value:%u\n", i, value); + this->print(); +#endif + + if (i < length) + { + ensure(length + 1); + if (i + 1 < length) + { + //Move the rest of the elements to fill in the gap. + memmove(data + i + 1, data + i, (length - i) * sizeof(uint32_t)); + } + + data[i] = value; + length++; + } + else + { + //This is insert beyond the length, just call set which will adjust the length + set(i, value); + } +#ifdef DEBUG_BUILD + printf("After Segment::insert index:%u\n", i); + this->print(); +#endif } void Segment::print() @@ -365,17 +431,34 @@ namespace pxt { } } - void RefCollection::removeAt(int i) + uint32_t RefCollection::removeAt(int i) { if (!head.isValidIndex((uint32_t)i)) { - return; + error(ERR_OUT_OF_BOUNDS); + return 0; } if (isRef()) { decr(head.get(i)); } - head.remove(i); + return head.remove(i); + } + + void RefCollection::insertAt(int i, uint32_t value) + { + if (i < length()) + { + head.insert(i, value); + if (isRef()) + { + incr(value); + } + } + else + { + error(ERR_OUT_OF_BOUNDS); + } } void RefCollection::setAt(int i, uint32_t value) diff --git a/libs/core/pxt.h b/libs/core/pxt.h index 84ebb149..6da5ec7c 100644 --- a/libs/core/pxt.h +++ b/libs/core/pxt.h @@ -180,6 +180,7 @@ namespace pxt { static uint16_t growthFactor(uint16_t size); void growByMin(uint16_t minSize); void growBy(uint16_t newSize); + void ensure(uint16_t newSize); public: Segment() : data (nullptr), length(0), size(0) {}; @@ -188,11 +189,13 @@ namespace pxt { void set(uint32_t i, uint32_t value); uint32_t getLength() { return length;}; + void setLength(uint32_t newLength); void push(uint32_t value); uint32_t pop(); - void remove(uint32_t i); + uint32_t remove(uint32_t i); + void insert(uint32_t i, uint32_t value); //Returns true if there is a valid index greater than or equal to 'i', returns false otherwise //If 'i' is valid returns it in 'result', if not tries to find the next valid @@ -225,11 +228,17 @@ namespace pxt { void print(); uint32_t length() { return head.getLength();} + void setLength(uint32_t newLength) { head.setLength(newLength); } + void push(uint32_t x); uint32_t pop(); - uint32_t getAt(int x); - void removeAt(int x); - void setAt(int x, uint32_t y); + uint32_t getAt(int i); + void setAt(int i, uint32_t x); + //removes the element at index i and shifts the other elements left + uint32_t removeAt(int i); + //inserts the element at index i and moves the other elements right. + void insertAt(int i, uint32_t x); + int indexOf(uint32_t x, int start); int removeElement(uint32_t x); }; diff --git a/package.json b/package.json index 33691fa0..4650bf07 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,6 @@ "semantic-ui-less": "^2.2.4" }, "dependencies": { - "pxt-core": "0.7.13" + "pxt-core": "0.8.2" } }