bugfixes and starting to integrate with wasi_unstable
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 22 Aug 2020 16:36:14 +0000 (11:36 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 22 Aug 2020 16:36:14 +0000 (11:36 -0500)
13 files changed:
.vimspector.json
core/string.onyx
core/wasi.onyx [new file with mode: 0644]
docs/plan
include/onyxastnodes.h
onyx
progs/stack_based.onyx
progs/wasi_test.onyx [new file with mode: 0644]
src/onyxchecker.c
src/onyxsymres.c
src/onyxtypes.c
src/onyxutils.c
src/onyxwasm.c

index f6625bc264beb33f3eb80a1e1b2df5540e266d01..5388b49c347b5f46fb880185fc0b4eacd4e558ca 100644 (file)
@@ -6,7 +6,7 @@
                 "type": "cppdbg",
                 "request": "launch",
                 "program": "${workspaceFolder}/onyx",
-                "args": ["-verbose", "progs/stack_based.onyx"],
+                "args": ["-verbose", "progs/wasi_test.onyx"],
                 "stopAtEntry": true,
                 "cwd": "${workspaceFolder}",
                 "environment": [],
index 8beabf83d703bc8882bfac7d332f282c9c99f346..50a21994ef35a420c46ef523264fe9d4ac6fed8e 100644 (file)
@@ -55,5 +55,3 @@ string_concat :: proc (a: Allocator, s1: string, s2: string) -> string {
 
 string_free :: proc (a: Allocator, s: string) do free(a, s.data);
 
-#private print_str_with_len :: proc #foreign "host" "print_str_with_len" (s: ^u8, len: u32) ---
-string_print :: proc (s: string) do print_str_with_len(s.data, s.length);
diff --git a/core/wasi.onyx b/core/wasi.onyx
new file mode 100644 (file)
index 0000000..96908f0
--- /dev/null
@@ -0,0 +1,456 @@
+package wasi
+
+Size      :: #type u32;
+Filesize  :: #type u64;
+Timestamp :: #type u64;
+
+ClockID   :: enum (u32) {
+       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;
+}
+
+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;
+}
+
+FileDescriptor :: #type i32;
+
+IOVec :: struct {
+       buf : ^u8;
+       len : u32;
+}
+
+CIOVec :: #type IOVec; // Constant IOVec
+
+FileDelta :: #type i64;
+
+Whence :: enum (u8) {
+       Set :: 0x00;
+       Cur :: 0x01;
+       End :: 0x02;
+}
+
+DirCookie  :: #type u64;
+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;
+}
+
+DirEnt :: struct {
+       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;
+}
+
+FDFlags :: enum #flags (u16) {
+       Append;
+       DSync;
+       NonBlock;
+       RSync;
+       Sync;
+}
+
+FDStat :: struct {
+       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;
+}
+
+LookupFlags :: enum #flags (u32) {
+       SymLinkFollow;
+}
+
+OFlags :: enum #flags (u16) {
+       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;
+}
+
+Userdata :: #type u64;
+
+EventType :: enum (u8) {
+       Clock;
+       FDRead;
+       FDWrite;
+}
+
+EventRWFlags :: enum #flags (u16) {
+       ReadWriteHangUp;
+}
+
+EventFDReadWrite :: struct {
+       nbytes : Filesize;
+       flags  : EventRWFlags;
+}
+
+Event :: struct {
+       userdata     : Userdata;
+       error        : Errno;
+       type         : EventType;
+       fd_readwrite : EventFDReadWrite;
+}
+
+SubClockFlags :: enum #flags (u16) {
+       ClockAbsTime;
+}
+
+SubscriptionClock :: struct {
+       id        : ClockID;
+       timeout   : Timestamp;
+       precision : Timestamp;
+       flags     : SubClockFlags;
+}
+
+SubscriptionFDReadWrite :: struct {
+       file_descriptor : FileDescriptor;
+}
+
+SubscriptionTagged :: struct {
+       tag : EventType;
+
+       u : struct #union {
+               clock    : SubscriptionClock;
+               fd_read  : SubscriptionFDReadWrite;
+               fd_write : SubscriptionFDReadWrite;
+       };
+}
+
+Subscription :: struct {
+       userdata : Userdata;
+
+       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;
+}
+
+RIFlags :: enum #flags (u16) {
+       RecvPeek;
+       RecvWaitAll;
+}
+
+ROFlags :: enum #flags (u16) {
+       RecvDataTruncated :: 1;
+}
+
+SIFlags :: enum #flags (u16) {
+       None;
+}
+
+SDFlags :: enum #flags (u16) {
+       RD;
+       WR;
+}
+
+PreopenType :: enum (u8) {
+       Dir :: 0x00;
+}
+
+PrestatDir :: struct {
+       pr_name_len : Size;
+}
+
+PrestatTagged :: struct {
+       tag : PreopenType;
+
+       u : struct #union {
+               dir : PrestatDir;
+       };
+}
+
+IOVecArray :: struct {
+       iovs     : ^IOVec;
+       iovs_len : Size;
+}
+
+
+// FUNCTIONS
+args_get       :: proc #foreign "wasi_unstable" "args_get" (argv: ^^u8, argv_buf: ^u8) -> Errno ---
+args_sizes_get :: proc #foreign "wasi_unstable" "args_sizes_get" (argc: ^Size, argv_buf_size: ^Size) -> Errno ---
+
+environ_get       :: proc #foreign "wasi_unstable" "environ_get" (environ: ^^u8, environ_buf: ^u8) -> Errno ---
+environ_sizes_get :: proc #foreign "wasi_unstable" "environ_sizes_get" (environc: ^Size, environ_buf_size: ^Size) -> Errno ---
+
+clock_res_get  :: proc #foreign "wasi_unstable" "clock_res_get" (id: ClockID, resolution: ^Timestamp) -> Errno ---
+clock_time_get :: proc #foreign "wasi_unstable" "clock_time_get" (id: ClockID, precision: Timestamp, time: ^Timestamp) -> Errno ---
+
+fd_advise             :: proc #foreign "wasi_unstable" "fd_advise" (fd: FileDescriptor, offset: Filesize, len: Filesize, advice: Advice) -> Errno ---
+fd_allocate           :: proc #foreign "wasi_unstable" "fd_allocate" (fd: FileDescriptor, offset: Filesize, len: Filesize) -> Errno ---
+fd_close              :: proc #foreign "wasi_unstable" "fd_close" (fd: FileDescriptor) -> Errno ---
+fd_datasync           :: proc #foreign "wasi_unstable" "fd_datasync" (fd: FileDescriptor) -> Errno ---
+fd_fdstat_get         :: proc #foreign "wasi_unstable" "fd_fdstat_get" (fd: FileDescriptor, stat: ^FDStat) -> Errno ---
+fd_fdstat_set_flags   :: proc #foreign "wasi_unstable" "fd_fdstat_set_flags" (fd: FileDescriptor, flags: FDFlags) -> Errno ---
+fd_fdstat_set_rights  :: proc #foreign "wasi_unstable" "fd_fdstat_set_rights" (fd: FileDescriptor, rights_base: Rights, rights_inheriting: Rights) -> Errno ---
+fd_filestat_get       :: proc #foreign "wasi_unstable" "fd_filestat_get" (fd: FileDescriptor, buf: ^FileStat) -> Errno ---
+fd_filestat_set_size  :: proc #foreign "wasi_unstable" "fd_filestat_set_size" (fd: FileDescriptor, size: Filesize) -> Errno ---
+fd_filestat_set_times :: proc #foreign "wasi_unstable" "fd_filestat_set_times" (fd: FileDescriptor, atim: Timestamp, mtim: Timestamp, fst_flags: FSTFlags) -> Errno ---
+fd_pread ::
+       proc #foreign "wasi_unstable" "fd_pread"
+       (fd: FileDescriptor, iovs: IOVecArray, offset: Filesize, nread: ^Size) -> Errno ---
+fd_prestat_get :: proc #foreign "wasi_unstable" "fd_prestat_get" (fd: FileDescriptor, buf: ^PrestatTagged) -> Errno ---
+fd_prestat_dir_name :: proc #foreign "wasi_unstable" "fd_prestat_dir_name" (fd: FileDescriptor, path: ^u8, path_len: Size) -> Errno ---
+fd_pwrite ::
+       proc #foreign "wasi_unstable" "fd_pwrite"
+       (fd: FileDescriptor, iovs: IOVecArray, offset: Filesize, nwritten: ^Size) -> Errno ---
+fd_read ::
+       proc #foreign "wasi_unstable" "fd_read"
+       (fd: FileDescriptor, iovs: IOVecArray, nread: ^Size) -> Errno ---
+fd_readdir ::
+       proc #foreign "wasi_unstable" "fd_readdir"
+       (fd: FileDescriptor, buf: ^u8, buf_len: Size, cookie: DirCookie, bufused: ^Size) -> Errno ---
+fd_renumber ::
+       proc #foreign "wasi_unstable" "fd_renumber"
+       (fd: FileDescriptor, to: FileDescriptor) -> Errno ---
+fd_seek ::
+       proc #foreign "wasi_unstable" "fd_seek"
+       (fd: FileDescriptor, offset: FileDelta, whence: Whence, newoffset: ^Filesize) -> Errno ---
+fd_sync :: proc #foreign "wasi_unstable" "fd_sync" (fd: FileDescriptor) -> Errno ---
+fd_tell :: proc #foreign "wasi_unstable" "fd_tell" (fd: FileDescriptor, offset: ^Filesize) -> Errno ---
+fd_write ::
+       proc #foreign "wasi_unstable" "fd_write"
+       (fd: FileDescriptor, iovs: IOVecArray, nwritten: ^Size) -> Errno ---
+
+path_create_directory ::
+       proc #foreign "wasi_unstable" "path_create_directory"
+       (fd: FileDescriptor, path: ^u8, path_len: Size) -> Errno ---
+path_filestat_get ::
+       proc #foreign "wasi_unstable" "path_filestat_get"
+       (fd: FileDescriptor, flags: LookupFlags, path: ^u8, path_len: Size, buf: ^FileStat) -> Errno ---
+path_filestat_set_times ::
+       proc #foreign "wasi_unstable" "path_filestat_set_times"
+       (fd: FileDescriptor, flags: LookupFlags, path: ^u8, path_len: Size, atim: Timestamp, mtim: Timestamp, fst_flags: FSTFlags) -> Errno ---
+path_link ::
+       proc #foreign "wasi_unstable" "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 --- 
+path_open ::
+       proc #foreign "wasi_unstable" "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 ---
+path_readlink ::
+       proc #foreign "wasi_unstable" "path_readlink"
+       (fd: FileDescriptor, path: ^u8, path_len: Size, buf: ^u8, buf_len: Size, bufused: ^Size) -> Errno ---
+path_remove_directory ::
+       proc #foreign "wasi_unstable" "path_remove_directory"
+       (fd: FileDescriptor, path: ^u8, path_len: Size) -> Errno ---
+path_rename ::
+       proc #foreign "wasi_unstable" "path_rename"
+       (fd: FileDescriptor, old_path: ^u8, old_path_len: Size, new_fd: FileDescriptor, new_path: ^u8, new_path_len: Size) -> Errno ---
+path_symlink ::
+       proc #foreign "wasi_unstable" "path_symlink"
+       (old_path: ^u8, old_path_len: Size, fd: FileDescriptor, new_path: ^u8, new_path_len: Size) -> Errno ---
+path_unlink_file ::
+       proc #foreign "wasi_unstable" "path_unlink_file"
+       (fd: FileDescriptor, path: ^u8, path_len: Size) -> Errno ---
+
+poll_oneoff ::
+       proc #foreign "wasi_unstable" "poll_oneoff"
+       (in: ^Subscription, out: ^Event, nsubscriptions: Size, nevents: ^Size) -> Errno ---
+
+proc_exit :: proc #foreign "wasi_unstable" "proc_exit" (rval: ExitCode) ---
+proc_raise :: proc #foreign "wasi_unstable" "proc_raise" (sig: Signal) -> Errno ---
+
+sched_yield :: proc #foreign "wasi_unstable" "sched_yield" -> Errno ---
+
+random_get :: proc #foreign "wasi_unstable" "random_get" (buf: ^u8, buf_len: Size) -> Errno ---
+
+sock_recv ::
+       proc #foreign "wasi_unstable" "sock_recv"
+       (fd: FileDescriptor, ri_data: IOVecArray, ri_flags: RIFlags, ro_datalen: ^Size, ro_flags: ^ROFlags) -> Errno ---
+sock_send ::
+       proc #foreign "wasi_unstable" "sock_send"
+       (fd: FileDescriptor, si_data: IOVecArray, si_flags: SIFlags, so_datalen: ^Size) -> Errno ---
+sock_shutdown ::
+       proc #foreign "wasi_unstable" "sock_shutdown"
+       (fd: FileDescriptor, how: SDFlags) -> Errno ---
index 8bcf3262e801f437a45401971f82f5de1e3df4a7..bdc1b957b04e3fd98a084b936d850cca8a9dd973 100644 (file)
--- a/docs/plan
+++ b/docs/plan
@@ -187,6 +187,11 @@ HOW:
         [X] returning structs
             - This will put forward a lot of the work that will be done for multiple return values
 
