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 };
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
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
FileDelta :: #type i64;
Whence :: enum (u8) {
- Set :: 0x00;
- Cur :: 0x01;
- End :: 0x02;
+ Set :: 0x00;
+ Cur :: 0x01;
+ End :: 0x02;
}
DirCookie :: #type u64;
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;
}
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 ---
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);
+}
#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
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);
}
}
}
-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: ");
}
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();
+}