use StrInst (Str(*)) use Iter IntoIter(*), for-each use List (List) use Alloc (Allocator) use Slice subslice use Mem use Slice (Slice) use Error panic # TODO: utf8 support # - pop() for example. StrBuilder alloc chars List alloc U8 fn write-slice (builder Ptr (StrBuilder alloc), s Slice U8) <= Allocator alloc List.add-all(&builder&.chars, s) fn write-char (builder Ptr (StrBuilder alloc), c Char) -> Unit <= Allocator alloc builder write-slice(c Char.as-u8-slice(&@undefined)) fn write (builder Ptr (StrBuilder alloc), s str) -> Unit <= Str str, Allocator alloc s chars() for-each(fn c: builder write-char(c)) fn writeln (builder, s): builder write('\(s)\n') # TODO: change to num-bytes fn count(sb Ptr (StrBuilder alloc)): sb&.chars.count fn num-bytes(sb Ptr (StrBuilder alloc)): sb&.chars.count fn pop (sb Ptr (StrBuilder alloc)) <= Allocator alloc: List.pop(&sb&.chars) fn trim-bytes (sb Ptr (StrBuilder Allocator), new-count Size): List.trim(&sb&.chars, new-count) fn popn-bytes (sb Ptr (StrBuilder Allocator), pop-bytes Size) sb-bytes = sb num-bytes() if pop-bytes > sb-bytes panic('(StrBuilder.popn-bytes) poppin too many bytes (\(pop-bytes)), but can only pop \(sb-bytes)') return sb trim-bytes(sb-bytes - pop-bytes) fn mk (al alloc) -> StrBuilder alloc <= Allocator alloc return StrBuilder { chars: List.mk(al) } fn free(sb Ptr (StrBuilder Allocator)) List.free(&sb&.chars) # DOES NOT REALLOCATE! fn as-str (builder Ptr (StrBuilder alloc)): StrView { contents: builder&.chars.elements subslice(0, builder&.chars.count) Slice.cast-slice() } fn as-char-slice (builder Ptr (StrBuilder alloc)): builder&.chars List.to-slice() fn free (builder Ptr (StrBuilder alloc)) <= Allocator alloc List.free(&builder&.chars) inst Str StrBuilder print-str (s) len = s.chars.count ptr = s.chars.elements.ptr Cnile.printf2('%.*s', len, ptr) return chars (s): as-str(&s) into-iter() inst IntoIter StrBuilder into-iter (self): self chars() fn mk-dyn-str(s, al) sb =& mk(al) sb write(s) sb write-char(Char.nullchar()) dynstr = sb as-str() # freeing dynstr frees all memory of this sb # hide nullchar return StrView { contents: Slice { ptr: dynstr.contents.ptr, count: dynstr.contents.count - 1 } } fn mk-const-str(s, al): s mk-dyn-str(al).contents.ptr Mem.cast() as ConstStr # in reality, shouldn't be here fn free-const-str (s ConstStr, al Allocator) al Alloc.free(Slice{ ptr: @cast(s), count: 0 })