+        [ ] 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
+            - This mean no more token_toggle_end!! Woo!!
+
         [ ] Put type info in data section so it is runtime accessible
             - type name
             - size
@@ -194,11 +199,6 @@ HOW:
             - struct member names
             - array length
 
-        [ ] 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
-            - This mean no more token_toggle_end!! Woo!!
-
         [ ] Make the lexer much faster
             - Technically it isn't slow right now
             - But, profiling says we are spending 50% of the program execution time in the lexer
@@ -212,6 +212,8 @@ HOW:
                     data  : ^T;
                 }
 
+        [ ] Variadic arguments
+
         [ ] 'use' enums and packages at an arbitrary scope
 
         [ ] 'when' statements
@@ -241,14 +243,10 @@ HOW:
         [X] Start work on evaluating compile time known values.
             - An expression marked COMPTIME will be reduced to its value in the parse tree.
 
-        [ ] #initialize structs
-
         [ ] Better checking for casts
             - Checking which things are allowed to cast to/from should be checked in the checker,
                 not in the wasm generatation
 
-        [ ] Variadic arguments
-
         [ ] Switch statements
 
 
index 06225a023b6dddee1b8ba2477f7c3c5f476bedbd..b965794c73452c44f29511fbf48829b84e692b59 100644 (file)
@@ -133,15 +133,15 @@ typedef enum AstKind {
 // only 32-bits of flags to play with
 typedef enum AstFlags {
     // Top-level flags
-    Ast_Flag_Exported          = BH_BIT(0),
-    Ast_Flag_Foreign           = BH_BIT(1),
-    Ast_Flag_Const             = BH_BIT(2),
-    Ast_Flag_Comptime          = BH_BIT(3),
-    Ast_Flag_Private_Package   = BH_BIT(4),
+    Ast_Flag_Exported          = BH_BIT(1),
+    Ast_Flag_Foreign           = BH_BIT(2),
+    Ast_Flag_Const             = BH_BIT(3),
+    Ast_Flag_Comptime          = BH_BIT(4),
+    Ast_Flag_Private_Package   = BH_BIT(5),
 
     // Global flags
-    Ast_Flag_Global_Stack_Top  = BH_BIT(30),
-    Ast_Flag_Global_Stack_Base = BH_BIT(31),
+    Ast_Flag_Global_Stack_Top  = BH_BIT(6),
+    Ast_Flag_Global_Stack_Base = BH_BIT(7),
 
     // Function flags
     Ast_Flag_Inline            = BH_BIT(8),
@@ -150,18 +150,18 @@ typedef enum AstFlags {
     Ast_Flag_No_Stack          = BH_BIT(11),
 
     // Expression flags
-    Ast_Flag_Expr_Ignored      = BH_BIT(8),
-    Ast_Flag_Param_Use         = BH_BIT(10),
-    Ast_Flag_Address_Taken     = BH_BIT(11),
+    Ast_Flag_Expr_Ignored      = BH_BIT(12),
+    Ast_Flag_Param_Use         = BH_BIT(13),
+    Ast_Flag_Address_Taken     = BH_BIT(14),
 
     // Type flags
-    Ast_Flag_Type_Is_Resolved  = BH_BIT(8),
+    Ast_Flag_Type_Is_Resolved  = BH_BIT(15),
 
     // Enum flags
-    Ast_Flag_Enum_Is_Flags     = BH_BIT(11),
+    Ast_Flag_Enum_Is_Flags     = BH_BIT(16),
 
     // Struct flags
-    Ast_Flag_Struct_Is_Union   = BH_BIT(12),
+    Ast_Flag_Struct_Is_Union   = BH_BIT(17),
 } AstFlags;
 
 typedef enum UnaryOp {
diff --git a/onyx b/onyx
index 776bc7649c4310526a9f9e22618537cdbdb08572..7f0459b0fc8b914e0ae629d58ef4b629bb8f8178 100755 (executable)
Binary files a/onyx and b/onyx differ
index 865e583e27e84ec4c15902f30a495d159e52ddb7..4291c9f29e3a583bb2b174ed1ae96ce79e13a00f 100644 (file)
@@ -5,10 +5,12 @@ package main
 #include_file "printing"
 #include_file "alloc"
 #include_file "string"
+#include_file "wasi"
 
 use package printing
 use package memory
 use package core
+use package wasi
 
 sort :: proc (arr: [N]i32, cmp: proc (i32, i32) -> i32) -> [N] i32 {
     for i: 0, N {
diff --git a/progs/wasi_test.onyx b/progs/wasi_test.onyx
new file mode 100644 (file)
index 0000000..92f35ba
--- /dev/null
@@ -0,0 +1,234 @@
+package main
+
+// WASI is still crap and I cannot get file opening to work.
+// Will try again in 5 years or so when they can finally make
+// that basic and necessary feature work.
+
+#include_folder "/usr/share/onyx/core"
+
+#include_file "wasi"
+#include_file "alloc"
+#include_file "intrinsics"
+#include_file "random"
+#include_file "string"
+
+use package builtin
+use package core
+use package memory
+use package wasi
+
+print_u64_with_base :: proc (n_: u64, base: u64) {
+    n := n_;
+    str: [256] u8;
+    for i: 0, 256 do str[i] = #char "\0";
+
+    c := cast(^u8) ^str[255];
+    *c = #char "\0";
+    c -= 1;
+
+    if n == 0l {
+        *c = #char "0";
+        c -= 1;
+    } else {
+        while n > 0l {
+            m :: n % base;
+
+            ch := cast(u8) 0;
+
+            // TODO: Replace with array lookup when array literals are added
+            if     m == 0l  do ch = #char "0";
+            elseif m == 1l  do ch = #char "1";
+            elseif m == 2l  do ch = #char "2";
+            elseif m == 3l  do ch = #char "3";
+            elseif m == 4l  do ch = #char "4";
+            elseif m == 5l  do ch = #char "5";
+            elseif m == 6l  do ch = #char "6";
+            elseif m == 7l  do ch = #char "7";
+            elseif m == 8l  do ch = #char "8";
+            elseif m == 9l  do ch = #char "9";
+            elseif m == 10l do ch = #char "A";
+            elseif m == 11l do ch = #char "B";
+            elseif m == 12l do ch = #char "C";
+            elseif m == 13l do ch = #char "D";
+            elseif m == 14l do ch = #char "E";
+            elseif m == 15l do ch = #char "F";
+
+            *c = ch;
+            c -= 1;
+
+            n /= base;
+        }
+    }
+
+    if base == 16l {
+        *c = #char "x";
+        c -= 1;
+        *c = #char "0";
+        c -= 1;
+    }
+
+    if base == 2l {
+        *c = #char "b";
+        c -= 1;
+        *c = #char "0";
+        c -= 1;
+    }
+
+    print(c + 1);
+}
+
+print_string :: proc (s: string) {
+       vec := IOVec.{ buf = s.data, len = s.length };
+       tmp : Size;     
+       fd_write(1, IOVecArray.{ ^vec, 1 }, ^tmp);
+       fd_datasync(1);
+}
+
+print_u8 :: proc (s: ^u8) {
+       string_make(s) |> print_string();
+}
+
+print :: proc #overloaded { print_string, print_u8 }
+
+print_rights :: proc (rights: Rights) {
+       print_u64_with_base(cast(u64) rights, 2l);
+
+       if rights & Rights.DataSync != cast(Rights) 0 do print("DataSync\n");
+       if rights & Rights.Read != cast(Rights) 0 do print("Read\n");
+       if rights & Rights.Seek != cast(Rights) 0 do print("Seek\n");
+       if rights & Rights.FdStatSetFlags != cast(Rights) 0 do print("FdStatSetFlags\n");
+       if rights & Rights.Sync != cast(Rights) 0 do print("Sync\n");
+       if rights & Rights.Tell != cast(Rights) 0 do print("Tell\n");
+       if rights & Rights.Write != cast(Rights) 0 do print("Write\n");
+       if rights & Rights.Advise != cast(Rights) 0 do print("Advise\n");
+       if rights & Rights.Allocate != cast(Rights) 0 do print("Allocate\n");
+       if rights & Rights.PathCreateDirectory != cast(Rights) 0 do print("PathCreateDirectory\n");
+       if rights & Rights.PathCreateFile != cast(Rights) 0 do print("PathCreateFile\n");
+       if rights & Rights.PathLinkSource != cast(Rights) 0 do print("PathLinkSource\n");
+       if rights & Rights.PathLinkTarget != cast(Rights) 0 do print("PathLinkTarget\n");
+       if rights & Rights.PathOpen != cast(Rights) 0 do print("PathOpen\n");
+       if rights & Rights.ReadDir != cast(Rights) 0 do print("ReadDir\n");
+       if rights & Rights.PathReadlink != cast(Rights) 0 do print("PathReadlink\n");
+       if rights & Rights.PathRenameSource != cast(Rights) 0 do print("PathRenameSource\n");
+       if rights & Rights.PathRenameTarget != cast(Rights) 0 do print("PathRenameTarget\n");
+       if rights & Rights.PathFilestatGet != cast(Rights) 0 do print("PathFilestatGet\n");
+       if rights & Rights.PathFilestateSetSize != cast(Rights) 0 do print("PathFilestateSetSize\n");
+       if rights & Rights.PathFilestateSetTimes != cast(Rights) 0 do print("PathFilestateSetTimes\n");
+       if rights & Rights.FilestatGet != cast(Rights) 0 do print("FilestatGet\n");
+       if rights & Rights.FilestatSetSize != cast(Rights) 0 do print("FilestatSetSize\n");
+       if rights & Rights.FilestatSetTimes != cast(Rights) 0 do print("FilestatSetTimes\n");
+       if rights & Rights.PathSymlink != cast(Rights) 0 do print("PathSymlink\n");
+       if rights & Rights.PathRemoveDirectory != cast(Rights) 0 do print("PathRemoveDirectory\n");
+       if rights & Rights.PathUnlinkFile != cast(Rights) 0 do print("PathUnlinkFile\n");
+       if rights & Rights.PollFDReadWrite != cast(Rights) 0 do print("PollFDReadWrite\n");
+       if rights & Rights.SockShutdown != cast(Rights) 0 do print("SockShutdown\n");
+}
+
+readline :: proc (buf: ^u8, bufsize: u32) -> u32 {
+       iov := IOVec.{ buf, bufsize };
+       nread : Size;
+       fd_pread(0, IOVecArray.{ ^iov, 1 }, 0l, ^nread);
+
+       return nread;
+}
+
+main :: proc #export "_start" {
+       memory_init();
+
+       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");
+
+       fd : FileDescriptor;
+       err := path_open(3,
+               cast(LookupFlags) 0,
+               "./foo.txt", 9,
+               OFlags.Creat,
+               Rights.DataSync | Rights.Write | Rights.Read | Rights.Seek | Rights.Tell | Rights.Advise | Rights.PathOpen | Rights.PathCreateFile | Rights.Seek,
+               Rights.DataSync | Rights.Write | Rights.Read | Rights.Seek | Rights.Tell | Rights.Advise | Rights.PathOpen | Rights.PathCreateFile | Rights.Seek,
+               FDFlags.Sync | FDFlags.Append,
+               ^fd);
+
+       if err != Errno.Success {
+               print("Failed to open file\n");
+               proc_exit(cast(u32) err);
+       }
+
+       print_u64_with_base(cast(u64) fd, 16l);
+       print("\n");
+
+       hello_vec := IOVec.{ buf = "Hello World!\n", len = 13 };
+       nwritten : Size;
+       if fd_write(fd, IOVecArray.{ ^hello_vec, 1 }, ^nwritten) != Errno.Success {
+               print("Failed to write to file\n");
+               proc_exit(cast(u32) 123);
+               return;
+       }
+
+       fd_close(fd);
+//
+//     if false {
+//             argc_size : Size;
+//             argv_size : Size;
+//             args_sizes_get(^argc_size, ^argv_size);
+//             print_u64_with_base(cast(u64) argc_size, 10l);
+//             print("\n");
+//             print_u64_with_base(cast(u64) argv_size, 10l);
+//             print("\n");
+//
+//             argv : ^u8;
+//             argv_buf := cast(^u8) malloc(argv_size);
+//             args_get(^argv, argv_buf);
+//             print(argv);
+//
+//             fs : FDStat;
+//             new_fd : FileDescriptor;
+//             print_u64_with_base(cast(u64) new_fd, 16l);
+//
+//             err := path_open(3,
+//                             cast(LookupFlags) 0,
+//                             "./Makefile", 10,
+//                             cast(OFlags) 0,
+//                             Rights.Read | Rights.Sync,
+//                             Rights.Read | Rights.Sync,
+//                             cast(FDFlags) 0,
+//                             ^new_fd);
+//
+//             print_u64_with_base(cast(u64) new_fd, 16l);
+//
+//             if err != Errno.Success {
+//                     print("Failed to open file\n");
+//                     proc_exit(cast(u32) err);
+//                     return;
+//             }
+//
+//             fd_fdstat_get(new_fd, ^fs);
+//             print("Rights base:\n");
+//             print_rights(fs.fs_rights_base);
+//             print("Rights inheriting:\n");
+//             print_rights(fs.fs_rights_inheriting);
+//
+//             buf : [128] u8;
+//             read_iov := IOVec.{ cast(^u8) buf, 128 };
+//             nread : Size;
+//             fd_read(new_fd, IOVecArray.{ ^read_iov, 1 }, ^nread);
+//
+//             print(string.{nread, cast(^u8) buf});
+//
+//             //hello_vec := IOVec.{ buf = "Hello World!\n", len = 13 };
+//             //nwritten : Size;
+//             //if fd_write(new_fd, IOVecArray.{ ^hello_vec, 1 }, ^nwritten) != Errno.Success {
+//             //      print("Failed to write to file\n");
+//             //      proc_exit(cast(u32) 123);
+//             //      return;
+//             //}
+//             //print_u64_with_base(cast(u64) nwritten, 10l);
+//             //fd_datasync(1);
+//             //fd_datasync(new_fd);
+//             //fd_close(new_fd);
+//     }
+}
\ No newline at end of file
index a2ca405f04f5a43afe774657c91398cffa867714..b3d2f7448422b580369eb6857646fc4d25801c4d 100644 (file)
@@ -96,7 +96,7 @@ CHECK(for, AstFor* fornode) {
     if (check_expression(&fornode->end)) return 1;
     if (check_expression(&fornode->step)) return 1;
 
-    if (fornode->var->type_node == NULL)
+    if (fornode->var->type_node == NULL || fornode->var->type_node != fornode->start->type_node)
         fornode->var->type_node = fornode->start->type_node;
     fill_in_type((AstTyped *) fornode->var);
 
index ced78907794546d35e30496d2eab1023e65243e3..69a2fd46f9ea2b899680746052c2a7e7454141bd 100644 (file)
@@ -110,6 +110,11 @@ static AstType* symres_type(AstType* type) {
         return type;
     }
 
+    if (type->kind == Ast_Kind_Enum_Type) {
+       // symres_enum((AstEnumType *) type);
+       return type;
+    }
+
     onyx_message_add(Msg_Type_Literal,
             (OnyxFilePos) { 0 },
             onyx_ast_node_kind_string(type->kind));
@@ -525,7 +530,7 @@ static void symres_enum(AstEnumType* enum_node) {
                 next_assign_value = (*value)->value->value.l;
             } else {
                 onyx_message_add(Msg_Type_Literal,
-                    (*value)->value->token->pos,
+                    (*value)->token->pos,
                     "expected numeric integer literal for enum initialization");
                 return;
             }
index e6cdc36c5aca68d554da05dfa7d198830c1e382f..c921abfe53fe5ca2832bcd05c688ddb74f11decc 100644 (file)
@@ -496,6 +496,7 @@ b32 type_is_integer(Type* type) {
 }
 
 b32 type_is_numeric(Type* type) {
+    if (type->kind == Type_Kind_Enum) return 1;
     if (type->kind != Type_Kind_Basic) return 0;
 
     return type->Basic.kind >= Basic_Kind_I8 && type->Basic.kind <= Basic_Kind_F64;
index 049d120370009f18699255bbcc736cf1239491c3..766d0c46273f1466564b54213fe34d840df181cf 100644 (file)
@@ -36,6 +36,7 @@ static const char* ast_node_names[] = {
 
     "TYPE_START (BAD)",
     "TYPE",
+    "BASIC_TYPE",
     "POINTER_TYPE",
     "FUNCTION_TYPE",
     "ARRAY TYPE",
index 0f635fdd11466b14293dcd2ea083d3c5e7b46f80..e33b3789f829c1994f710a5a3fe07a5178f38526 100644 (file)
@@ -250,6 +250,7 @@ static i32 get_element_idx(OnyxWasmModule* mod, AstFunction* func);
 static b32 local_is_wasm_local(AstLocal* local) {
     if (local->flags & Ast_Flag_Address_Taken) return 0;
     if (local->type->kind == Type_Kind_Basic) return 1;
+    if (local->type->kind == Type_Kind_Enum && local->type->Enum.backing->kind == Type_Kind_Basic) return 1;
     if (local->type->kind == Type_Kind_Pointer) return 1;
     return 0;
 }
@@ -298,6 +299,7 @@ static u64 local_allocate(LocalAllocator* la, AstLocal* local) {
     } else {
         u32 size = type_size_of(local->type);
         u32 alignment = type_alignment_of(local->type);
+
         if (size % alignment != 0)
             size += alignment - (size % alignment);
 
@@ -1500,6 +1502,9 @@ COMPILE_FUNC(cast, AstUnaryOp* cast) {
         return;
     }
 
+    if (from->kind == Type_Kind_Enum) from = from->Enum.backing;
+    if (to->kind == Type_Kind_Enum) to = to->Enum.backing;
+
     if (from->kind == Type_Kind_Basic && from->Basic.kind == Basic_Kind_Void) {
         onyx_message_add(Msg_Type_Literal,
                 cast->token->pos,