Updated grammar. Removal of elif. Removal of ':' ';' in some ct statements. Empty faults is now an error. Remove "define" for types. Remove "private". Better errors on incorrect bitstruct syntax. Introduction of wildcard type rather than optional wildcard. Removal of scaled vector type. mkdir and rmdir. Disallow define @Foo() = { @inline }. Add handling for @optreturn and change it to @return!. Restrict interface style functions. Updated x64 ABI. stdlib updates to string. Removed deprecated functions. Update how variadics are implemented. Extended error messages. x86 ABI fixes. Shift check fixes. '!' and '?' are flipped. No trailing ',' allowed in functions. Fix to string parsing. Allow l suffix. Simplifying flatpath. any replaces variant, anyfault replaces anyerr. Allow getting the underlying type of anyfault. De-duplicate string constants. Fix of readme. Extended list. Fix of "(MyEnum)x + 1". Clock and DateTime types. Fixes to array concat.

This commit is contained in:
Christoffer Lerno
2023-03-23 14:49:51 +01:00
committed by Christoffer Lerno
parent d14e778232
commit 809321e20c
270 changed files with 8777 additions and 7237 deletions

View File

@@ -61,23 +61,23 @@ extern fn int sched_yield();
fn void! NativeMutex.init(NativeMutex* mutex, MutexType type)
{
PthreadMutexAttribute attr;
if (pthread_mutexattr_init(&attr)) return ThreadFault.INIT_FAILED!;
if (pthread_mutexattr_init(&attr)) return ThreadFault.INIT_FAILED?;
defer pthread_mutexattr_destroy(&attr);
if (type & thread::MUTEX_RECURSIVE)
{
if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)) return ThreadFault.INIT_FAILED!;
if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)) return ThreadFault.INIT_FAILED?;
}
if (pthread_mutex_init(mutex, &attr)) return ThreadFault.INIT_FAILED!;
if (pthread_mutex_init(mutex, &attr)) return ThreadFault.INIT_FAILED?;
}
fn void! NativeMutex.destroy(NativeMutex* mtx)
{
if (pthread_mutex_destroy(mtx)) return ThreadFault.DESTROY_FAILED!;
if (pthread_mutex_destroy(mtx)) return ThreadFault.DESTROY_FAILED?;
}
fn void! NativeMutex.lock(NativeMutex* mtx)
{
if (pthread_mutex_lock(mtx)) return ThreadFault.LOCK_FAILED!;
if (pthread_mutex_lock(mtx)) return ThreadFault.LOCK_FAILED?;
}
fn void! NativeMutex.lock_timeoutout(NativeMutex* mtx, ulong ms)
@@ -88,7 +88,7 @@ fn void! NativeMutex.lock_timeoutout(NativeMutex* mtx, ulong ms)
{
if (!ms) break;
ulong sleep = min(5, ms);
if (!libc::nanosleep(&& TimeSpec { .s = 0, .ns = sleep * 1000_000 }, null)) return ThreadFault.LOCK_FAILED!;
if (!libc::nanosleep(&& TimeSpec { .s = 0, .ns = (CLong)sleep * 1000_000 }, null)) return ThreadFault.LOCK_FAILED?;
ms -= sleep;
}
switch (result)
@@ -97,9 +97,9 @@ fn void! NativeMutex.lock_timeoutout(NativeMutex* mtx, ulong ms)
return;
case errno::EBUSY:
case errno::ETIMEDOUT:
return ThreadFault.LOCK_TIMEOUT!;
return ThreadFault.LOCK_TIMEOUT?;
default:
return ThreadFault.LOCK_FAILED!;
return ThreadFault.LOCK_FAILED?;
}
}
@@ -110,48 +110,48 @@ fn bool NativeMutex.try_lock(NativeMutex* mtx)
fn void! NativeMutex.unlock(NativeMutex* mtx)
{
if (pthread_mutex_unlock(mtx)) return ThreadFault.UNLOCK_FAILED!;
if (pthread_mutex_unlock(mtx)) return ThreadFault.UNLOCK_FAILED?;
}
fn void! NativeConditionVariable.init(NativeConditionVariable* cond)
{
if (pthread_cond_init(cond, null)) return ThreadFault.INIT_FAILED!;
if (pthread_cond_init(cond, null)) return ThreadFault.INIT_FAILED?;
}
fn void! NativeConditionVariable.destroy(NativeConditionVariable* cond)
{
if (pthread_cond_destroy(cond)) return ThreadFault.DESTROY_FAILED!;
if (pthread_cond_destroy(cond)) return ThreadFault.DESTROY_FAILED?;
}
fn void! NativeConditionVariable.signal(NativeConditionVariable* cond)
{
if (pthread_cond_signal(cond)) return ThreadFault.SIGNAL_FAILED!;
if (pthread_cond_signal(cond)) return ThreadFault.SIGNAL_FAILED?;
}
fn void! NativeConditionVariable.broadcast(NativeConditionVariable* cond)
{
if (pthread_cond_broadcast(cond)) return ThreadFault.SIGNAL_FAILED!;
if (pthread_cond_broadcast(cond)) return ThreadFault.SIGNAL_FAILED?;
}
fn void! NativeConditionVariable.wait(NativeConditionVariable* cond, NativeMutex* mtx)
{
if (pthread_cond_wait(cond, mtx)) return ThreadFault.WAIT_FAILED!;
if (pthread_cond_wait(cond, mtx)) return ThreadFault.WAIT_FAILED?;
}
fn void! NativeConditionVariable.wait_timeout(NativeConditionVariable* cond, NativeMutex* mtx, ulong ms)
{
TimeSpec now;
if (libc::timespec_get(&now, libc::TIME_UTC) != libc::TIME_UTC) return ThreadFault.WAIT_FAILED!;
now.s += ms / 1000;
now.ns += (ms % 1000) * 1000_000;
if (libc::timespec_get(&now, libc::TIME_UTC) != libc::TIME_UTC) return ThreadFault.WAIT_FAILED?;
now.s += (Time_t)(ms / 1000);
now.ns += (CLong)((ms % 1000) * 1000_000);
switch (pthread_cond_timedwait(cond, mtx, &now))
{
case errno::ETIMEDOUT:
return ThreadFault.WAIT_TIMEOUT!;
return ThreadFault.WAIT_TIMEOUT?;
case errno::OK:
return;
default:
return ThreadFault.WAIT_FAILED!;
return ThreadFault.WAIT_FAILED?;
}
}
@@ -170,13 +170,13 @@ fn void! NativeThread.create(NativeThread* thread, ThreadFn thread_fn, void* arg
{
*thread = null;
free(thread_data);
return ThreadFault.INIT_FAILED!;
return ThreadFault.INIT_FAILED?;
}
}
fn void! NativeThread.detach(NativeThread thread)
{
if (!pthread_detach(thread)) return ThreadFault.DETACH_FAILED!;
if (!pthread_detach(thread)) return ThreadFault.DETACH_FAILED?;
}
fn void native_thread_exit(int result)
@@ -197,7 +197,7 @@ fn bool NativeThread.equals(NativeThread this, NativeThread other)
fn int! NativeThread.join(NativeThread thread)
{
void *pres;
if (pthread_join(thread, &pres)) return ThreadFault.JOIN_FAILED!;
if (pthread_join(thread, &pres)) return ThreadFault.JOIN_FAILED?;
return (int)(iptr)pres;
}
@@ -219,21 +219,21 @@ struct PosixThreadData @private
fn void! native_sleep_nano(ulong nano)
{
TimeSpec to = { .s = 0, .ns = nano };
if (libc::nanosleep(&to, null)) return ThreadFault.INTERRUPTED!;
TimeSpec to = { .s = 0, .ns = (CLong)nano };
if (libc::nanosleep(&to, null)) return ThreadFault.INTERRUPTED?;
}
fn void! native_sleep_ms(ulong ms)
{
TimeSpec to = { .s = ms / 1000, .ns = (ms % 1000) * 1000_000 };
if (libc::nanosleep(&to, null)) return ThreadFault.INTERRUPTED!;
TimeSpec to = { .s = (Time_t)(ms / 1000), .ns = (CLong)((ms % 1000) * 1000_000) };
if (libc::nanosleep(&to, null)) return ThreadFault.INTERRUPTED?;
}
fn void! native_sleep(double s)
{
ulong si = (ulong)s;
TimeSpec to = { .s = si, .ns = (ulong)((s - si) * 1000_000_000) };
if (libc::nanosleep(&to, null)) return ThreadFault.INTERRUPTED!;
Time_t si = (Time_t)s;
TimeSpec to = { .s = si, .ns = (CLong)((s - si) * 1000_000_000) };
if (libc::nanosleep(&to, null)) return ThreadFault.INTERRUPTED?;
}
$endif

