diff --git a/libs/hello/kind.json b/libs/hello/kind.json index 468413e1..73eb3d11 100644 --- a/libs/hello/kind.json +++ b/libs/hello/kind.json @@ -6,6 +6,7 @@ ], "public": true, "dependencies": { - "microbit": "file:../microbit" + "microbit": "file:../microbit", + "microbit-radio": "file:../microbit-radio" } } diff --git a/libs/lang-test0/lang-test0.ts b/libs/lang-test0/lang-test0.ts index 66cf5111..77070c32 100644 --- a/libs/lang-test0/lang-test0.ts +++ b/libs/lang-test0/lang-test0.ts @@ -59,6 +59,7 @@ testMemoryFreeHOF(); postPreFix() eqOp() testEnums() +testBuffer() // test some top-level code let xsum = 0; @@ -722,3 +723,52 @@ function switchB(e: En) { } return r; } + +function bufferIs(b:Buffer, a:number[]) { + assert(b.length == a.length, "bis-len") + for (let i = 0; i < a.length; ++i) { + if (a[i] != b[i]) { + assert(false, `bufferIs: buf[${i}]:${b[i]} != ${a[i]}`) + } + } +} + +function testBuffer() { + let b = pins.createBuffer(3); + assert(b[0] == 0, "buf0"); + assert(b[1] == 0, "buf0"); + assert(b[2] == 0, "buf0"); + assert(b[-100000] == 0, "bufM"); + assert(b[100000] == 0, "bufM"); + + b[0] = 42; + bufferIs(b, [42, 0, 0]); + b[2] = 41; + bufferIs(b, [42, 0, 41]); + + b.rotate(1) + bufferIs(b, [0, 41, 42]); + b.rotate(-2) + bufferIs(b, [41, 42, 0]); + b.shift(1) + bufferIs(b, [42, 0, 0]); + b.rotate(9) + bufferIs(b, [42, 0, 0]); + b.rotate(-9) + bufferIs(b, [42, 0, 0]); + + b.fill(4); + bufferIs(b, [4, 4, 4]); + + b.fill(12, 1, 1); + bufferIs(b, [4, 12, 4]); + + b.fill(13, 1, -1); + bufferIs(b, [4, 13, 13]); + + b.fill(100, -1, -1); + bufferIs(b, [4, 13, 13]); + + b.shift(-1) + bufferIs(b, [0, 4, 13]); +} diff --git a/libs/microbit/buffer.cpp b/libs/microbit/buffer.cpp new file mode 100644 index 00000000..843b8076 --- /dev/null +++ b/libs/microbit/buffer.cpp @@ -0,0 +1,72 @@ +#include "ksbit.h" + +//% indexerGet=BufferMethods::getByte indexerSet=BufferMethods::setByte +namespace BufferMethods { + //% + int getByte(Buffer buf, int off) { + return max(ManagedBuffer(buf).getByte(off), 0); + } + + //% + void setByte(Buffer buf, int off, int v) { + ManagedBuffer(buf).setByte(off, v); + } + + /** Returns the length of a Buffer object. */ + //% property + int length(Buffer s) { + return s->length; + } + + /** + * Fill (a fragment) of the buffer with given value. + */ + //% + void fill(Buffer buf, int value, int offset = 0, int length = -1) + { + ManagedBuffer(buf).fill(value, offset, length); + } + + /** + * Return a copy of a fragment of a buffer. + */ + //% + Buffer slice(Buffer buf, int offset = 0, int length = -1) + { + return ManagedBuffer(buf).slice(offset, length).leakData(); + } + + /** + * Shift buffer left in place, with zero padding. + * @param offset number of bytes to shift; use negative value to shift right + */ + //% + void shift(Buffer buf, int offset) + { + ManagedBuffer(buf).shift(offset); + } + + /** + * Rotate buffer left in place. + * @param offset number of bytes to shift; use negative value to shift right + */ + //% + void rotate(Buffer buf, int offset) + { + ManagedBuffer(buf).rotate(offset); + } + + // int readBytes(uint8_t *dst, int offset, int length, bool swapBytes = false) const; + // int writeBytes(int dstOffset, uint8_t *src, int length, bool swapBytes = false); + + /** + * Write contents of `src` at `dstOffset` in current buffer. + */ + //% + void write(Buffer buf, int dstOffset, Buffer src) + { + //Not supported, we only do up to 4 args :/ + //void write(Buffer buf, int dstOffset, Buffer src, int srcOffset = 0, int length = -1) + ManagedBuffer(buf).writeBuffer(dstOffset, ManagedBuffer(src), 0, -1); + } +} diff --git a/libs/microbit/core.cpp b/libs/microbit/core.cpp index e4a36350..821ee4cd 100644 --- a/libs/microbit/core.cpp +++ b/libs/microbit/core.cpp @@ -324,7 +324,7 @@ namespace ksrt { RefAction *stclo(RefAction *a, int idx, uint32_t v) { //DBG("STCLO "); a->print(); DBG("@%d = %p\n", idx, (void*)v); - a->st(idx, v); + a->stCore(idx, v); return a; } diff --git a/libs/microbit/core.d.ts b/libs/microbit/core.d.ts index 916a781c..fa39b096 100644 --- a/libs/microbit/core.d.ts +++ b/libs/microbit/core.d.ts @@ -82,6 +82,10 @@ interface String { } +interface Buffer { + [index: number]: number; +} + /** * Converts A string to an integer. * @param s A string to convert into a number. @@ -93,4 +97,3 @@ interface Object {} interface Function {} interface IArguments {} interface RegExp {} - diff --git a/libs/microbit/kind.json b/libs/microbit/kind.json index 2dff51ed..b6024527 100644 --- a/libs/microbit/kind.json +++ b/libs/microbit/kind.json @@ -23,7 +23,8 @@ "music.ts", "pins.cpp", "serial.cpp", - "serial.ts" + "serial.ts", + "buffer.cpp" ], "public": true, "dependencies": {}, @@ -88,7 +89,7 @@ "autoRun": true }, "compileService": { - "gittag": "v0.1.2", + "gittag": "v0.1.5", "serviceId": "ws" }, "serial": { diff --git a/libs/microbit/ksbit.h b/libs/microbit/ksbit.h index 97012b5e..abdf5d72 100644 --- a/libs/microbit/ksbit.h +++ b/libs/microbit/ksbit.h @@ -1,6 +1,8 @@ #include "kindscript.h" +#include "ManagedBuffer.h" using namespace kindscript; MicroBitPin *getPin(int id); typedef ImageData* Image; +typedef BufferData* Buffer; diff --git a/libs/microbit/pins.cpp b/libs/microbit/pins.cpp index 12f9631a..c8193239 100644 --- a/libs/microbit/pins.cpp +++ b/libs/microbit/pins.cpp @@ -179,6 +179,16 @@ namespace pins { } } + /** + * Create a new zero-initialized buffer. + * @param size number of bytes in the buffer + */ + //% + Buffer createBuffer(int size) + { + return ManagedBuffer(size).leakData(); + } + // TODO: void i2cReadBuffer(int address, RefBuffer *buf) { diff --git a/libs/microbit/shims.d.ts b/libs/microbit/shims.d.ts index c48f7dc2..fb28059e 100644 --- a/libs/microbit/shims.d.ts +++ b/libs/microbit/shims.d.ts @@ -374,7 +374,7 @@ declare namespace control { * @param mode optional definition of how the event should be processed after construction (default is CREATE_AND_QUEUE). */ //% weight=21 blockGap=12 blockId="control_raise_event" block="raise event|from source %src=control_event_source|with value %value=control_event_value" blockExternalInputs=1 - //% mode.defl=1 shim=control::raiseEvent + //% mode.defl=1 shim=control::raiseEvent function raiseEvent(src: number, value: number, mode: EventCreationMode): void; /** @@ -534,6 +534,13 @@ declare namespace pins { */ //% help=pins/analog-pitch weight=14 async shim=pins::analogPitch function analogPitch(frequency: number, ms: number): void; + + /** + * Create a new zero-initialized buffer. + * @param size number of bytes in the buffer + */ + //% shim=pins::createBuffer + function createBuffer(size: number): Buffer; } @@ -566,4 +573,45 @@ declare namespace serial { function readScreen(): void; } + + + //% indexerGet=BufferMethods::getByte indexerSet=BufferMethods::setByte +declare interface Buffer { + /** Returns the length of a Buffer object. */ + //% property shim=BufferMethods::length + length: number; + + /** + * Fill (a fragment) of the buffer with given value. + */ + //% offset.defl=0 length.defl=-1 shim=BufferMethods::fill + fill(value: number, offset?: number, length?: number): void; + + /** + * Return a copy of a fragment of a buffer. + */ + //% offset.defl=0 length.defl=-1 shim=BufferMethods::slice + slice(offset?: number, length?: number): Buffer; + + /** + * Shift buffer left in place, with zero padding. + * @param offset number of bytes to shift; use negative value to shift right + */ + //% shim=BufferMethods::shift + shift(offset: number): void; + + /** + * Rotate buffer left in place. + * @param offset number of bytes to shift; use negative value to shift right + */ + //% shim=BufferMethods::rotate + rotate(offset: number): void; + + /** + * Write contents of `src` at `dstOffset` in current buffer. + */ + //% shim=BufferMethods::write + write(dstOffset: number, src: Buffer): void; +} + // Auto-generated. Do not edit. Really. diff --git a/sim/libmbit.ts b/sim/libmbit.ts index 41ab453d..8d5ca9f6 100644 --- a/sim/libmbit.ts +++ b/sim/libmbit.ts @@ -527,4 +527,4 @@ namespace ks.rt.ImageMethods { } // TODO ... -} \ No newline at end of file +}