hare

The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit 2a882b165c7cc5eede197109e2bdf65a73d1421f
parent 7f0e8f75fe7d437561b8a705aa060ea5e053bbf3
Author: Drew DeVault <sir@cmpwn.com>
Date:   Fri,  5 Feb 2021 16:26:01 -0500

strings: add push function

Diffstat:
Mstrings/iter.ha | 31+++++++++++++++++++++++++++----
1 file changed, 27 insertions(+), 4 deletions(-)

diff --git a/strings/iter.ha b/strings/iter.ha @@ -1,14 +1,27 @@ use encoding::utf8; // An iterator which yields each rune from a string. -export type iterator = utf8::decoder; +export type iterator = struct { + dec: utf8::decoder, + push: (rune | void), +}; // Initializes a string iterator. -export fn iter(src: str) iterator = utf8::decode(src); +export fn iter(src: str) iterator = iterator { + dec = utf8::decode(src), + push = void, +}; // Get the next rune from an iterator, or void if there are none left. export fn next(iter: *iterator) (rune | void) = { - return match (utf8::next(iter)) { + match (iter.push) { + r: rune => { + iter.push = void; + return r; + }, + void => void, + }; + return match (utf8::next(&iter.dec)) { r: rune => r, void => void, utf8::more => abort("Invalid UTF-8 string (this should not happen)"), @@ -16,9 +29,17 @@ export fn next(iter: *iterator) (rune | void) = { }; }; +// Pushes a rune back to the iterator, effectively un-reading it. The given rune +// will be returned on the next call to 'next'. Only one rune can be pushed at a +// time. +export fn push(iter: *iterator, r: rune) void = { + assert(iter.push is void); + iter.push = r; +}; + // Return a substring from the next rune to the end of the string. export fn iter_str(iter: *iterator) str = { - return from_utf8(iter.src[iter.offs..]); + return from_utf8(iter.dec.src[iter.dec.offs..]); }; @test fn iter() void = { @@ -40,4 +61,6 @@ export fn iter_str(iter: *iterator) str = { }; assert(next(&s) is void); assert(next(&s) is void); + push(&s, 'q'); + assert(next(&s) as rune == 'q'); };