From: Brendan Hansen Date: Sat, 22 Aug 2020 16:36:14 +0000 (-0500) Subject: bugfixes and starting to integrate with wasi_unstable X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=3ef75038066d6dbb8bc214aa5aff549a5797170f;p=onyx.git bugfixes and starting to integrate with wasi_unstable --- diff --git a/.vimspector.json b/.vimspector.json index f6625bc2..5388b49c 100644 --- a/.vimspector.json +++ b/.vimspector.json @@ -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": [], diff --git a/core/string.onyx b/core/string.onyx index 8beabf83..50a21994 100644 --- a/core/string.onyx +++ b/core/string.onyx @@ -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 index 00000000..96908f0f --- /dev/null +++ b/core/wasi.onyx @@ -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 --- diff --git a/docs/plan b/docs/plan index 8bcf3262..bdc1b957 100644 --- 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 diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index 06225a02..b965794c 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -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 776bc764..7f0459b0 100755 Binary files a/onyx and b/onyx differ diff --git a/progs/stack_based.onyx b/progs/stack_based.onyx index 865e583e..4291c9f2 100644 --- a/progs/stack_based.onyx +++ b/progs/stack_based.onyx @@ -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 index 00000000..92f35ba3 --- /dev/null +++ b/progs/wasi_test.onyx @@ -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 diff --git a/src/onyxchecker.c b/src/onyxchecker.c index a2ca405f..b3d2f744 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -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); diff --git a/src/onyxsymres.c b/src/onyxsymres.c index ced78907..69a2fd46 100644 --- a/src/onyxsymres.c +++ b/src/onyxsymres.c @@ -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; } diff --git a/src/onyxtypes.c b/src/onyxtypes.c index e6cdc36c..c921abfe 100644 --- a/src/onyxtypes.c +++ b/src/onyxtypes.c @@ -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; diff --git a/src/onyxutils.c b/src/onyxutils.c index 049d1203..766d0c46 100644 --- a/src/onyxutils.c +++ b/src/onyxutils.c @@ -36,6 +36,7 @@ static const char* ast_node_names[] = { "TYPE_START (BAD)", "TYPE", + "BASIC_TYPE", "POINTER_TYPE", "FUNCTION_TYPE", "ARRAY TYPE", diff --git a/src/onyxwasm.c b/src/onyxwasm.c index 0f635fdd..e33b3789 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -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,