plum
git clone https://git.pyrossh.dev/plum
A statically typed, imperative programming language inspired by rust, python
plum-std/ByteSlice.plum
| a271f34 | 1 | module std |
| b7071c9 | 2 | import std/Byte |
| b7071c9 | 3 | import std/Str |
| 73b5e55 | 4 | import std/Bool |
| ca5fd6f | 5 | import std/Number |
| a271f34 | 6 | |
| a271f34 | 7 | # ByteSlice is `[]Byte` — Plum's counterpart to Go's byte slice: a |
| a271f34 | 8 | # fixed-length, mutable sequence of raw bytes backed directly by a wasm-gc |
| 73e4ff1 | 9 | # `array<i8>` (see `plum-wasm-codegen`'s `PlumType::TByteSlice`) — the same |
| 73e4ff1 | 10 | # raw array type `Buffer`'s own `data` field uses underneath (`Str` itself is |
| 73e4ff1 | 11 | # now a real two-level struct wrapping a `Buffer`, not this array directly; |
| 73e4ff1 | 12 | # see `str.plum`'s header comment). Every method here, and `makeBytes`/ |
| 73e4ff1 | 13 | # `copyBytes` below, is a compiler intrinsic (see `compileIntrinsicFnBody`) |
| a271f34 | 14 | # — there's no way to express raw array length/indexing/construction/copying |
| 73e4ff1 | 15 | # in Plum source itself; `copyStrToBytes`/`bytesToStr` build on top of them |
| 73e4ff1 | 16 | # instead of needing intrinsics of their own. |
| 5f2f962 | 17 | enum ByteSlice = |
| 5f2f962 | 18 | | ByteSlice |
| 5f2f962 | 19 | |
| a271f34 | 20 | # Number of bytes in the slice. |
| a271f34 | 21 | fun length(self) -> Int = |
| a271f34 | 22 | todo |
| a271f34 | 23 | |
| a271f34 | 24 | # The raw byte at index `i`. Traps if `i` is out of range. |
| a271f34 | 25 | fun get(self, i: Int) -> Byte = |
| a271f34 | 26 | todo |
| a271f34 | 27 | |
| a271f34 | 28 | # Overwrites the byte at index `i` with `b`. Traps if `i` is out of range. |
| a271f34 | 29 | fun set(self, i: Int, b: Byte) -> Unit = |
| a271f34 | 30 | todo |
| a271f34 | 31 | |
| a271f34 | 32 | # A new zero-filled `[]Byte` of length `n`. |
| a271f34 | 33 | fun makeBytes(n: Int) -> []Byte = |
| a271f34 | 34 | todo |
| a271f34 | 35 | |
| a271f34 | 36 | # Copies `n` bytes from `src` (starting at `srcStart`) into `dst` (starting at |
| a271f34 | 37 | # `dstStart`). `dst` and `src` may be the same slice — overlapping ranges are |
| a271f34 | 38 | # handled correctly, matching wasm's `array.copy`. |
| a271f34 | 39 | fun copyBytes(dst: []Byte, dstStart: Int, src: []Byte, srcStart: Int, n: Int) -> Unit = |
| a271f34 | 40 | todo |
| a271f34 | 41 | |
| 73e4ff1 | 42 | # Like `copyBytes`, but the source is a `Str` — ordinary Plum glue over |
| 73e4ff1 | 43 | # `copyBytes` itself, reaching through `Str`'s real `data: Buffer` field to |
| 73e4ff1 | 44 | # its own `data: []Byte` (see `str.plum`'s header comment on `Str`'s shape). |
| a271f34 | 45 | fun copyStrToBytes(dst: []Byte, dstStart: Int, src: Str, srcStart: Int, n: Int) -> Unit = |
| 73e4ff1 | 46 | copyBytes(dst, dstStart, src.data.data, srcStart, n) |
| a271f34 | 47 | |
| a271f34 | 48 | # Copies out `n` bytes of `src` starting at `start` into a fresh, independent |
| a271f34 | 49 | # `Str` — never aliases `src`, so mutating `src` afterwards can't |
| 73e4ff1 | 50 | # retroactively change an already-returned `Str`. Ordinary Plum: allocate a |
| 73e4ff1 | 51 | # right-sized `[]Byte`, copy into it, wrap it in a fresh `Buffer`/`Str` pair. |
| a271f34 | 52 | fun bytesToStr(src: []Byte, start: Int, n: Int) -> Str = |
| 73e4ff1 | 53 | data := makeBytes(n) |
| 73e4ff1 | 54 | copyBytes(data, 0, src, start, n) |
| 73e4ff1 | 55 | return Str(data: Buffer(data: data, len: n)) |