From: Brendan Hansen Date: Sun, 23 Aug 2020 04:28:48 +0000 (-0500) Subject: adding more core functionality and bugfixes X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=13217d97b8ee66c5237763a311c654a8dd8a5ea5;p=onyx.git adding more core functionality and bugfixes --- diff --git a/core/string.onyx b/core/string.onyx index 8f58d66b..4ff1f2fd 100644 --- a/core/string.onyx +++ b/core/string.onyx @@ -1,17 +1,18 @@ package core -use package builtin { string } +use package builtin { string, cstring } use package memory +use package wasi Buffer :: struct { data : rawptr = null; - length : u32 = 0; + len : u32 = 0; } -string_make :: proc #overloaded { string_make_from_u8 } +string_make :: proc #overloaded { string_make_from_cstring } #private -string_make_from_u8 :: proc (s: ^u8) -> string { +string_make_from_cstring :: proc (s: cstring) -> string { len :: string_length(s); return string.{ len = len, data = s }; @@ -51,3 +52,158 @@ string_concat :: proc (a: Allocator, s1: string, s2: string) -> string { string_free :: proc (a: Allocator, s: string) do free(a, s.data); +StringSplitResult :: struct { + tokens: ^string; + count: u32; +} + +string_split :: proc (a: Allocator, str: string, delim: u8) -> StringSplitResult { + delim_count := 0; + for i: 0, str.len do if str.data[i] == delim do delim_count += 1; + + strarr := cast(^string) alloc(a, sizeof string * (delim_count + 1)); + + curr_str := 0; + begin := str.data; + + for i: 0, str.len { + if str.data[i] == delim { + strarr[curr_str] = string.{ begin, cast(u32) ^str.data[i] - cast(u32) begin }; + begin = ^str.data[i + 1]; + curr_str += 1; + } + } + + strarr[curr_str] = string.{ begin, cast(u32) str.data + str.len - cast(u32) begin }; + + return StringSplitResult.{ strarr, delim_count + 1 }; +} + + + +StringBuilder :: struct { + // FIX(nested-structs): This should not be a pointer eventually. + // Currently nested structures cannot be passed as arguments or returned from procedures. + // When this issue is fixed, change this to Allocator. + alloc : ^Allocator; + + data : ^u8 = null; + len : u32 = 0; + cap : u32 = 0; +} + +string_builder_make :: proc (a: ^Allocator, initial_cap: u32) -> StringBuilder { + data: ^u8 = null; + + if initial_cap > 0 { + data = cast(^u8) alloc(*a, initial_cap); + } + + return StringBuilder.{ + alloc = a, + data = data, + cap = initial_cap, + }; +} + +string_builder_add_string :: proc (use sb: ^StringBuilder, str: string) -> ^StringBuilder { + len_total :: len + str.len; + + if cap >= len_total { + for i: 0, str.len do data[len + i] = str.data[i]; + len += str.len; + return sb; + } + + new_cap := cap; + while new_cap < len_total do new_cap <<= 1; + + new_data := cast(^u8) resize(*alloc, data, new_cap); + if new_data == null do return sb; + + data = new_data; + cap = new_cap; + + for i: 0, str.len do data[len + i] = str.data[i]; + len += str.len; + return sb; +} + +string_builder_add_cstring :: proc (use sb: ^StringBuilder, cstr: cstring) -> ^StringBuilder { + s := string_make(cstr); + return string_builder_add_string(sb, s); +} + +u64_to_string :: proc (n_: u64, base: u64, buf: Buffer) -> string { + n := n_; + + str :: cast(^u8) buf.data; + for i: 0, buf.len do str[i] = #char "\0"; + + c := cast(^u8) ^str[buf.len - 1]; + len := 0; + + s :: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; + + if n == 0l { + *c = #char "0"; + len += 1; + c -= 1; + } else { + while n > 0l { + m :: n % base; + + *c = s.data[cast(u32) m]; + len += 1; + c -= 1; + + n /= base; + } + } + + if base == 16l { + *c = #char "x"; + len += 1; + c -= 1; + *c = #char "0"; + len += 1; + c -= 1; + } + + if base == 2l { + *c = #char "b"; + len += 1; + c -= 1; + *c = #char "0"; + len += 1; + c -= 1; + } + + return string.{ data = c + 1, len = len }; +} + +string_builder_add_u64 :: proc (use sb: ^StringBuilder, n: u64) -> ^StringBuilder { + return string_builder_add_u64_with_base(sb, n, 10l); +} + +string_builder_add_u64_with_base :: proc (use sb: ^StringBuilder, n: u64, base: u64) -> ^StringBuilder { + buf : [256] u8; + s := u64_to_string(n, 10l, Buffer.{ cast(^u8) buf, 256 }); + return string_builder_add_string(sb, s); +} + +string_builder_append :: proc #overloaded { + string_builder_add_string, + string_builder_add_cstring, + string_builder_add_u64_with_base, + string_builder_add_u64, +} + +string_builder_to_string :: proc (use sb: ^StringBuilder) -> string { + return string.{ data, len }; +} + +string_builder_clear :: proc (use sb: ^StringBuilder) -> ^StringBuilder { + len = 0; + return sb; +} \ No newline at end of file diff --git a/core/wasi.onyx b/core/wasi.onyx index d26d9e96..c146415e 100644 --- a/core/wasi.onyx +++ b/core/wasi.onyx @@ -1,134 +1,138 @@ package wasi +use package main as main +use package builtin { string } +use package memory + Size :: #type u32; Filesize :: #type u64; Timestamp :: #type u64; ClockID :: enum (u32) { - Realtime :: 0x00; - Monotonic :: 0x01; - ProcessCPUTimeID :: 0x02; - ThreadCPUTimeID :: 0x03; + Realtime :: 0x00; + Monotonic :: 0x01; + ProcessCPUTimeID :: 0x02; + ThreadCPUTimeID :: 0x03; } Errno :: enum (u16) { - Success :: 0x00; - TooBig :: 0x01; - Access :: 0x02; - AddrInUse :: 0x03; - AddrNotAvail :: 0x04; - AFNoSupport :: 0x05; - Again :: 0x06; - Already :: 0x07; - BadFile :: 0x08; - BadMsg :: 0x09; - Busy :: 0x0a; - Canceled :: 0x0b; - Child :: 0x0c; - ConnAborted :: 0x0d; - ConnRefused :: 0x0e; - ConnReset :: 0x0f; - DeadLock :: 0x10; - DestAddrReq :: 0x11; - Domain :: 0x12; - DQUOT :: 0x13; - Exist :: 0x14; - Fault :: 0x15; - FileTooBig :: 0x16; - HostUnreach :: 0x17; - IdentRemoved :: 0x18; - IllegalSeq :: 0x19; - InProgress :: 0x1a; - Interrupt :: 0x1b; - Invalid :: 0x1c; - IO :: 0x1d; - IsConnection :: 0x1e; - IsDirectory :: 0x1f; - Loop :: 0x20; - MFile :: 0x21; - MLink :: 0x22; - MsgSize :: 0x23; - MultiHop :: 0x24; - NameTooLong :: 0x25; - NetDown :: 0x26; - NetReset :: 0x27; - NetUnreach :: 0x28; - NFile :: 0x29; - NoBufs :: 0x2a; - NoDev :: 0x2b; - NoEntry :: 0x2c; - NoExec :: 0x2d; - NoLock :: 0x2e; - NoLink :: 0x2f; - NoMemory :: 0x30; - NoMsg :: 0x31; - NoProtoOpt :: 0x32; - NoSpace :: 0x33; - NoSys :: 0x34; - NotConn :: 0x35; - NotDir :: 0x36; - NotEmpty :: 0x37; - NotRecover :: 0x38; - NotSock :: 0x39; - NotSupported :: 0x3a; - NoTTY :: 0x3b; - NXIO :: 0x3c; - Overflow :: 0x3d; - OwnerDead :: 0x3e; - Permission :: 0x3f; - Pipe :: 0x40; - Protocol :: 0x41; - ProtoNoSup :: 0x42; - Prototype :: 0x43; - Range :: 0x44; - ReadonlyFS :: 0x45; - SeekPipe :: 0x46; - Search :: 0x47; - Stale :: 0x48; - Timedout :: 0x49; - TextBusy :: 0x4a; - XDev :: 0x4b; - - NotCapable :: 0x4c; + Success :: 0x00; + TooBig :: 0x01; + Access :: 0x02; + AddrInUse :: 0x03; + AddrNotAvail :: 0x04; + AFNoSupport :: 0x05; + Again :: 0x06; + Already :: 0x07; + BadFile :: 0x08; + BadMsg :: 0x09; + Busy :: 0x0a; + Canceled :: 0x0b; + Child :: 0x0c; + ConnAborted :: 0x0d; + ConnRefused :: 0x0e; + ConnReset :: 0x0f; + DeadLock :: 0x10; + DestAddrReq :: 0x11; + Domain :: 0x12; + DQUOT :: 0x13; + Exist :: 0x14; + Fault :: 0x15; + FileTooBig :: 0x16; + HostUnreach :: 0x17; + IdentRemoved :: 0x18; + IllegalSeq :: 0x19; + InProgress :: 0x1a; + Interrupt :: 0x1b; + Invalid :: 0x1c; + IO :: 0x1d; + IsConnection :: 0x1e; + IsDirectory :: 0x1f; + Loop :: 0x20; + MFile :: 0x21; + MLink :: 0x22; + MsgSize :: 0x23; + MultiHop :: 0x24; + NameTooLong :: 0x25; + NetDown :: 0x26; + NetReset :: 0x27; + NetUnreach :: 0x28; + NFile :: 0x29; + NoBufs :: 0x2a; + NoDev :: 0x2b; + NoEntry :: 0x2c; + NoExec :: 0x2d; + NoLock :: 0x2e; + NoLink :: 0x2f; + NoMemory :: 0x30; + NoMsg :: 0x31; + NoProtoOpt :: 0x32; + NoSpace :: 0x33; + NoSys :: 0x34; + NotConn :: 0x35; + NotDir :: 0x36; + NotEmpty :: 0x37; + NotRecover :: 0x38; + NotSock :: 0x39; + NotSupported :: 0x3a; + NoTTY :: 0x3b; + NXIO :: 0x3c; + Overflow :: 0x3d; + OwnerDead :: 0x3e; + Permission :: 0x3f; + Pipe :: 0x40; + Protocol :: 0x41; + ProtoNoSup :: 0x42; + Prototype :: 0x43; + Range :: 0x44; + ReadonlyFS :: 0x45; + SeekPipe :: 0x46; + Search :: 0x47; + Stale :: 0x48; + Timedout :: 0x49; + TextBusy :: 0x4a; + XDev :: 0x4b; + + NotCapable :: 0x4c; } Rights :: enum #flags (u64) { - DataSync; - Read; - Seek; - FdStatSetFlags; - Sync; - Tell; - Write; - Advise; - Allocate; - PathCreateDirectory; - PathCreateFile; - PathLinkSource; - PathLinkTarget; - PathOpen; - ReadDir; - PathReadlink; - PathRenameSource; - PathRenameTarget; - PathFilestatGet; - PathFilestateSetSize; - PathFilestateSetTimes; - FilestatGet; - FilestatSetSize; - FilestatSetTimes; - PathSymlink; - PathRemoveDirectory; - PathUnlinkFile; - PollFDReadWrite; - SockShutdown; + DataSync; + Read; + Seek; + FdStatSetFlags; + Sync; + Tell; + Write; + Advise; + Allocate; + PathCreateDirectory; + PathCreateFile; + PathLinkSource; + PathLinkTarget; + PathOpen; + ReadDir; + PathReadlink; + PathRenameSource; + PathRenameTarget; + PathFilestatGet; + PathFilestateSetSize; + PathFilestateSetTimes; + FilestatGet; + FilestatSetSize; + FilestatSetTimes; + PathSymlink; + PathRemoveDirectory; + PathUnlinkFile; + PollFDReadWrite; + SockShutdown; } FileDescriptor :: #type i32; IOVec :: struct { - buf : ^u8; - len : u32; + buf : ^u8; + len : u32; } CIOVec :: #type IOVec; // Constant IOVec @@ -136,9 +140,9 @@ CIOVec :: #type IOVec; // Constant IOVec FileDelta :: #type i64; Whence :: enum (u8) { - Set :: 0x00; - Cur :: 0x01; - End :: 0x02; + Set :: 0x00; + Cur :: 0x01; + End :: 0x02; } DirCookie :: #type u64; @@ -146,205 +150,205 @@ DirNameLen :: #type u32; INode :: #type u64; Filetype :: enum (u8) { - Unknown :: 0x00; - BlockDevice :: 0x01; - CharDevice :: 0x02; - Directory :: 0x03; - RegularFile :: 0x04; - SocketDgram :: 0x05; - SocketStream :: 0x06; - SymLink :: 0x07; + Unknown :: 0x00; + BlockDevice :: 0x01; + CharDevice :: 0x02; + Directory :: 0x03; + RegularFile :: 0x04; + SocketDgram :: 0x05; + SocketStream :: 0x06; + SymLink :: 0x07; } DirEnt :: struct { - d_next : DirCookie; - d_ino : INode; - d_namlen : DirNameLen; - d_type : Filetype; + d_next : DirCookie; + d_ino : INode; + d_namlen : DirNameLen; + d_type : Filetype; } Advice :: enum (u8) { - Normal :: 0x00; - Sequential :: 0x01; - Random :: 0x02; - WillNeed :: 0x03; - DontNeed :: 0x04; - NoReuse :: 0x05; + Normal :: 0x00; + Sequential :: 0x01; + Random :: 0x02; + WillNeed :: 0x03; + DontNeed :: 0x04; + NoReuse :: 0x05; } FDFlags :: enum #flags (u16) { - Append; - DSync; - NonBlock; - RSync; - Sync; + Append; + DSync; + NonBlock; + RSync; + Sync; } FDStat :: struct { - fs_filetype : Filetype; - fs_flags : FDFlags; - fs_rights_base : Rights; - fs_rights_inheriting : Rights; + fs_filetype : Filetype; + fs_flags : FDFlags; + fs_rights_base : Rights; + fs_rights_inheriting : Rights; } Device :: #type u64; FSTFlags :: enum #flags (u16) { - ATIM; - ATIM_NOW; - MTIM; - MTIM_NOW; + ATIM; + ATIM_NOW; + MTIM; + MTIM_NOW; } LookupFlags :: enum #flags (u32) { - SymLinkFollow; + SymLinkFollow; } OFlags :: enum #flags (u16) { - Creat; - Directory; - FailIfExists; - Trunc; + Creat; + Directory; + FailIfExists; + Trunc; } LinkCount :: #type u64; FileStat :: struct { - dev : Device; - ino : INode; - filetype : Filetype; - nlink : LinkCount; - size : Filesize; - atim : Timestamp; - mtim : Timestamp; - ctim : Timestamp; + dev : Device; + ino : INode; + filetype : Filetype; + nlink : LinkCount; + size : Filesize; + atim : Timestamp; + mtim : Timestamp; + ctim : Timestamp; } Userdata :: #type u64; EventType :: enum (u8) { - Clock; - FDRead; - FDWrite; + Clock; + FDRead; + FDWrite; } EventRWFlags :: enum #flags (u16) { - ReadWriteHangUp; + ReadWriteHangUp; } EventFDReadWrite :: struct { - nbytes : Filesize; - flags : EventRWFlags; + nbytes : Filesize; + flags : EventRWFlags; } Event :: struct { - userdata : Userdata; - error : Errno; - type : EventType; - fd_readwrite : EventFDReadWrite; + userdata : Userdata; + error : Errno; + type : EventType; + fd_readwrite : EventFDReadWrite; } SubClockFlags :: enum #flags (u16) { - ClockAbsTime; + ClockAbsTime; } SubscriptionClock :: struct { - id : ClockID; - timeout : Timestamp; - precision : Timestamp; - flags : SubClockFlags; + id : ClockID; + timeout : Timestamp; + precision : Timestamp; + flags : SubClockFlags; } SubscriptionFDReadWrite :: struct { - file_descriptor : FileDescriptor; + file_descriptor : FileDescriptor; } SubscriptionTagged :: struct { - tag : EventType; + tag : EventType; - u : struct #union { - clock : SubscriptionClock; - fd_read : SubscriptionFDReadWrite; - fd_write : SubscriptionFDReadWrite; - }; + u : struct #union { + clock : SubscriptionClock; + fd_read : SubscriptionFDReadWrite; + fd_write : SubscriptionFDReadWrite; + }; } Subscription :: struct { - userdata : Userdata; + userdata : Userdata; - u : SubscriptionTagged; + u : SubscriptionTagged; } ExitCode :: #type u32; Signal :: enum (u8) { - None; - Hup; - Int; - Quit; - Ill; - Trap; - Abrt; - Bus; - Fpe; - Kill; - USR1; - Segv; - USR2; - Pipe; - Alrm; - Term; - Chld; - Stop; - Tstp; - Ttin; - Urg; - Xcpu; - Xfsz; - Vtalrm; - Prof; - Winch; - Poll; - Pwr; - Sys; + None; + Hup; + Int; + Quit; + Ill; + Trap; + Abrt; + Bus; + Fpe; + Kill; + USR1; + Segv; + USR2; + Pipe; + Alrm; + Term; + Chld; + Stop; + Tstp; + Ttin; + Urg; + Xcpu; + Xfsz; + Vtalrm; + Prof; + Winch; + Poll; + Pwr; + Sys; } RIFlags :: enum #flags (u16) { - RecvPeek; - RecvWaitAll; + RecvPeek; + RecvWaitAll; } ROFlags :: enum #flags (u16) { - RecvDataTruncated :: 1; + RecvDataTruncated :: 1; } SIFlags :: enum #flags (u16) { - None; + None; } SDFlags :: enum #flags (u16) { - RD; - WR; + RD; + WR; } PreopenType :: enum (u8) { - Dir :: 0x00; + Dir :: 0x00; } PrestatDir :: struct { - pr_name_len : Size; + pr_name_len : Size; } PrestatTagged :: struct { - tag : PreopenType; + tag : PreopenType; - u : struct #union { - dir : PrestatDir; - }; + u : struct #union { + dir : PrestatDir; + }; } IOVecArray :: struct { - iovs : ^IOVec; - iovs_len : Size; + iovs : ^IOVec; + iovs_len : Size; } @@ -369,74 +373,73 @@ fd_filestat_get :: proc #foreign "wasi_snapshot_preview1" "fd_filestat_get fd_filestat_set_size :: proc #foreign "wasi_snapshot_preview1" "fd_filestat_set_size" (fd: FileDescriptor, size: Filesize) -> Errno --- fd_filestat_set_times :: proc #foreign "wasi_snapshot_preview1" "fd_filestat_set_times" (fd: FileDescriptor, atim: Timestamp, mtim: Timestamp, fst_flags: FSTFlags) -> Errno --- fd_pread :: - proc #foreign "wasi_snapshot_preview1" "fd_pread" - (fd: FileDescriptor, iovs: IOVecArray, offset: Filesize, nread: ^Size) -> Errno --- + proc #foreign "wasi_snapshot_preview1" "fd_pread" + (fd: FileDescriptor, iovs: IOVecArray, offset: Filesize, nread: ^Size) -> Errno --- fd_prestat_get :: proc #foreign "wasi_snapshot_preview1" "fd_prestat_get" (fd: FileDescriptor, buf: ^PrestatTagged) -> Errno --- -fd_prestat_dir_name :: proc #foreign "wasi_snapshot_preview1" "fd_prestat_dir_name" (fd: FileDescriptor, path: ^u8, path_len: Size) -> Errno --- +fd_prestat_dir_name :: proc #foreign "wasi_snapshot_preview1" "fd_prestat_dir_name" (fd: FileDescriptor, path: string) -> Errno --- fd_pwrite :: - proc #foreign "wasi_snapshot_preview1" "fd_pwrite" - (fd: FileDescriptor, iovs: IOVecArray, offset: Filesize, nwritten: ^Size) -> Errno --- + proc #foreign "wasi_snapshot_preview1" "fd_pwrite" + (fd: FileDescriptor, iovs: IOVecArray, offset: Filesize, nwritten: ^Size) -> Errno --- fd_read :: - proc #foreign "wasi_snapshot_preview1" "fd_read" - (fd: FileDescriptor, iovs: IOVecArray, nread: ^Size) -> Errno --- + proc #foreign "wasi_snapshot_preview1" "fd_read" + (fd: FileDescriptor, iovs: IOVecArray, nread: ^Size) -> Errno --- fd_readdir :: - proc #foreign "wasi_snapshot_preview1" "fd_readdir" - (fd: FileDescriptor, buf: ^u8, buf_len: Size, cookie: DirCookie, bufused: ^Size) -> Errno --- + proc #foreign "wasi_snapshot_preview1" "fd_readdir" + (fd: FileDescriptor, buf: ^u8, buf_len: Size, cookie: DirCookie, bufused: ^Size) -> Errno --- fd_renumber :: - proc #foreign "wasi_snapshot_preview1" "fd_renumber" - (fd: FileDescriptor, to: FileDescriptor) -> Errno --- + proc #foreign "wasi_snapshot_preview1" "fd_renumber" + (fd: FileDescriptor, to: FileDescriptor) -> Errno --- fd_seek :: - proc #foreign "wasi_snapshot_preview1" "fd_seek" - (fd: FileDescriptor, offset: FileDelta, whence: Whence, newoffset: ^Filesize) -> Errno --- + proc #foreign "wasi_snapshot_preview1" "fd_seek" + (fd: FileDescriptor, offset: FileDelta, whence: Whence, newoffset: ^Filesize) -> Errno --- fd_sync :: proc #foreign "wasi_snapshot_preview1" "fd_sync" (fd: FileDescriptor) -> Errno --- fd_tell :: proc #foreign "wasi_snapshot_preview1" "fd_tell" (fd: FileDescriptor, offset: ^Filesize) -> Errno --- fd_write :: - proc #foreign "wasi_snapshot_preview1" "fd_write" - (fd: FileDescriptor, iovs: IOVecArray, nwritten: ^Size) -> Errno --- + proc #foreign "wasi_snapshot_preview1" "fd_write" + (fd: FileDescriptor, iovs: IOVecArray, nwritten: ^Size) -> Errno --- path_create_directory :: - proc #foreign "wasi_snapshot_preview1" "path_create_directory" - (fd: FileDescriptor, path: ^u8, path_len: Size) -> Errno --- + proc #foreign "wasi_snapshot_preview1" "path_create_directory" + (fd: FileDescriptor, path: string) -> Errno --- path_filestat_get :: - proc #foreign "wasi_snapshot_preview1" "path_filestat_get" - (fd: FileDescriptor, flags: LookupFlags, path: ^u8, path_len: Size, buf: ^FileStat) -> Errno --- + proc #foreign "wasi_snapshot_preview1" "path_filestat_get" + (fd: FileDescriptor, flags: LookupFlags, path: string, buf: ^FileStat) -> Errno --- path_filestat_set_times :: - proc #foreign "wasi_snapshot_preview1" "path_filestat_set_times" - (fd: FileDescriptor, flags: LookupFlags, path: ^u8, path_len: Size, atim: Timestamp, mtim: Timestamp, fst_flags: FSTFlags) -> Errno --- + proc #foreign "wasi_snapshot_preview1" "path_filestat_set_times" + (fd: FileDescriptor, flags: LookupFlags, path: string, atim: Timestamp, mtim: Timestamp, fst_flags: FSTFlags) -> Errno --- path_link :: - proc #foreign "wasi_snapshot_preview1" "path_link" - (fd: FileDescriptor, old_flags: LookupFlags, old_path: ^u8, old_path_len: Size, new_fd: FileDescriptor, new_path: ^u8, new_path_len: Size) -> Errno --- + proc #foreign "wasi_snapshot_preview1" "path_link" + (fd: FileDescriptor, old_flags: LookupFlags, old_path: string, new_fd: FileDescriptor, new_path: string) -> Errno --- path_open :: - proc #foreign "wasi_snapshot_preview1" "path_open" - ( fd: FileDescriptor - , dirflags: LookupFlags - , path: ^u8 - , path_len: Size - , oflags: OFlags - , fs_rights_base: Rights - , fs_rights_inherting: Rights - , fdflags: FDFlags - , opened_fd: ^FileDescriptor - ) -> Errno --- + proc #foreign "wasi_snapshot_preview1" "path_open" + ( fd: FileDescriptor + , dirflags: LookupFlags + , path: string + , oflags: OFlags + , fs_rights_base: Rights + , fs_rights_inherting: Rights + , fdflags: FDFlags + , opened_fd: ^FileDescriptor + ) -> Errno --- path_readlink :: - proc #foreign "wasi_snapshot_preview1" "path_readlink" - (fd: FileDescriptor, path: ^u8, path_len: Size, buf: ^u8, buf_len: Size, bufused: ^Size) -> Errno --- + proc #foreign "wasi_snapshot_preview1" "path_readlink" + (fd: FileDescriptor, path: string, buf: ^u8, buf_len: Size, bufused: ^Size) -> Errno --- path_remove_directory :: - proc #foreign "wasi_snapshot_preview1" "path_remove_directory" - (fd: FileDescriptor, path: ^u8, path_len: Size) -> Errno --- + proc #foreign "wasi_snapshot_preview1" "path_remove_directory" + (fd: FileDescriptor, path: string) -> Errno --- path_rename :: - proc #foreign "wasi_snapshot_preview1" "path_rename" - (fd: FileDescriptor, old_path: ^u8, old_path_len: Size, new_fd: FileDescriptor, new_path: ^u8, new_path_len: Size) -> Errno --- + proc #foreign "wasi_snapshot_preview1" "path_rename" + (fd: FileDescriptor, old_path: string, new_fd: FileDescriptor, new_path: string) -> Errno --- path_symlink :: - proc #foreign "wasi_snapshot_preview1" "path_symlink" - (old_path: ^u8, old_path_len: Size, fd: FileDescriptor, new_path: ^u8, new_path_len: Size) -> Errno --- + proc #foreign "wasi_snapshot_preview1" "path_symlink" + (old_path: ^u8, old_path_len: Size, fd: FileDescriptor, new_path: string) -> Errno --- path_unlink_file :: - proc #foreign "wasi_snapshot_preview1" "path_unlink_file" - (fd: FileDescriptor, path: ^u8, path_len: Size) -> Errno --- + proc #foreign "wasi_snapshot_preview1" "path_unlink_file" + (fd: FileDescriptor, path: string) -> Errno --- poll_oneoff :: - proc #foreign "wasi_snapshot_preview1" "poll_oneoff" - (in: ^Subscription, out: ^Event, nsubscriptions: Size, nevents: ^Size) -> Errno --- + proc #foreign "wasi_snapshot_preview1" "poll_oneoff" + (in: ^Subscription, out: ^Event, nsubscriptions: Size, nevents: ^Size) -> Errno --- proc_exit :: proc #foreign "wasi_snapshot_preview1" "proc_exit" (rval: ExitCode) --- proc_raise :: proc #foreign "wasi_snapshot_preview1" "proc_raise" (sig: Signal) -> Errno --- @@ -446,11 +449,31 @@ sched_yield :: proc #foreign "wasi_snapshot_preview1" "sched_yield" -> Errno --- random_get :: proc #foreign "wasi_snapshot_preview1" "random_get" (buf: ^u8, buf_len: Size) -> Errno --- sock_recv :: - proc #foreign "wasi_snapshot_preview1" "sock_recv" - (fd: FileDescriptor, ri_data: IOVecArray, ri_flags: RIFlags, ro_datalen: ^Size, ro_flags: ^ROFlags) -> Errno --- + proc #foreign "wasi_snapshot_preview1" "sock_recv" + (fd: FileDescriptor, ri_data: IOVecArray, ri_flags: RIFlags, ro_datalen: ^Size, ro_flags: ^ROFlags) -> Errno --- sock_send :: - proc #foreign "wasi_snapshot_preview1" "sock_send" - (fd: FileDescriptor, si_data: IOVecArray, si_flags: SIFlags, so_datalen: ^Size) -> Errno --- + proc #foreign "wasi_snapshot_preview1" "sock_send" + (fd: FileDescriptor, si_data: IOVecArray, si_flags: SIFlags, so_datalen: ^Size) -> Errno --- sock_shutdown :: - proc #foreign "wasi_snapshot_preview1" "sock_shutdown" - (fd: FileDescriptor, how: SDFlags) -> Errno --- + proc #foreign "wasi_snapshot_preview1" "sock_shutdown" + (fd: FileDescriptor, how: SDFlags) -> Errno --- + + + +// The builtin _start proc. +// Sets up everything needed for execution. +proc #export "_start" { + memory_init(); + + argc : Size; + argv_buf_size : Size; + + args_sizes_get(^argc, ^argv_buf_size); + + argv := cast(^^u8) malloc(sizeof ^u8 * argc); + argv_buf := cast(^u8) malloc(argv_buf_size); + + args_get(argv, argv_buf); + + main.main(argc, argv); +} diff --git a/docs/plan b/docs/plan index bdc1b957..a3e2cb00 100644 --- a/docs/plan +++ b/docs/plan @@ -187,6 +187,10 @@ HOW: [X] returning structs - This will put forward a lot of the work that will be done for multiple return values + [ ] implicit overloading + + [ ] 'use' enums and packages at an arbitrary scope + [ ] convert to using an 'atom' like table - All identifier tokens are given a unique atom ptr, up to string equality. - This means identifiers can be compared using ptr comparison, instead of string comparison @@ -208,14 +212,12 @@ HOW: - Arrays without a size - Converted to a struct that looks like: []T :: struct { - count : u32; data : ^T; + count : u32; } [ ] Variadic arguments - [ ] 'use' enums and packages at an arbitrary scope - [ ] 'when' statements - Compile time conditions - Only evalutate code blocks that evaluate to be true diff --git a/onyx b/onyx index 54e07f57..fc892e9a 100755 Binary files a/onyx and b/onyx differ diff --git a/progs/wasi_test.onyx b/progs/wasi_test.onyx index 9f4f7c36..d0fbf8da 100644 --- a/progs/wasi_test.onyx +++ b/progs/wasi_test.onyx @@ -10,7 +10,11 @@ package main #include_file "string" use package builtin + +// NOTE: Didn't realize this would work so easily +use package core { string_builder_append as sba } use package core + use package memory use package wasi use package intrinsics @@ -59,7 +63,7 @@ print_u64_with_base :: proc (n_: u64, base: u64) { print_string :: proc (s: string) { vec := IOVec.{ buf = s.data, len = s.len }; - tmp : Size; + tmp : Size; fd_write(1, IOVecArray.{ ^vec, 1 }, ^tmp); fd_datasync(1); } @@ -141,32 +145,63 @@ readdir :: proc (fd: FileDescriptor) { } } -main :: proc #export "_start" { - memory_init(); +timer_start :: proc -> Timestamp { + curr_time: Timestamp; + clock_time_get(ClockID.Realtime, cast(Timestamp) 1, ^curr_time); + return curr_time; +} +timer_end :: proc (start_time: Timestamp) -> Timestamp { curr_time: Timestamp; clock_time_get(ClockID.Realtime, cast(Timestamp) 1, ^curr_time); - print_u64_with_base(cast(u64) curr_time, 10l); - print("\n"); + return (curr_time - start_time) / 1000000l; +} - print("Hello World!\n"); - print_u64_with_base(cast(u64) 0x624abd, 16l); - print("\n"); - print_u64_with_base(cast(u64) __stack_top, 16l); - print("\n"); - print_u64_with_base(cast(u64) __heap_start, 16l); - print("\n"); +is_prime :: proc (n: u32) -> bool { + sqrt :: cast(i32) (sqrt_f32(cast(f32) n)); + for i: 2, sqrt + 1 do if n % i == 0 do return false; + return true; +} + +main :: proc (argc: u32, argv: ^cstring) { + sb := string_builder_make(^heap_allocator, 16); + + timer := timer_start(); + defer { + ^sb |> string_builder_clear() + |> sba("Time taken: ") + |> sba(cast(u64) timer_end(timer), 10l) + |> sba("ms\n") + |> string_builder_to_string() + |> print(); + } + + ^sb |> sba("\x01\x02\x03There are ") + |> sba(cast(u64) argc) + |> sba(" arguments.\n") + |> string_builder_to_string() + |> print(); + + string_builder_clear(^sb); + + for i: 0, argc do ^sb |> sba(argv[i]) |> sba(" "); + ^sb |> sba("\n") + |> string_builder_to_string() + |> print(); - fd : FileDescriptor; + fd: FileDescriptor = -1; err := path_open(3, LookupFlags.SymLinkFollow, - "./src/onyxmsgs.c".data, 16, + string_make(argv[1]), cast(OFlags) 0, Rights.DataSync | Rights.Write | Rights.Read | Rights.Tell | Rights.Seek | Rights.Advise | Rights.PathOpen | Rights.PathCreateFile, Rights.DataSync | Rights.Write | Rights.Read | Rights.Tell | Rights.Seek | Rights.Advise | Rights.PathOpen | Rights.PathCreateFile, FDFlags.Sync, ^fd); + defer if fd != -1 do fd_close(fd); + + if err != Errno.Success { print("Failed to open file\n"); print("Error code: "); @@ -184,19 +219,42 @@ main :: proc #export "_start" { } print("the size is: "); print_u64_with_base(cast(u64) filelen, 10l); + print("\n"); + + sum := 0l; + for i: 0, 20000 do if is_prime(i) do sum += cast(u64) i; + print("Sum of primes less than 20000 is: "); + print_u64_with_base(sum, 10l); + print("\n"); + - //buf : [128] u8; - //hello_vec := IOVec.{ buf = cast(^u8) buf, len = 128 }; - //nread : Size; - //if fd_read(fd, IOVecArray.{ ^hello_vec, 1 }, ^nread) != Errno.Success { - // print("Failed to read from file\n"); - // print("Error code: "); - // print_u64_with_base(cast(u64) err, 10l); - // proc_exit(1); - // return; - //} -// - //print(string.{ nread, cast(^u8) buf }); - - fd_close(fd); -} \ No newline at end of file + matches := string_split(heap_allocator, "This is a test string to test splitting. It surprisingly works very well.", #char " "); + defer free(heap_allocator, matches.tokens); + + string_builder_clear(^sb); + for i: 0, matches.count { + ^sb |> sba(matches.tokens[i]) + |> sba("\n"); + } + + ^sb |> string_builder_to_string() |> print(); + + program := "+ + * s - /"; + tokens := string_split(heap_allocator, program, #char " "); + defer free(heap_allocator, tokens.tokens); + + acc := 0; + for i: 0, tokens.count { + tok :: tokens.tokens[i].data[0]; + + if tok == #char "+" do acc += 1; + elseif tok == #char "-" do acc -= 1; + elseif tok == #char "*" do acc *= 2; + elseif tok == #char "/" do acc /= 2; + elseif tok == #char "s" do acc *= acc; + } + + string_builder_clear(^sb); + ^sb |> sba("The program evaluated to '") |> sba(cast(u64) acc) |> sba("'\n"); + ^sb |> string_builder_to_string() |> print(); +} diff --git a/src/onyxparser.c b/src/onyxparser.c index 2ae55a91..1794b7f0 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -440,6 +440,15 @@ static AstTyped* parse_factor(OnyxParser* parser) { case 'r': char_lit->value.i = '\r'; break; case 'v': char_lit->value.i = '\v'; break; case 'e': char_lit->value.i = '\e'; break; + case 'x': { + // HACK: This whole way of doing this + u8 buf[3]; + buf[0] = char_lit->token->text[2]; + buf[1] = char_lit->token->text[3]; + buf[2] = 0; + char_lit->value.i = strtol((const char *) buf, NULL, 16); + break; + } default: { onyx_message_add(Msg_Type_Literal, char_lit->token->pos, @@ -889,6 +898,7 @@ static AstNode* parse_statement(OnyxParser* parser) { case '-': case '!': case '*': + case '^': case Token_Type_Literal_Integer: case Token_Type_Literal_Float: case Token_Type_Literal_String: diff --git a/src/onyxutils.c b/src/onyxutils.c index 9733d625..8dbacf26 100644 --- a/src/onyxutils.c +++ b/src/onyxutils.c @@ -184,6 +184,7 @@ AstNode* symbol_resolve(Scope* start_scope, OnyxToken* tkn) { if (res == NULL) { onyx_message_add(Msg_Type_Unknown_Symbol, tkn->pos, tkn->text); + token_toggle_end(tkn); return &empty_node; } diff --git a/src/onyxwasm.c b/src/onyxwasm.c index 0eec5286..8133520a 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -1916,6 +1916,17 @@ static void compile_string_literal(OnyxWasmModule* mod, AstStrLit* strlit) { case 'r': *des++ = '\r'; break; case 'v': *des++ = '\v'; break; case 'e': *des++ = '\e'; break; + case 'x': { + // HACK: This whole way of doing this + i++; + u8 buf[3]; + buf[0] = src[i + 0]; + buf[1] = src[i + 1]; + buf[2] = 0; + *des++ = strtol((const char *) buf, NULL, 16); + i++; + break; + } default: *des++ = '\\'; *des++ = src[i]; }