plum

#treesitter#compiler#wasm

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))