improvements to WASI files; '--print-function-mappings' flag
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 21 Jan 2021 19:45:10 +0000 (13:45 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 21 Jan 2021 19:45:10 +0000 (13:45 -0600)
bin/onyx
core/file.onyx
core/io/io.onyx
core/io/reader.onyx
core/io/stream.onyx
include/onyxastnodes.h
misc/onyx.sublime-syntax
onyx.exe
src/onyx.c
src/onyxtypes.c
src/onyxwasm.c

index ddc44fd8d5c55fcc87e23c84ddb3168cccd57be6..310ed167d837aa61ca3c97cc093b76e0515fd643 100755 (executable)
Binary files a/bin/onyx and b/bin/onyx differ
index ea5be3c827f7b032ea95b68ef86232070e1d71ef..7515dc95dc4e31dc2c1ca8393bda880105d49cd3 100644 (file)
@@ -1,37 +1,35 @@
-package core.file
-
-// Many of these functions will be improved when
-// multiple return values are implemented.
-
+package core.io
 
 use package core
-use package wasi
+use package wasi as wasi
+use package wasi {
+    FileDescriptor,
+    FDFlags, OFlags, Rights,
+    LookupFlags, Errno,
+    IOVec, IOVecArray, Size,
+    FileStat, Whence
+}
 
 OpenMode :: enum {
+    Invalid;
     Read;
     Write;
     Append;
 }
 
 File :: struct {
-    fd : FileDescriptor;
+    fd     : FileDescriptor;
+
+    mode   : OpenMode = OpenMode.Invalid;
+    rights : Rights   = ~~ 0;
+    flags  : FDFlags  = ~~ 0;
 }
 
-open :: proc (file: ^File, path: str, mode := OpenMode.Read, flags := FDFlags.Sync) -> bool {
+file_open :: (path: str, mode := OpenMode.Read, flags := FDFlags.Sync) -> (File, bool) {
     // Currently the directory's file descriptor appears to always be 3
     DIR_FD :: 3;
 
-    open_flags := cast(OFlags) 0;
-    // rights := Rights.DataSync
-    //         | Rights.Sync
-    //         | Rights.FilestatGet
-    //         | Rights.FilestatSetSize
-    //         | Rights.FilestatSetTimes
-    //         | Rights.Advise
-    //         | Rights.Allocate
-    //         | Rights.PathOpen
-    //         | Rights.PathCreateFile;
-            
+    // Requesting all of the rights because why not.
     rights :=
         Rights.DataSync
         | Rights.Read
@@ -62,7 +60,8 @@ open :: proc (file: ^File, path: str, mode := OpenMode.Read, flags := FDFlags.Sy
         | Rights.PathUnlinkFile
         | Rights.PollFDReadWrite;
 
-    fdflags := flags;
+    open_flags := cast(OFlags) 0;
+    fd_flags := flags;
 
     switch mode {
         case OpenMode.Write {
@@ -73,7 +72,7 @@ open :: proc (file: ^File, path: str, mode := OpenMode.Read, flags := FDFlags.Sy
         case OpenMode.Append {
             open_flags |= OFlags.Creat;
             rights     |= Rights.Write;
-            fdflags    |= FDFlags.Append;
+            fd_flags   |= FDFlags.Append;
         }
 
         case OpenMode.Read {
@@ -81,60 +80,65 @@ open :: proc (file: ^File, path: str, mode := OpenMode.Read, flags := FDFlags.Sy
         }
     }
 
-    if err := path_open(
+    file := File.{ fd = -1 };
+
+    if err := wasi.path_open(
         DIR_FD,
         LookupFlags.SymLinkFollow,
         path,
         open_flags,
         rights,
         rights,
-        fdflags,
+        fd_flags,
         ^file.fd);
         err != Errno.Success {
-        return false;
+        return file, false;
     }
 
-    return true;
+    file.mode   = mode;
+    file.rights = rights;
+    file.flags  = fd_flags;
+    return file, true;
 }
 
-close :: proc (file: File) -> bool {
-    if fd_close(file.fd) != Errno.Success {
+file_close :: (file: File) -> bool {
+    if wasi.fd_close(file.fd) != Errno.Success {
         return false;
     }
 
     return true;
 }
 
-write :: proc (file: File, data: str) {
+file_write :: (file: File, data: str) {
     vec := IOVec.{ buf = cast(u32) data.data, len = data.count };
     tmp : Size;
-    fd_write(file.fd, IOVecArray.{ cast(u32) ^vec, 1 }, ^tmp);
-    fd_datasync(file.fd);
+    wasi.fd_write(file.fd, IOVecArray.{ cast(u32) ^vec, 1 }, ^tmp);
+    wasi.fd_datasync(file.fd);
 }
 
-get_size :: proc (file: File) -> u64 {
+get_size :: (file: File) -> u64 {
     fs: FileStat;
-    if fd_filestat_get(file.fd, ^fs) != Errno.Success do return 0;
+    if wasi.fd_filestat_get(file.fd, ^fs) != Errno.Success do return 0;
 
     return fs.size;
 }
 
-get_contents_from_file :: proc (file: File) -> str {
+get_contents_from_file :: (file: File) -> str {
     size := cast(u32) get_size(file);
 
     data := cast(^u8) raw_alloc(context.allocator, size);
 
     prev_loc: i64;
-    fd_tell(file.fd, ^prev_loc);
+    wasi.fd_tell(file.fd, ^prev_loc);
 
     dummy: i64;
-    fd_seek(file.fd, 0, Whence.Set, ^dummy);
+    wasi.fd_seek(file.fd, 0, Whence.Set, ^dummy);
 
     dummy2: u32;
     buf := IOVec.{ cast(u32) data, size };
-    fd_pread(file.fd, IOVecArray.{ cast(u32) ^buf, 1 }, 0, ^dummy2);
+    wasi.fd_pread(file.fd, IOVecArray.{ cast(u32) ^buf, 1 }, 0, ^dummy2);
 
-    fd_seek(file.fd, prev_loc, Whence.Set, ^dummy);
+    wasi.fd_seek(file.fd, prev_loc, Whence.Set, ^dummy);
 
     return data[0 .. size];
 }
@@ -143,11 +147,130 @@ get_contents :: proc {
     get_contents_from_file,
 
     proc (path: str) -> str {
-        tmp_file: File;
-
-        if !open(^tmp_file, path, OpenMode.Read) do return str.{ null, 0 };
-        defer close(tmp_file);
+        tmp_file, success := file_open(path, OpenMode.Read);
+        if !success do return str.{ null, 0 };
+        defer file_close(tmp_file);
 
         return get_contents(tmp_file);
     }
 }
+
+FileStream :: struct {
+    use stream : Stream;
+    use file   : File;
+}
+
+open :: (path: str, mode := OpenMode.Read) -> (Error, FileStream) {
+    fs := FileStream.{
+        stream = Stream.{ vtable = null },
+        file   = File.{ fd = -1 },
+    };
+
+    file, success := file_open(path, mode);
+    if !success do return Error.NotFound, fs;
+
+    fs.file = file;
+    fs.vtable = ^file_stream_vtable;
+    return Error.None, fs;
+}
+
+#private
+file_stream_vtable := Stream_Vtable.{
+    seek = (use fs: ^FileStream, to: i32, whence: SeekFrom) -> Error {
+        // Currently, the new offset is just ignored.
+        newoffset : wasi.Filesize;
+        error := wasi.fd_seek(file.fd, ~~ to, ~~ whence, ^newoffset);
+        if error != Errno.Success do return Error.BadFile;
+
+        return Error.None;
+    },
+
+    tell = (use fs: ^FileStream) -> (Error, u32) {
+        location : wasi.Filesize;
+        error := wasi.fd_tell(file.fd, ^location);
+        if error != Errno.Success do return Error.BadFile, 0;
+
+        return Error.None, ~~location;
+    },
+
+    read = (use fs: ^FileStream, buffer: [] u8) -> (Error, u32) {
+        bytes_read : wasi.Size;
+        vec   := IOVec.{ buf = cast(u32) buffer.data, len = buffer.count };
+        error := wasi.fd_read(file.fd, IOVecArray.{ cast(u32) ^vec, 1 }, ^bytes_read);
+        if error != Errno.Success do return Error.BadFile, 0;
+
+        return Error.None, bytes_read;
+    },
+
+    read_at = (use fs: ^FileStream, at: u32, buffer: [] u8) -> (Error, u32) {
+        bytes_read : wasi.Size;
+        vec   := IOVec.{ buf = cast(u32) buffer.data, len = buffer.count };
+        error := wasi.fd_pread(file.fd, IOVecArray.{ cast(u32) ^vec, 1 }, ~~at, ^bytes_read);
+
+        // FIX: Maybe report Error.OutOfBounds if the 'at' was out of bounds?
+        if error != Errno.Success do return Error.BadFile, 0;
+
+        return Error.None, bytes_read;
+    },
+
+    read_byte = (use fs: ^FileStream) -> (Error, u8) {
+        bytes_read : wasi.Size;
+        byte  : u8;
+        vec   := IOVec.{ buf = cast(u32) ^byte, len = 1};
+        error := wasi.fd_read(file.fd, IOVecArray.{ cast(u32) ^vec, 1 }, ^bytes_read);
+        if error != Errno.Success do return Error.BadFile, 0;
+
+        return Error.None, byte;
+    },
+
+    unread_byte = (use fs: ^FileStream) -> Error {
+        return Error.NotImplemented;
+    },
+
+    write = (use fs: ^FileStream, buffer: [] u8) -> (Error, u32) {
+        bytes_written : wasi.Size;
+        vec   := IOVec.{ buf = cast(u32) buffer.data, len = buffer.count };
+        error := wasi.fd_write(file.fd, IOVecArray.{ cast(u32) ^vec, 1 }, ^bytes_written);
+        if error != Errno.Success do return Error.BadFile, 0;
+
+        return Error.None, bytes_written;
+    },
+
+    write_at = (use fs: ^FileStream, at: u32, buffer: [] u8) -> (Error, u32) {
+        bytes_written : wasi.Size;
+        vec   := IOVec.{ buf = cast(u32) buffer.data, len = buffer.count };
+        error := wasi.fd_pwrite(file.fd, IOVecArray.{ cast(u32) ^vec, 1 }, ~~at, ^bytes_written);
+
+        // FIX: Maybe report Error.OutOfBounds if the 'at' was out of bounds?
+        if error != Errno.Success do return Error.BadFile, 0;
+
+        return Error.None, bytes_written;
+    },
+
+    write_byte = (use fs: ^FileStream, byte: u8) -> Error {
+        bytes_written : wasi.Size;
+        byte_to_write := byte;
+        vec   := IOVec.{ buf = cast(u32) ^byte_to_write, len = 1 };
+        error := wasi.fd_write(file.fd, IOVecArray.{ cast(u32) ^vec, 1 }, ^bytes_written);
+        if error != Errno.Success do return Error.BadFile;
+
+        return Error.None;
+    },
+
+    close = (use fs: ^FileStream) -> Error {
+        file_close(file);
+        return Error.None;
+    },
+
+    flush = (use fs: ^FileStream) -> Error {
+        wasi.fd_datasync(file.fd);
+        return Error.None;
+    },
+
+    size = (use fs: ^FileStream) -> i32 {
+        file_stat: FileStat;
+        if wasi.fd_filestat_get(file.fd, ^file_stat) != Errno.Success do return 0;
+
+        return ~~ file_stat.size;
+    },
+}
index 718e5f52c9c9fbd6c2b2de8e4e944f564f4b97ae..a43d3cac2da5448cf5dce3e78460e97fbcbed808 100644 (file)
@@ -14,4 +14,10 @@ Error :: enum {
 
     // A seek was outside the bounds of the stream.
     OutOfBounds    :: 0x04;
+
+    // The file or stream was not found.
+    NotFound       :: 0x05;
+
+    // The file or stream was not initialized correctly.
+    BadFile        :: 0x06;
 }
\ No newline at end of file
index 14508eb590014b8805401485950aa9785a26c1cd..a0f037cfac6b25831d56804ae246d1534bc40b4d 100644 (file)
@@ -49,8 +49,7 @@ read_u64 :: proc (use reader: ^Reader) -> u64 {
 }
 
 read_line :: proc (use reader: ^Reader, allocator := context.allocator) -> str {
-    curr_pos : i32;
-    stream_tell(stream, ^curr_pos);
+    _, curr_pos := stream_tell(stream);
 
     count := 0;
     err, curr := stream_read_byte(stream);
@@ -75,8 +74,7 @@ read_line :: proc (use reader: ^Reader, allocator := context.allocator) -> str {
 read_word :: proc (use reader: ^Reader, allocator := context.allocator) -> str {
     skip_whitespace(reader);
 
-    curr_pos : i32;
-    stream_tell(stream, ^curr_pos);
+    _, curr_pos := stream_tell(stream);
 
     count := 0;
     err, curr := stream_read_byte(stream);
index d6abe0c80669afc0746541f10da8c7f552c06b1a..0faed374d05ab20d312ab23858bd54d0b775851e 100644 (file)
@@ -9,7 +9,7 @@ Stream :: struct {
 #private
 Stream_Vtable :: struct {
     seek         : proc (s: ^Stream, to: i32, whence: SeekFrom) -> Error;
-    tell         : proc (s: ^Stream, out: ^i32) -> Error;
+    tell         : proc (s: ^Stream) -> (Error, u32);
 
     read         : proc (s: ^Stream, buffer: [] u8) -> (Error, u32);
     read_at      : proc (s: ^Stream, at: u32, buffer: [] u8) -> (Error, u32);
@@ -32,91 +32,91 @@ SeekFrom :: enum {
     End     :: 0x02;    
 }
 
-stream_seek :: proc (use s: ^Stream, to: i32, whence: SeekFrom) -> Error {
+stream_seek :: (use s: ^Stream, to: i32, whence: SeekFrom) -> Error {
     if vtable == null do return Error.NoVtable;
     if vtable.seek == null_proc do return Error.NotImplemented;
 
     return vtable.seek(s, to, whence);
 }
 
-stream_tell :: proc (use s: ^Stream, out: ^i32) -> Error {
-    if vtable == null do return Error.NoVtable;
-    if vtable.tell == null_proc do return Error.NotImplemented;
+stream_tell :: (use s: ^Stream) -> (Error, u32) {
+    if vtable == null do return Error.NoVtable, 0;
+    if vtable.tell == null_proc do return Error.NotImplemented, 0;
     
-    return vtable.tell(s, out);
+    return vtable.tell(s);
 }
 
-stream_read :: proc (use s: ^Stream, buffer: [] u8) -> (Error, u32) {
+stream_read :: (use s: ^Stream, buffer: [] u8) -> (Error, u32) {
     if vtable == null do return Error.NoVtable, 0;
     if vtable.read == null_proc do return Error.NotImplemented, 0;
     
     return vtable.read(s, buffer);
 }
 
-stream_read_at :: proc (use s: ^Stream, at: u32, buffer: [] u8) -> (Error, u32) {
+stream_read_at :: (use s: ^Stream, at: u32, buffer: [] u8) -> (Error, u32) {
     if vtable == null do return Error.NoVtable, 0;
     if vtable.read_at == null_proc do return Error.NotImplemented, 0;
     
     return vtable.read_at(s, at, buffer);
 }
 
-stream_read_byte :: proc (use s: ^Stream) -> (Error, u8) {
+stream_read_byte :: (use s: ^Stream) -> (Error, u8) {
     if vtable == null do return Error.NoVtable, cast(u8) 0;
     if vtable.read_byte == null_proc do return Error.NotImplemented, 0;
     
     return vtable.read_byte(s);
 }
 
-stream_unread_byte :: proc (use s: ^Stream) -> Error {
+stream_unread_byte :: (use s: ^Stream) -> Error {
     if vtable == null do return Error.NoVtable;
     if vtable.unread_byte == null_proc do return Error.NotImplemented;
     
     return vtable.unread_byte(s);
 }
 
-stream_write :: proc (use s: ^Stream, buffer: [] u8) -> (Error, u32) {
+stream_write :: (use s: ^Stream, buffer: [] u8) -> (Error, u32) {
     if vtable == null do return Error.NoVtable, 0;
     if vtable.write == null_proc do return Error.NotImplemented, 0;
     
     return vtable.write(s, buffer);
 }
 
-stream_write_at :: proc (use s: ^Stream, at: u32, buffer: [] u8) -> (Error, u32) {
+stream_write_at :: (use s: ^Stream, at: u32, buffer: [] u8) -> (Error, u32) {
     if vtable == null do return Error.NoVtable, 0;
     if vtable.write_at == null_proc do return Error.NotImplemented, 0;
     
     return vtable.write_at(s, at, buffer);
 }
 
-stream_write_byte :: proc (use s: ^Stream, byte: u8) -> Error {
+stream_write_byte :: (use s: ^Stream, byte: u8) -> Error {
     if vtable == null do return Error.NoVtable;
     if vtable.write_byte == null_proc do return Error.NotImplemented;
     
     return vtable.write_byte(s, byte);
 }
 
-stream_close :: proc (use s: ^Stream) -> Error {
+stream_close :: (use s: ^Stream) -> Error {
     if vtable == null do return Error.NoVtable;
     if vtable.close == null_proc do return Error.NotImplemented;
 
     return vtable.close(s);
 }
 
-stream_flush :: proc (use s: ^Stream) -> Error {
+stream_flush :: (use s: ^Stream) -> Error {
     if vtable == null do return Error.NoVtable;
     if vtable.flush == null_proc do return Error.NotImplemented;
 
     return vtable.flush(s);
 }
 
-stream_size :: proc (use s: ^Stream) -> i32 {
+stream_size :: (use s: ^Stream) -> i32 {
     if vtable == null do return 0;
     if vtable.size == null_proc do return 0;
 
     return vtable.size(s);
 }
 
-stream_peek_byte :: proc (use s: ^Stream) -> (Error, u8) {
+stream_peek_byte :: (use s: ^Stream) -> (Error, u8) {
     err, out := stream_read_byte(s);
     if err != Error.None do return err, 0;
 
@@ -138,7 +138,7 @@ StringStream :: struct {
     data : str;
 }
 
-string_stream_make :: proc (s: str) -> StringStream {
+string_stream_make :: (s: str) -> StringStream {
     return StringStream.{
         stream = Stream.{
             vtable   = ^string_stream_vtable,
@@ -151,10 +151,7 @@ string_stream_make :: proc (s: str) -> StringStream {
 
 #private
 string_stream_vtable := Stream_Vtable.{
-    seek = proc (s: ^Stream, to: i32, whence: SeekFrom) -> Error {
-        ss : ^StringStream = ~~s;
-        use ss;
-
+    seek = (use ss: ^StringStream, to: i32, whence: SeekFrom) -> Error {
         if to >= data.count do return Error.OutOfBounds;
 
         switch whence {
@@ -166,18 +163,11 @@ string_stream_vtable := Stream_Vtable.{
         return Error.None;
     },
 
-    tell = proc (s: ^Stream, out: ^i32) -> Error {
-        ss : ^StringStream = ~~s;
-        use ss;
-
-        if out != null do *out = curr_pos;
-        return Error.None;
+    tell = (use ss: ^StringStream) -> (Error, u32) {
+        return Error.None, curr_pos;
     },
 
-    read = proc (s: ^Stream, buffer: [] u8) -> (Error, u32) {
-        ss : ^StringStream = ~~s;
-        use ss;
-
+    read = (use ss: ^StringStream, buffer: [] u8) -> (Error, u32) {
         if curr_pos >= data.count do return Error.EOF, 0;
 
         bytes_to_read := math.min(buffer.count, data.count - curr_pos);
@@ -187,10 +177,7 @@ string_stream_vtable := Stream_Vtable.{
         return Error.None, bytes_to_read;
     },
 
-    read_at = proc (s: ^Stream, at: u32, buffer: [] u8) -> (Error, u32) {
-        ss : ^StringStream = ~~s;
-        use ss;
-
+    read_at = (use ss: ^StringStream, at: u32, buffer: [] u8) -> (Error, u32) {
         if at >= data.count do return Error.EOF, 0;
 
         bytes_to_read := math.min(buffer.count, data.count - at);
@@ -199,30 +186,21 @@ string_stream_vtable := Stream_Vtable.{
         return Error.None, bytes_to_read;
     },
 
-    read_byte = proc (s: ^Stream) -> (Error, u8) {
-        ss : ^StringStream = ~~s;
-        use ss;
-
+    read_byte = (use ss: ^StringStream) -> (Error, u8) {
         if curr_pos >= data.count do return Error.EOF, 0;
 
         defer curr_pos += 1;
         return Error.None, data[curr_pos];
     },
 
-    unread_byte = proc (s: ^Stream) -> Error {
-        ss : ^StringStream = ~~s;
-        use ss;
-
+    unread_byte = (use ss: ^StringStream) -> Error {
         if curr_pos <= 0 do return Error.OutOfBounds;
 
         curr_pos -= 1;
         return Error.None;
     },
 
-    write = proc (s: ^Stream, buffer: [] u8) -> (Error, u32) {
-        ss : ^StringStream = ~~s;
-        use ss;
-
+    write = (use ss: ^StringStream, buffer: [] u8) -> (Error, u32) {
         if curr_pos >= data.count do return Error.EOF, 0;
 
         bytes_to_write := math.min(buffer.count, data.count - curr_pos);
@@ -232,10 +210,7 @@ string_stream_vtable := Stream_Vtable.{
         return Error.None, bytes_to_write;
     },
 
-    write_at = proc (s: ^Stream, at: u32, buffer: [] u8) -> (Error, u32) {
-        ss : ^StringStream = ~~s;
-        use ss;
-
+    write_at = (use ss: ^StringStream, at: u32, buffer: [] u8) -> (Error, u32) {
         if at >= data.count do return Error.EOF, 0;
 
         bytes_to_write := math.min(buffer.count, data.count - at);
@@ -244,10 +219,7 @@ string_stream_vtable := Stream_Vtable.{
         return Error.None, bytes_to_write;
     },
 
-    write_byte = proc (s: ^Stream, byte: u8) -> Error {
-        ss : ^StringStream = ~~s;
-        use ss;
-
+    write_byte = (use ss: ^StringStream, byte: u8) -> Error {
         if curr_pos >= data.count do return Error.EOF;
 
         data[curr_pos] = byte;
@@ -256,10 +228,7 @@ string_stream_vtable := Stream_Vtable.{
         return Error.None;
     },
 
-    size = proc (s: ^Stream) -> i32 {
-        ss : ^StringStream = ~~s;
-        use ss;
-
+    size = (use ss: ^StringStream) -> i32 {
         return data.count;
     },
 
@@ -279,7 +248,7 @@ DynamicStringStream :: struct {
     alloc : Allocator;
 }
 
-dynamic_string_stream_make :: proc (init_size := 128, a := context.allocator) -> DynamicStringStream {
+dynamic_string_stream_make :: (init_size := 128, a := context.allocator) -> DynamicStringStream {
     data : [..] u8;
     array.init(^data, init_size);
 
@@ -294,16 +263,13 @@ dynamic_string_stream_make :: proc (init_size := 128, a := context.allocator) ->
     };
 }
 
-dynamic_string_stream_to_str :: proc (use dds: ^DynamicStringStream) -> str {
+dynamic_string_stream_to_str :: (use dds: ^DynamicStringStream) -> str {
     return data.data[0 .. curr_pos];
 }
 
 #private
 dynamic_string_stream_vtable := Stream_Vtable.{
-    seek = proc (s: ^Stream, to: i32, whence: SeekFrom) -> Error {
-        dss : ^DynamicStringStream = ~~s;
-        use dss;
-
+    seek = (use dss: ^DynamicStringStream, to: i32, whence: SeekFrom) -> Error {
         dest : i32;
         switch whence {
             case SeekFrom.Start   do dest = to;
@@ -322,18 +288,11 @@ dynamic_string_stream_vtable := Stream_Vtable.{
         return Error.None;
     },
 
-    tell = proc (s: ^Stream, out: ^i32) -> Error {
-        dss : ^DynamicStringStream = ~~s;
-        use dss;
-
-        if out != null do *out = curr_pos;
-        return Error.None;
+    tell = (use dss: ^DynamicStringStream) -> (Error, u32) {
+        return Error.None, curr_pos;
     },
 
-    read = proc (s: ^Stream, buffer: [] u8) -> (Error, u32) {
-        dss : ^DynamicStringStream = ~~s;
-        use dss;
-
+    read = (use dss: ^DynamicStringStream, buffer: [] u8) -> (Error, u32) {
         if curr_pos >= data.count do return Error.EOF, 0;
 
         bytes_to_read := math.min(buffer.count, data.count - curr_pos);
@@ -343,10 +302,7 @@ dynamic_string_stream_vtable := Stream_Vtable.{
         return Error.None, bytes_to_read;
     },
 
-    read_at = proc (s: ^Stream, at: u32, buffer: [] u8) -> (Error, u32) {
-        dss : ^DynamicStringStream = ~~s;
-        use dss;
-
+    read_at = (use dss: ^DynamicStringStream, at: u32, buffer: [] u8) -> (Error, u32) {
         if at >= data.count do return Error.EOF, 0;
 
         bytes_to_read := math.min(buffer.count, data.count - at);
@@ -355,30 +311,21 @@ dynamic_string_stream_vtable := Stream_Vtable.{
         return Error.None, bytes_to_read;
     },
 
-    read_byte = proc (s: ^Stream) -> (Error, u8) {
-        dss : ^DynamicStringStream = ~~s;
-        use dss;
-
+    read_byte = (use dss: ^DynamicStringStream) -> (Error, u8) {
         if curr_pos >= data.count do return Error.EOF, 0;
 
         defer curr_pos += 1;
         return Error.None, data[curr_pos];
     },
 
-    unread_byte = proc (s: ^Stream) -> Error {
-        dss : ^DynamicStringStream = ~~s;
-        use dss;
-
+    unread_byte = (use dss: ^DynamicStringStream) -> Error {
         if curr_pos <= 0 do return Error.OutOfBounds;
 
         curr_pos -= 1;
         return Error.None;
     },
 
-    write = proc (s: ^Stream, buffer: [] u8) -> (Error, u32) {
-        dss : ^DynamicStringStream = ~~s;
-        use dss;
-
+    write = (use dss: ^DynamicStringStream, buffer: [] u8) -> (Error, u32) {
         if curr_pos + buffer.count >= data.capacity {
             #context_scope {
                 context.allocator = alloc;
@@ -393,10 +340,7 @@ dynamic_string_stream_vtable := Stream_Vtable.{
         return Error.None, buffer.count;
     },
 
-    write_at = proc (s: ^Stream, at: u32, buffer: [] u8) -> (Error, u32) {
-        dss : ^DynamicStringStream = ~~s;
-        use dss;
-
+    write_at = (use dss: ^DynamicStringStream, at: u32, buffer: [] u8) -> (Error, u32) {
         if at + buffer.count >= data.capacity {
             #context_scope {
                 context.allocator = alloc;
@@ -410,10 +354,7 @@ dynamic_string_stream_vtable := Stream_Vtable.{
         return Error.None, buffer.count;
     },
 
-    write_byte = proc (s: ^Stream, byte: u8) -> Error {
-        dss : ^DynamicStringStream = ~~s;
-        use dss;
-
+    write_byte = (use dss: ^DynamicStringStream, byte: u8) -> Error {
         #context_scope {
             context.allocator = alloc;
             if !array.ensure_capacity(^data, data.count + 1) do return Error.EOF;
@@ -426,17 +367,11 @@ dynamic_string_stream_vtable := Stream_Vtable.{
         return Error.None;
     },
 
-    size = proc (s: ^Stream) -> i32 {
-        dss : ^DynamicStringStream = ~~s;
-        use dss;
-
+    size = (use dss: ^DynamicStringStream) -> i32 {
         return data.count;
     },
 
-    flush = proc (s: ^Stream) -> Error {
-        dss : ^DynamicStringStream = ~~s;
-        use dss;
-
+    flush = (use dss: ^DynamicStringStream) -> Error {
         curr_pos = 0;
         array.clear(^data);
 
index 06664d9ecc8228c21fd28347823818a92bc7e9cd..7f19f85c53fe413203df212a6f57ebfe0b681ef6 100644 (file)
@@ -952,8 +952,9 @@ struct CompileOptions {
     bh_allocator allocator;
     CompileAction action;
 
-    u32 verbose_output : 31;
-    u32 fun_output     : 1;
+    u32 verbose_output          : 30;
+    b32 fun_output              : 1;
+    b32 print_function_mappings : 1; 
 
     bh_arr(const char *) included_folders;
     bh_arr(const char *) files;
index b2da15114638b290b28ff7522026694086cdd0fa..9f42e42d58dfadd5909cd7bcd96b4e6966317c75 100644 (file)
@@ -76,10 +76,10 @@ contexts:
       captures:
         1: meta.function-call.onyx
 
-    - match: '([a-zA-Z_][a-zA-Z0-9_]*)(,\s*([a-zA-Z_][a-zA-Z0-9_]*))*\s*:'
-      captures:
-        1: variable
-        2: variable
+    - match: '([a-zA-Z_][a-zA-Z0-9_]*)(,\s*([a-zA-Z_][a-zA-Z0-9_]*))*\s*:'
+      captures:
+        1: variable
+        2: variable
 
   double_quoted_string:
     - meta_scope: string.quoted.double.onyx
index 381c62a0cef6cc1147b387a585d5b282f8805003..41c79d7fa36d32821e20c890e8bede23a823c4c7 100644 (file)
Binary files a/onyx.exe and b/onyx.exe differ
index 8cdf1e48360aea12f92d6a1d7b2f946fa5722b91..9a6b0ccda7b1d75cc62b9a2ac73d17f6bdfffbc3 100644 (file)
@@ -45,7 +45,9 @@ static CompileOptions compile_opts_parse(bh_allocator alloc, int argc, char *arg
         .allocator = alloc,
         .action = ONYX_COMPILE_ACTION_PRINT_HELP,
 
-        .verbose_output = 0,
+        .verbose_output          = 0,
+        .fun_output              = 0,
+        .print_function_mappings = 0,
 
         .files = NULL,
         .target_file = "out.wasm",
@@ -87,6 +89,9 @@ static CompileOptions compile_opts_parse(bh_allocator alloc, int argc, char *arg
             else if (!strcmp(argv[i], "--fun") || !strcmp(argv[i], "-F")) {
                 options.fun_output = 1;
             }
+            else if (!strcmp(argv[i], "--print-function-mappings")) {
+                options.print_function_mappings = 1;
+            }
             else if (!strcmp(argv[i], "-I")) {
                 bh_arr_push(options.included_folders, argv[++i]);
             }
index 8a5365bd525a26a79e2a00d1e10556153b1af847..47f65823d7203f851b3b30450b49e09cd6b9d8d1 100644 (file)
@@ -281,7 +281,7 @@ u32 type_alignment_of(Type* type) {
         case Type_Kind_Slice:    return 8;
         case Type_Kind_VarArgs:  return 8;
         case Type_Kind_DynArray: return 8;
-        case Type_Kind_Compound: return 8; // HACK
+        case Type_Kind_Compound: return 4; // HACK
         default: return 1;
     }
 }
@@ -547,10 +547,10 @@ Type* type_build_from_ast(bh_allocator alloc, AstType* type_node) {
             fori (i, 0, type_count) {
                 assert(ctype->types[i] != NULL);
                 comp_type->Compound.types[i] = type_build_from_ast(alloc, ctype->types[i]);
-                comp_type->Compound.size += type_size_of(comp_type->Compound.types[i]);
+                comp_type->Compound.size += bh_max(type_size_of(comp_type->Compound.types[i]), 4);
             }
 
-            bh_align(comp_type->Compound.size, 8);
+            bh_align(comp_type->Compound.size, 4);
 
             return comp_type;
         }
@@ -598,11 +598,11 @@ Type* type_build_compound_type(bh_allocator alloc, AstCompound* compound) {
 
     fori (i, 0, expr_count) {
         assert(compound->exprs[i]->type != NULL);
-        comp_type->Compound.size += type_size_of(compound->exprs[i]->type);
         comp_type->Compound.types[i] = compound->exprs[i]->type;
+        comp_type->Compound.size += bh_max(type_size_of(comp_type->Compound.types[i]), 4);
     }
     
-    bh_align(comp_type->Compound.size, 8);
+    bh_align(comp_type->Compound.size, 4);
 
     return comp_type;
 }
index 38cc66cf265b42f3ae950cad61130240432d355c..6ed8198310bd0022c02494012e0962fd74709cf5 100644 (file)
@@ -3251,11 +3251,13 @@ void emit_entity(Entity* ent) {
         case Entity_Type_Function_Header:
             if (!should_emit_function(ent->function)) break;
 
-            // bh_printf("%d -> %s:%d:%d\n",
-            //     module->next_func_idx,
-            //     ent->expr->token->pos.filename,
-            //     ent->expr->token->pos.line,
-            //     ent->expr->token->pos.column);
+            if (context.options->print_function_mappings) {
+                bh_printf("%d -> %s:%d:%d\n",
+                    module->next_func_idx,
+                    ent->expr->token->pos.filename,
+                    ent->expr->token->pos.line,
+                    ent->expr->token->pos.column);
+            }
             
             bh_imap_put(&module->index_map, (u64) ent->function, module->next_func_idx++);
             break;