hare

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

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

fmt: expand format string parser

Diffstat:
Mfmt/fmt.ha | 64+++++++++++++++++++++++++++++++++++-----------------------------
1 file changed, 35 insertions(+), 29 deletions(-)

diff --git a/fmt/fmt.ha b/fmt/fmt.ha @@ -104,25 +104,31 @@ export fn fprintf( r: rune => r, }; - let mod = modifiers { ... }; - const arg = switch (r) { - '{' => match (io::write(s, utf8::encode_rune('{'))) { - err: io::error => return err, - w: size => { - n += w; - continue; - }, - }, - '}' => { - i += 1z; - args[i - 1z]; - }, - ':' => { - scan_modifiers(&iter, &mod); - i += 1z; - args[i - 1z]; + const arg = if (r == '{') match (io::write( + s, utf8::encode_rune('{'))) { + err: io::error => return err, + w: size => { + n += w; + continue; }, - * => args[scan_uint(r, &iter)], + } else if (ascii::isdigit(r)) { + strings::push(&iter, r); + args[scan_uint(&iter)]; + } else { + strings::push(&iter, r); + i += 1z; + args[i - 1z]; + }; + + let mod = modifiers { ... }; + r = match (strings::next(&iter)) { + void => abort("Invalid format string (unterminated '{')"), + r: rune => r, + }; + switch (r) { + ':' => scan_modifiers(&iter, &mod), + '}' => void, + * => abort("Invalid format string"), }; format(s, arg, &mod); @@ -173,29 +179,29 @@ fn format( }, }; -fn scan_uint(r: rune, iter: *strings::iterator) uint = { - assert(ascii::isdigit(r)); - let num = alloc([]u8, [r: u32: u8], 1z); // XXX: alloc slice w/o cap +fn scan_uint(iter: *strings::iterator) uint = { + let num = alloc([]u8, [], 1z); // TODO: alloc slice w/o cap defer free(num); for (true) { - r = match (strings::next(iter)) { - void => abort("Invalid format string (unterminated '(')"), + let r = match (strings::next(iter)) { + void => abort("Invalid format string (unterminated '{')"), r: rune => r, }; - switch (r) { - * => append(num, r: u32: u8), - ':' => abort(), // TODO: Format modifiers - '}' => match (strconv::stou(strings::from_utf8(num))) { + if (ascii::isdigit(r)) { + append(num, r: u32: u8); + } else { + strings::push(iter, r); + match (strconv::stou(strings::from_utf8(num))) { (strconv::invalid | strconv::overflow) => abort("Invalid format string (invalid index)"), u: uint => return u, - }, + }; }; }; abort("unreachable"); }; fn scan_modifiers(iter: *strings::iterator, mod: *modifiers) void = { - abort(); // TODO + abort("TODO: format modifiers"); };