Something went wrong. Try again.
An experiment in static, refcounted, procedural language with ownership
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110use std.builtinuse std.char.(encode-utf8-raw, ?)use std.collections.Arrayfn str.from-utf8*(bytes: []u8) Result[str, unit] = if unsafe builtin.slice-utf8-validate(&bytes) { Result.Ok(unsafe as[_](bytes)) } else { Result.Err({}) }fn str.from-utf8*(bytes: &[]u8) Result[&str, unit] = if unsafe builtin.slice-utf8-validate(bytes) { Result.Ok(unsafe as[_](bytes)) } else { Result.Err({}) }// TODO: should be marked unsafefn str.from-utf8-unchecked*(bytes: []u8) str = unsafe as[_](bytes)// TODO: should be marked unsafefn str.from-utf8-unchecked*(bytes: &[]u8) &str = unsafe as[_](bytes)// TODO: should be marked unsafefn str.from-utf8-mut-unchecked*(bytes: &mut []u8) &mut str = unsafe as[_](bytes)fn as-bytes*(s: &str) &[]u8 = unsafe as[_](s)fn as-bytes-mut*(s: &mut str) &mut []u8 = unsafe as[_](s)fn fmt*(s: &str, buf: &mut StrBuf) unit = buf.push(s)type StrBuf*(array: Array[u8])fn StrBuf.new*() StrBuf = StrBuf.with-cap(1)fn StrBuf.with-cap*(cap: uint) StrBuf = StrBuf(array-with-nul-byte(cap))fn len*(sb: &StrBuf) uint = sb.array.len() - 1fn cap*(sb: &StrBuf) uint = sb.array.cap()fn is-empty*(sb: &StrBuf) bool = sb.len() == 0fn as-ref*(sb: &StrBuf) &str = str.from-utf8-unchecked( &sb.array.as-ref().[..sb.array.len() - 1] )fn as-mut*(sb: &mut StrBuf) &mut str = str.from-utf8-mut-unchecked( &mut sb.array.as-mut().[..sb.array.len() - 1] )fn take*(mut sb: StrBuf) str = { let s = sb.array.take() unsafe s.len -= 1 str.from-utf8-unchecked(s)}fn push*(sb: &mut StrBuf, s: str) unit = sb.push(&s)fn push*(sb: &mut StrBuf, s: &str) unit = { if s.len == 0 { return } let bytes = s.as-bytes() let len = bytes.len // TODO: This is a good use-case for implementing a `push([]T)` function. sb.array.reserve(len + 1) sb.array.set(sb.array.len() - 1, bytes.[0]) let mut i = 1 for if i < len { sb.array.push-unchecked(bytes.[i]) i += 1 } sb.array.push(b'\0')}fn push*(sb: &mut StrBuf, ch: char) unit = { let len = sb.array.len() let ch-len = ch.len-utf8() let new-len = len + ch-len // TODO: This is a good use-case for implementing an `extend` function. For this we need: // 1. Stack allocated arrays. We then encode the char into an array of 4 elements. // 2. Implement `std.array.extend([]T)` sb.array.reserve(ch-len + 1) sb.array.set-len(new-len - 1) ch.encode-utf8(&mut sb.array.as-mut().[len - 1..new-len - 1]) sb.array.push(b'\0')}fn clear*(sb: &mut StrBuf) unit = { sb.array = array-with-nul-byte(sb.array.cap())}fn array-with-nul-byte(cap: uint) Array[u8] = { let mut a = Array.with-cap(cap) a.push(b'\0') a}