hare

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

commit c953c01492a7be3bb1887f8e4ad94ddbc55eb2d8
parent 5f07cb9ab596705a42fba176e8183e42272fb42e
Author: Bor Grošelj Simić <bor.groseljsimic@telemach.net>
Date:   Tue, 26 Oct 2021 19:18:38 +0200

fs::mem: utilize subtyping

Signed-off-by: Bor Grošelj Simić <bor.groseljsimic@telemach.net>

Diffstat:
Mfs/mem/mem.ha | 58+++++++++++++++++++++++++++++++---------------------------
Mfs/mem/stream.ha | 17+++++++----------
2 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/fs/mem/mem.ha b/fs/mem/mem.ha @@ -17,7 +17,7 @@ type directory = struct { type file = []u8; type inode = struct { - fs: fs::fs, + fs::fs, data: (directory | file), name: str, hash: u64, @@ -27,28 +27,12 @@ type inode = struct { }; type iterator = struct { - it: fs::iterator, + fs::iterator, parent: *inode, curr: nullable *inode, idx: size, }; -const inode_iface: fs::fs = fs::fs { - close = &close, - create = &create, - iter = &iter, - mkdir = &mkdir, - mksubdir = &mksubdir, - open = &open, - remove = &remove, - rmdir = &rmdir, - stat = &stat, - subdir = &subdir, - ... -}; - -const fs_iter: fs::iterator = fs::iterator { next = &next, }; - const supported_flags: fs::flags = ( fs::flags::RDONLY | fs::flags::WRONLY | @@ -60,12 +44,22 @@ const supported_flags: fs::flags = ( // number of handles to the same directory simultaneously are allowed. Supports // any number of readers or one writer at the same time on a file. export fn memopen() *fs::fs = alloc(inode { - fs = inode_iface, + close = &close, + create = &create, + iter = &iter, + mkdir = &mkdir, + mksubdir = &mksubdir, + open = &open, + remove = &remove, + rmdir = &rmdir, + stat = &stat, + subdir = &subdir, + data = empty_dir(), name = "", opencount = 1, parent = null, -}): *fs::fs; +}); fn file_flags(flags: fs::flags...) ((io::mode, bool) | fs::error) = { let fl: fs::flags = 0; @@ -164,7 +158,17 @@ fn mksubdir(fs: *fs::fs, path: str) (*fs::fs | fs::error) = { }; let name = strings::dup(path::basename(path)); let ino = alloc(inode { - fs = inode_iface, + close = &close, + create = &create, + iter = &iter, + mkdir = &mkdir, + mksubdir = &mksubdir, + open = &open, + remove = &remove, + rmdir = &rmdir, + stat = &stat, + subdir = &subdir, + data = empty_dir(), name = name, hash = hash_of(name), @@ -172,7 +176,7 @@ fn mksubdir(fs: *fs::fs, path: str) (*fs::fs | fs::error) = { parent = parent, }); inode_insert(parent, ino); - return ino: *fs::fs; + return ino; }; fn subdir(fs: *fs::fs, path: str) (*fs::fs | fs::error) = { @@ -181,7 +185,7 @@ fn subdir(fs: *fs::fs, path: str) (*fs::fs | fs::error) = { return fs::wrongtype; }; ino.opencount += 1; - return ino: *fs::fs; + return ino; }; fn iter(fs: *fs::fs, path: str) (*fs::iterator | fs::error) = { @@ -191,11 +195,11 @@ fn iter(fs: *fs::fs, path: str) (*fs::iterator | fs::error) = { }; let p = ino.data: directory; return alloc(iterator { - it = fs::iterator { next = &next, }, + next = &next, parent = ino, idx = 0, curr = p.ents[0], - }): *fs::iterator; + }); }; fn next(iter: *fs::iterator) (fs::dirent | void) = { @@ -269,8 +273,8 @@ fn close_rec(ino: *inode) void = { if (ino.opencount != 0 || ino.parent != null) { return; }; - let it = iterator { it = fs_iter, parent = ino, ... }; - for (true) match (_next(&it: *fs::iterator)) { + let it = iterator { next = &next, parent = ino, ... }; + for (true) match (_next(&it)) { case null => break; case ino: *inode => diff --git a/fs/mem/stream.ha b/fs/mem/stream.ha @@ -5,7 +5,7 @@ use io; use types; type stream = struct { - stream: io::stream, + io::stream, source: *io::stream, inode: *inode, appnd: bool, @@ -18,25 +18,22 @@ fn stream_open( ) (*io::stream | fs::error) = { let f = ino.data as file; let s = alloc(stream { - stream = io::stream { - closer = &stream_close, - seeker = &seek, - ... - }, + closer = &stream_close, + seeker = &seek, inode = ino, appnd = appnd, ... }); if (mode & io::mode::WRITE == 0) { assert(mode & io::mode::READ == io::mode::READ); - s.stream.reader = &read; + s.reader = &read; if (ino.opencount == types::SIZE_MAX) { return errors::busy; }; ino.opencount += 1; s.source = bufio::fixed(f, io::mode::READ); } else { - s.stream.writer = &write; + s.writer = &write; if (ino.opencount != 0) { return errors::busy; }; @@ -47,7 +44,7 @@ fn stream_open( }; }; io::seek(s.source, 0, io::whence::SET)?; - return &s.stream; + return s; }; fn read(s: *io::stream, buf: []u8) (size | io::EOF | io::error) = { @@ -71,7 +68,7 @@ fn seek(s: *io::stream, off: io::off, w: io::whence) (io::off | io::error) = { fn stream_close(s: *io::stream) void = { let s = s: *stream; defer free(s); - if (s.stream.writer == null) { + if (s.writer == null) { io::close(s.source); s.inode.opencount -= 1; if (s.inode.opencount > 0) {