~sircmpwn/hare

55fcd753b387011a3c79d8f608d264bc520d4816 — Sebastian 3 months ago 70127bd
strings: simplify sub

sub also now aborts when one of the indices exceeds the string's length.

Signed-off-by: Sebastian <sebastian@sebsite.pw>
2 files changed, 7 insertions(+), 10 deletions(-)

M fmt/print.ha
M strings/sub.ha
M fmt/print.ha => fmt/print.ha +3 -1
@@ 83,7 83,9 @@ case void =>
case let r: rune =>
	return io::write(out, utf8::encoderune(r));
case let s: str =>
	if (mod.prec != 0) s = strings::sub(s, 0, mod.prec);
	if (mod.prec > 0 && mod.prec < len(s)) {
		s = strings::sub(s, 0, mod.prec);
	};
	return io::write(out, strings::toutf8(s));
case let b: bool =>
	return io::write(out, strings::toutf8(if (b) "true" else "false"));

M strings/sub.ha => strings/sub.ha +4 -9
@@ 6,18 6,15 @@ use encoding::utf8;
export type end = void;

fn utf8_byte_len_bounded(iter: *iterator, end: size) size = {
	let pos = 0z;
	for (let i = 0z; i < end; i += 1) {
		let r = match (next(iter)) {
		case let r: rune =>
			yield r;
		case void =>
			break;
			abort("index exceeds string length");
		};

		pos += utf8::runesz(r);
	};
	return pos;
	return iter.dec.offs;
};

// Returns a substring in the range [start, end - 1], where each argument is the


@@ 29,14 26,12 @@ fn utf8_byte_len_bounded(iter: *iterator, end: size) size = {
// may cause unexpected linguistic errors to arise. You may want to use a
// third-party Unicode module instead.
export fn sub(s: str, start: size, end: (size | end)) str = {
	if (end is size) {
		assert(start <= end as size, "start is higher than end");
	};
	let iter = iter(s);
	let starti = utf8_byte_len_bounded(&iter, start);
	let endi = match (end) {
	case let sz: size =>
		yield starti + utf8_byte_len_bounded(&iter, sz - start);
		assert(start <= sz, "start is higher than end");
		yield utf8_byte_len_bounded(&iter, sz - start);
	case =>
		yield len(s);
	};