View File

@@ -76,7 +76,7 @@ fn void! NativeMutex.init(NativeMutex* mtx, MutexType type)
win32_InitializeCriticalSection(&(mtx.critical_section));
return;
}
if (!(mtx.handle = win32_CreateMutex(null, false, null))) return ThreadFault.INIT_FAILED!;
if (!(mtx.handle = win32_CreateMutex(null, false, null))) return ThreadFault.INIT_FAILED?;
}
fn void! NativeMutex.destroy(NativeMutex* mtx)
@@ -86,7 +86,7 @@ fn void! NativeMutex.destroy(NativeMutex* mtx)
win32_DeleteCriticalSection(&mtx.critical_section);
return;
}
if (!win32_CloseHandle(mtx.handle)) return ThreadFault.DESTROY_FAILED!;
if (!win32_CloseHandle(mtx.handle)) return ThreadFault.DESTROY_FAILED?;
}
fn void! NativeMutex.lock(NativeMutex* mtx)
@@ -103,7 +103,7 @@ fn void! NativeMutex.lock(NativeMutex* mtx)
break;
case WAIT_ABANDONED:
default:
return ThreadFault.LOCK_FAILED!;
return ThreadFault.LOCK_FAILED?;
}
}
@@ -125,10 +125,10 @@ fn void! NativeMutex.lock_timeout(NativeMutex* mtx, uint ms)
case WAIT_OBJECT_0:
break;
case WAIT_TIMEOUT:
return ThreadFault.LOCK_TIMEOUT!;
return ThreadFault.LOCK_TIMEOUT?;
case WAIT_ABANDONED:
default:
return ThreadFault.LOCK_FAILED!;
return ThreadFault.LOCK_FAILED?;
}
if (!mtx.recursive)
{
@@ -165,7 +165,7 @@ fn void! NativeMutex.unlock(NativeMutex* mtx)
win32_LeaveCriticalSection(&mtx.critical_section);
return;
}
if (!win32_ReleaseMutex(mtx.handle)) return ThreadFault.UNLOCK_FAILED!;
if (!win32_ReleaseMutex(mtx.handle)) return ThreadFault.UNLOCK_FAILED?;
}
const int CONDITION_EVENT_ONE = 0;
@@ -179,14 +179,14 @@ fn void! NativeConditionVariable.init(NativeConditionVariable* cond)
if (!cond.event_one)
{
cond.event_all = (Win32_HANDLE)0;
return ThreadFault.INIT_FAILED!;
return ThreadFault.INIT_FAILED?;
}
cond.event_all = win32_CreateEventA(null, true, false, null);
if (!cond.event_all)
{
win32_CloseHandle(cond.event_one);
cond.event_one = (Win32_HANDLE)0;
return ThreadFault.INIT_FAILED!;
return ThreadFault.INIT_FAILED?;
}
}
@@ -202,7 +202,7 @@ fn void! NativeConditionVariable.signal(NativeConditionVariable* cond)
win32_EnterCriticalSection(&cond.waiters_count_lock);
bool have_waiters = cond.waiters_count > 0;
win32_LeaveCriticalSection(&cond.waiters_count_lock);
if (have_waiters && !win32_SetEvent(cond.event_one)) return ThreadFault.SIGNAL_FAILED!;
if (have_waiters && !win32_SetEvent(cond.event_one)) return ThreadFault.SIGNAL_FAILED?;
}
fn void! NativeConditionVariable.broadcast(NativeConditionVariable* cond)
@@ -210,7 +210,7 @@ fn void! NativeConditionVariable.broadcast(NativeConditionVariable* cond)
win32_EnterCriticalSection(&cond.waiters_count_lock);
bool have_waiters = cond.waiters_count > 0;
win32_LeaveCriticalSection(&cond.waiters_count_lock);
if (have_waiters && !win32_SetEvent(cond.event_all)) return ThreadFault.SIGNAL_FAILED!;
if (have_waiters && !win32_SetEvent(cond.event_all)) return ThreadFault.SIGNAL_FAILED?;
}
fn void! timedwait(NativeConditionVariable* cond, NativeMutex* mtx, uint timeout) @private
@@ -219,17 +219,17 @@ fn void! timedwait(NativeConditionVariable* cond, NativeMutex* mtx, uint timeout
cond.waiters_count++;
win32_LeaveCriticalSection(&cond.waiters_count_lock);
mtx.unlock()?;
mtx.unlock()!;
uint result = win32_WaitForMultipleObjects(2, &cond.events, false, timeout);
switch (result)
{
case WAIT_TIMEOUT:
mtx.lock()?;
return ThreadFault.WAIT_TIMEOUT!;
mtx.lock()!;
return ThreadFault.WAIT_TIMEOUT?;
case WAIT_FAILED:
mtx.lock()?;
return ThreadFault.WAIT_FAILED!;
mtx.lock()!;
return ThreadFault.WAIT_FAILED?;
default:
break;
}
@@ -244,12 +244,12 @@ fn void! timedwait(NativeConditionVariable* cond, NativeMutex* mtx, uint timeout
{
if (!win32_ResetEvent(cond.event_all))
{
mtx.lock()?;
return ThreadFault.WAIT_FAILED!;
mtx.lock()!;
return ThreadFault.WAIT_FAILED?;
}
}
mtx.lock()?;
mtx.lock()!;
}
fn void! NativeConditionVariable.wait(NativeConditionVariable* cond, NativeMutex* mtx) @inline
@@ -264,12 +264,12 @@ fn void! NativeConditionVariable.wait_timeout(NativeConditionVariable* cond, Nat
fn void! NativeThread.create(NativeThread* thread, ThreadFn func, void* args)
{
if (!(*thread = win32_CreateThread(null, 0, func, args, 0, null))) return ThreadFault.INIT_FAILED!;
if (!(*thread = win32_CreateThread(null, 0, func, args, 0, null))) return ThreadFault.INIT_FAILED?;
}
fn void! NativeThread.detach(NativeThread thread) @inline
{
if (!win32_CloseHandle(thread)) return ThreadFault.DETACH_FAILED!;
if (!win32_CloseHandle(thread)) return ThreadFault.DETACH_FAILED?;
}
@@ -313,8 +313,8 @@ fn void NativeOnceFlag.call_once(NativeOnceFlag* flag, OnceFn func)
fn void! NativeThread.join(NativeThread thread, int *res)
{
if (win32_WaitForSingleObject(thread, INFINITE) == WAIT_FAILED) return ThreadFault.JOIN_FAILED!;
if (!win32_GetExitCodeThread(thread, (uint*)res)) return ThreadFault.JOIN_FAILED!;
if (win32_WaitForSingleObject(thread, INFINITE) == WAIT_FAILED) return ThreadFault.JOIN_FAILED?;
if (!win32_GetExitCodeThread(thread, (uint*)res)) return ThreadFault.JOIN_FAILED?;
defer win32_CloseHandle(thread);
}
@@ -333,7 +333,7 @@ fn bool NativeThread.equals(NativeThread this, NativeThread other)
**/
fn void! native_sleep_ms(ulong ms)
{
if (win32_SleepEx((uint)ms, true) == WAIT_IO_COMPLETION) return ThreadFault.INTERRUPTED!;
if (win32_SleepEx((uint)ms, true) == WAIT_IO_COMPLETION) return ThreadFault.INTERRUPTED?;
}
fn void! native_sleep(double s)