hare

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

commit e15652b32701ef43535fe018f05ebf6f3718ecfc
parent c9539e8692cc24b57424e44afb4d7985454e5ef5
Author: Drew DeVault <sir@cmpwn.com>
Date:   Wed, 24 Feb 2021 12:23:55 -0500

Flesh out bufio, strio some more

Diffstat:
Mbufio/fixed.ha | 5+++--
Mfmt/fmt.ha | 8++++++++
Mhare/lex/lex.ha | 6+++++-
Mstrio/buffer.ha | 4++--
4 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/bufio/fixed.ha b/bufio/fixed.ha @@ -8,7 +8,8 @@ type fixed_stream = struct { }; // Creates an [io::stream] for a fixed, caller-supplied buffer. Supports either -// read or write, but not both. +// read or write, but not both. The program aborts if writes would exceed the +// buffer's capacity. export fn fixed(in: []u8, mode: io::mode) *io::stream = { let s = alloc(fixed_stream { stream = io::stream { @@ -42,7 +43,7 @@ fn fixed_read(s: *io::stream, buf: []u8) (size | io::error | io::EOF) = { fn fixed_write(s: *io::stream, buf: const []u8) (size | io::error) = { let stream = s: *fixed_stream; if (len(stream.buf) == 0) { - return 0z; + abort("bufio::fixed buffer exceeded"); }; const n = if (len(buf) > len(stream.buf)) len(stream.buf) else len(buf); stream.buf[..n] = buf[..n]; diff --git a/fmt/fmt.ha b/fmt/fmt.ha @@ -75,6 +75,14 @@ export fn asprintf(fmt: str, args: formattable...) str = { return strings::from_utf8_unsafe(bufio::buffer(buf) as []u8); }; +// Formats text for printing and writes it into a caller supplied buffer. The +// returned string is borrowed from this buffer. +export fn bsprintf(buf: []u8, fmt: str, args: formattable...) str = { + let sink = bufio::fixed(buf, io::mode::WRITE); + assert(fprintf(sink, fmt, args...) is size); + return strings::from_utf8_unsafe(buf); +}; + // Formats text for printing and writes it to [os::stderr], followed by a line // feed, then exits the program with an error status. export @noreturn fn fatal(fmt: str, args: formattable...) void = { diff --git a/hare/lex/lex.ha b/hare/lex/lex.ha @@ -1,6 +1,7 @@ // hare::lex provides a lexer for Hare source code. use ascii; use encoding::utf8; +use fmt; use io; use sort; use strconv; @@ -21,10 +22,13 @@ export type syntax = (location, str)!; // All possible lexer errors export type error = (io::error | syntax)!; +// Returns a human-friendly string for a given error export fn errstr(err: error) const str = { + static let buf: [2048]u8 = [0...]; return match (err) { err: io::error => io::errstr(err), - s: syntax => s.1, // TODO: format me + s: syntax => fmt::bsprintf(buf, "Syntax error @{}:{},{}: {}", + s.0.path, s.0.line, s.0.col, s.1), }; }; diff --git a/strio/buffer.ha b/strio/buffer.ha @@ -8,7 +8,7 @@ type fixed_stream = struct { }; // Creates a write-only string stream using the provided buffer for storage. -// The buffer will not be expanded if the writes exceed its capacity. +// The program aborts if writes would exceed the buffer's capacity. export fn fixed(in: []u8) *io::stream = { let s = alloc(fixed_stream { stream = io::stream { @@ -34,7 +34,7 @@ export fn string(s: *io::stream) str = { fn fixed_write(s: *io::stream, buf: const []u8) (size | io::error) = { let stream = s: *fixed_stream; if (len(stream.cur) == 0) { - return 0z; + abort("strio::fixed buffer exceeded"); }; const n = if (len(buf) > len(stream.cur)) len(stream.cur) else len(buf); stream.cur[..n] = buf[..n];