Fix on rethrow + macros.

This commit is contained in:
Christoffer Lerno
2023-06-27 20:40:46 +02:00
parent 550b1f23ec
commit 57c8b5fc75
10 changed files with 140 additions and 46 deletions

View File

@@ -375,7 +375,7 @@ fn void DString.reserve(DString* str, usz addition)
*str = (DString)realloc(data, StringData.sizeof + new_capacity, .using = data.allocator); *str = (DString)realloc(data, StringData.sizeof + new_capacity, .using = data.allocator);
} }
fn usz! DString.read_from_stream(DString* string, Stream* reader) fn usz! DString.read_from_stream(DString* string, Stream reader)
{ {
if (reader.supports_available()) if (reader.supports_available())
{ {

65
lib/std/encoding/csv.c3 Normal file
View File

@@ -0,0 +1,65 @@
module std::encoding::csv;
import std::io;
struct CsvReader
{
Stream stream;
String separator;
}
fn void CsvReader.init_file(CsvReader* csv, File* file, String separator = ",")
{
csv.stream = file.as_stream();
csv.separator = separator;
}
fn void CsvReader.init(CsvReader* csv, Stream stream, String separator = ",")
{
csv.stream = stream;
csv.separator = separator;
}
fn String[]! CsvReader.read_row(CsvReader csv, Allocator* using = mem::heap())
{
@stack_mem(512; Allocator* mem)
{
return csv.stream.readline(mem).split(csv.separator, .using = using);
};
}
fn String[]! CsvReader.tread_row(CsvReader csv)
{
return csv.read_row(mem::temp()) @inline;
}
fn void! CsvReader.skip_row(CsvReader csv) @maydiscard
{
@pool()
{
csv.stream.readline(mem::temp())!;
};
}
macro CsvReader.@each_row(CsvReader csv, int rows = int.max; @body(String[] row))
{
Stream stream = csv.stream;
String sep = csv.separator;
while (rows--)
{
@stack_mem(512; Allocator* mem)
{
String[] parts;
@pool()
{
String! s = stream.readline(mem::temp());
if (catch err = s)
{
if (err == IoError.EOF) return;
return err?;
}
parts = s.split(sep, .using = mem);
};
@body(parts);
};
}
}

View File

@@ -1,18 +1,18 @@
module std::io; module std::io;
def CloseStreamFn = fn void!(Stream*); def CloseStreamFn = fn void!(Stream);
def FlushStreamFn = fn void!(Stream*); def FlushStreamFn = fn void!(Stream);
def SeekStreamFn = fn usz!(Stream*, isz offset, Seek seek); def SeekStreamFn = fn usz!(Stream, isz offset, Seek seek);
def LenStreamFn = fn usz(Stream*); def LenStreamFn = fn usz(Stream);
def AvailableStreamFn = fn usz(Stream*); def AvailableStreamFn = fn usz(Stream);
def ReadStreamFn = fn usz!(Stream*, char[] bytes); def ReadStreamFn = fn usz!(Stream, char[] bytes);
def ReadFromStreamFn = fn usz!(Stream*, Stream*); def ReadFromStreamFn = fn usz!(Stream, Stream);
def ReadByteStreamFn = fn char!(Stream*); def ReadByteStreamFn = fn char!(Stream);
def PushbackByteStreamFn = fn void!(Stream*); def PushbackByteStreamFn = fn void!(Stream);
def WriteStreamFn = fn usz!(Stream*, char[] bytes); def WriteStreamFn = fn usz!(Stream, char[] bytes);
def WriteToStreamFn = fn usz!(Stream*, Stream* out); def WriteToStreamFn = fn usz!(Stream, Stream out);
def WriteByteStreamFn = fn void!(Stream*, char c); def WriteByteStreamFn = fn void!(Stream, char c);
def DestroyStreamFn = fn void!(Stream*); def DestroyStreamFn = fn void!(Stream);
struct StreamInterface struct StreamInterface
{ {
@@ -37,33 +37,33 @@ struct Stream
void* data; void* data;
} }
fn bool Stream.supports_seek(Stream* s) @inline => (bool)s.fns.seek_fn; fn bool Stream.supports_seek(Stream s) @inline => (bool)s.fns.seek_fn;
fn bool Stream.supports_available(Stream* s) @inline => s.fns.available_fn || s.fns.seek_fn; fn bool Stream.supports_available(Stream s) @inline => s.fns.available_fn || s.fns.seek_fn;
fn bool Stream.supports_len(Stream* s) @inline => s.fns.len_fn || s.fns.seek_fn; fn bool Stream.supports_len(Stream s) @inline => s.fns.len_fn || s.fns.seek_fn;
fn bool Stream.supports_read(Stream* s) @inline => s.fns.read_fn || s.fns.read_byte_fn; fn bool Stream.supports_read(Stream s) @inline => s.fns.read_fn || s.fns.read_byte_fn;
fn bool Stream.supports_read_from(Stream* s) @inline => (bool)s.fns.read_stream_fn; fn bool Stream.supports_read_from(Stream s) @inline => (bool)s.fns.read_stream_fn;
fn bool Stream.supports_write_to(Stream* s) @inline => (bool)s.fns.write_stream_fn; fn bool Stream.supports_write_to(Stream s) @inline => (bool)s.fns.write_stream_fn;
fn bool Stream.supports_pushback_byte(Stream* s) @inline => s.fns.pushback_byte_fn || s.fns.seek_fn; fn bool Stream.supports_pushback_byte(Stream s) @inline => s.fns.pushback_byte_fn || s.fns.seek_fn;
fn bool Stream.supports_write(Stream* s) @inline => s.fns.write_fn || s.fns.write_byte_fn; fn bool Stream.supports_write(Stream s) @inline => s.fns.write_fn || s.fns.write_byte_fn;
fn void! Stream.destroy(Stream* s) @inline @maydiscard fn void! Stream.destroy(Stream s) @inline @maydiscard
{ {
if (s.fns.destroy_fn) return s.fns.destroy_fn(s); if (s.fns.destroy_fn) return s.fns.destroy_fn(s);
return s.close(); return s.close();
} }
fn void! Stream.close(Stream* s) @inline @maydiscard fn void! Stream.close(Stream s) @inline @maydiscard
{ {
if (CloseStreamFn func = s.fns.close_fn) return func(s); if (CloseStreamFn func = s.fns.close_fn) return func(s);
} }
fn usz! Stream.seek(Stream* s, isz offset, Seek seek) @inline fn usz! Stream.seek(Stream s, isz offset, Seek seek) @inline
{ {
if (SeekStreamFn func = s.fns.seek_fn) return func(s, offset, seek); if (SeekStreamFn func = s.fns.seek_fn) return func(s, offset, seek);
return IoError.NOT_SEEKABLE?; return IoError.NOT_SEEKABLE?;
} }
fn usz! Stream.available(Stream* s) @inline fn usz! Stream.available(Stream s) @inline
{ {
if (AvailableStreamFn func = s.fns.available_fn) return func(s); if (AvailableStreamFn func = s.fns.available_fn) return func(s);
if (SeekStreamFn func = s.fns.seek_fn) if (SeekStreamFn func = s.fns.seek_fn)
@@ -76,7 +76,7 @@ fn usz! Stream.available(Stream* s) @inline
return IoError.NOT_SEEKABLE?; return IoError.NOT_SEEKABLE?;
} }
fn usz! Stream.read(Stream* s, char[] buffer) fn usz! Stream.read(Stream s, char[] buffer)
{ {
if (ReadStreamFn func = s.fns.read_fn) return func(s, buffer); if (ReadStreamFn func = s.fns.read_fn) return func(s, buffer);
if (ReadByteStreamFn func = s.fns.read_byte_fn) if (ReadByteStreamFn func = s.fns.read_byte_fn)
@@ -97,13 +97,40 @@ fn usz! Stream.read(Stream* s, char[] buffer)
return IoError.UNSUPPORTED_OPERATION?; return IoError.UNSUPPORTED_OPERATION?;
} }
fn char! Stream.read_byte(Stream* s) @inline fn char! Stream.read_byte(Stream s) @inline
{ {
if (ReadByteStreamFn func = s.fns.read_byte_fn) return func(s); if (ReadByteStreamFn func = s.fns.read_byte_fn) return func(s);
return IoError.UNSUPPORTED_OPERATION?; return IoError.UNSUPPORTED_OPERATION?;
} }
fn usz! Stream.write(Stream* s, char[] bytes) @inline fn String! Stream.readline(Stream s, Allocator* using = mem::heap())
{
ReadByteStreamFn func;
if (func = s.fns.read_byte_fn, !func) return IoError.UNSUPPORTED_OPERATION?;
bool read = false;
char val = func(s)!;
if (val == '\n') return "";
@stack_mem(256 + 64; Allocator* mem)
{
DString str = dstring::new_with_capacity(256, .using = mem);
if (val != '\r') str.append(val);
while (1)
{
char! c = func(s);
if (catch err = c)
{
if (err == IoError.EOF) break;
return err?;
}
if (c == '\r') continue;
if (c == '\n') break;
str.append_char(c);
}
return str.copy_str(using);
};
}
fn usz! Stream.write(Stream s, char[] bytes) @inline
{ {
if (WriteStreamFn func = s.fns.write_fn) return func(s, bytes); if (WriteStreamFn func = s.fns.write_fn) return func(s, bytes);
if (WriteByteStreamFn func = s.fns.write_byte_fn) if (WriteByteStreamFn func = s.fns.write_byte_fn)
@@ -114,31 +141,31 @@ fn usz! Stream.write(Stream* s, char[] bytes) @inline
return IoError.UNSUPPORTED_OPERATION?; return IoError.UNSUPPORTED_OPERATION?;
} }
fn void! Stream.write_byte(Stream* s, char b) @inline fn void! Stream.write_byte(Stream s, char b) @inline
{ {
if (WriteByteStreamFn func = s.fns.write_byte_fn) return func(s, b); if (WriteByteStreamFn func = s.fns.write_byte_fn) return func(s, b);
return IoError.UNSUPPORTED_OPERATION?; return IoError.UNSUPPORTED_OPERATION?;
} }
fn usz! Stream.write_to(Stream* s, Stream* to) @inline fn usz! Stream.write_to(Stream s, Stream to) @inline
{ {
if (WriteToStreamFn func = s.fns.write_stream_fn) return func(s, to); if (WriteToStreamFn func = s.fns.write_stream_fn) return func(s, to);
return IoError.UNSUPPORTED_OPERATION?; return IoError.UNSUPPORTED_OPERATION?;
} }
fn usz! Stream.read_from(Stream* s, Stream* from) @inline fn usz! Stream.read_from(Stream s, Stream from) @inline
{ {
if (ReadFromStreamFn func = s.fns.read_stream_fn) return func(s, from); if (ReadFromStreamFn func = s.fns.read_stream_fn) return func(s, from);
return IoError.UNSUPPORTED_OPERATION?; return IoError.UNSUPPORTED_OPERATION?;
} }
fn void! Stream.flush(Stream* s) @inline @maydiscard fn void! Stream.flush(Stream s) @inline @maydiscard
{ {
if (FlushStreamFn func = s.fns.flush_fn) return func(s); if (FlushStreamFn func = s.fns.flush_fn) return func(s);
return IoError.UNSUPPORTED_OPERATION?; return IoError.UNSUPPORTED_OPERATION?;
} }
fn usz! Stream.len(Stream* s) @inline fn usz! Stream.len(Stream s) @inline
{ {
if (LenStreamFn func = s.fns.len_fn) return func(s); if (LenStreamFn func = s.fns.len_fn) return func(s);
if (SeekStreamFn func = s.fns.seek_fn) if (SeekStreamFn func = s.fns.seek_fn)
@@ -151,7 +178,7 @@ fn usz! Stream.len(Stream* s) @inline
return IoError.NOT_SEEKABLE?; return IoError.NOT_SEEKABLE?;
} }
fn void! Stream.pushback_byte(Stream* s) @inline fn void! Stream.pushback_byte(Stream s) @inline
{ {
if (PushbackByteStreamFn func = s.fns.pushback_byte_fn) return func(s); if (PushbackByteStreamFn func = s.fns.pushback_byte_fn) return func(s);
if (SeekStreamFn func = s.fns.seek_fn) if (SeekStreamFn func = s.fns.seek_fn)
@@ -162,9 +189,9 @@ fn void! Stream.pushback_byte(Stream* s) @inline
return IoError.UNSUPPORTED_OPERATION?; return IoError.UNSUPPORTED_OPERATION?;
} }
fn void! Stream.write_string(Stream* s, String str) @inline => (void)(s.write((char[])str)!); fn void! Stream.write_string(Stream s, String str) @inline => (void)(s.write((char[])str)!);
fn usz! Stream.copy_to(Stream* s, Stream* dst, char[] buffer = {}) fn usz! Stream.copy_to(Stream s, Stream dst, char[] buffer = {})
{ {
if (buffer.len) return copy_through_buffer(s, dst, buffer); if (buffer.len) return copy_through_buffer(s, dst, buffer);
if (WriteToStreamFn func = s.fns.write_stream_fn) return func(s, dst); if (WriteToStreamFn func = s.fns.write_stream_fn) return func(s, dst);
@@ -186,7 +213,7 @@ fn usz! Stream.copy_to(Stream* s, Stream* dst, char[] buffer = {})
$endswitch $endswitch
} }
macro usz! copy_through_buffer(Stream* s, Stream* dst, char[] buffer) @local macro usz! copy_through_buffer(Stream s, Stream dst, char[] buffer) @local
{ {
usz total_copied; usz total_copied;
while (true) while (true)

View File

@@ -53,7 +53,7 @@ fn usz! ByteReader.seek(ByteReader* reader, isz offset, Seek seek)
return new_index; return new_index;
} }
fn usz! ByteReader.write_stream(ByteReader* reader, Stream* writer) fn usz! ByteReader.write_stream(ByteReader* reader, Stream writer)
{ {
if (reader.index >= reader.bytes.len) return 0; if (reader.index >= reader.bytes.len) return 0;
usz written = writer.write(reader.bytes[reader.index..])!; usz written = writer.write(reader.bytes[reader.index..])!;

View File

@@ -75,9 +75,9 @@ fn void! ByteWriter.write_byte(ByteWriter* writer, char c)
/** /**
* @param [&inout] writer * @param [&inout] writer
* @param [&inout] reader * @param reader
**/ **/
fn usz! ByteWriter.read_from(ByteWriter* writer, Stream* reader) fn usz! ByteWriter.read_from(ByteWriter* writer, Stream reader)
{ {
usz start_index = writer.index; usz start_index = writer.index;
if (reader.supports_available()) if (reader.supports_available())

View File

@@ -32,6 +32,7 @@ def spawn = posix_spawn;
extern fn CInt kill(Pid_t pid, CInt sig); extern fn CInt kill(Pid_t pid, CInt sig);
extern fn Pid_t waitpid(Pid_t pid, CInt* stat_loc, int options); extern fn Pid_t waitpid(Pid_t pid, CInt* stat_loc, int options);
extern fn CInt raise(CInt sig);
macro CInt wEXITSTATUS(CInt status) => (status & 0xff00) >> 8; macro CInt wEXITSTATUS(CInt status) => (status & 0xff00) >> 8;
macro CInt wTERMSIG(CInt status) => status & 0x7f; macro CInt wTERMSIG(CInt status) => status & 0x7f;

View File

@@ -88,6 +88,7 @@
- `assert` may now take varargs for formatting. - `assert` may now take varargs for formatting.
### Stdlib changes ### Stdlib changes
- `csv` package.
- Updated posix/win32 stdlib namespacing - Updated posix/win32 stdlib namespacing
- `process` stdlib - `process` stdlib
- Stdlib updates to string. - Stdlib updates to string.

View File

@@ -1 +1 @@
#define COMPILER_VERSION "0.4.543" #define COMPILER_VERSION "0.4.544"

View File

@@ -17,9 +17,9 @@ fn void! bytestream()
ws.write("helloworld")!; ws.write("helloworld")!;
assert(w.as_str() == "helloworld"); assert(w.as_str() == "helloworld");
s.seek(0, SET)!; s.seek(0, SET)!;
ws.read_from(&s)!; ws.read_from(s)!;
s.seek(1, SET)!; s.seek(1, SET)!;
s.write_to(&ws)!; s.write_to(ws)!;
assert(w.as_str() == "helloworldabcbc"); assert(w.as_str() == "helloworldabcbc");
} }
@@ -44,7 +44,7 @@ fn void! bytewriter_read_from()
ByteWriter bw; ByteWriter bw;
bw.tinit(); bw.tinit();
bw.read_from(&s)!; bw.read_from(s)!;
assert(bw.as_str() == data); assert(bw.as_str() == data);
} }

View File

@@ -11,7 +11,7 @@ fn void! test_writing()
ByteReader r; ByteReader r;
String test_str = "2134"; String test_str = "2134";
r.init(test_str); r.init(test_str);
s.read_from(&&r.as_stream())!; s.read_from(r.as_stream())!;
String o = foo.str(); String o = foo.str();
assert(o == "hello-what?2134"); assert(o == "hello-what?2134");
} }