port os functions, add testing module
This commit is contained in:
313
src/core/core.h
313
src/core/core.h
@@ -1,297 +1,16 @@
|
||||
typedef uintptr_t usize;
|
||||
typedef uint64_t u64;
|
||||
typedef uint32_t u32;
|
||||
typedef uint16_t u16;
|
||||
typedef uint8_t u8;
|
||||
|
||||
typedef intptr_t isize;
|
||||
typedef int64_t i64;
|
||||
typedef int32_t i32;
|
||||
typedef int16_t i16;
|
||||
typedef int8_t i8;
|
||||
|
||||
typedef int64_t b64;
|
||||
typedef int32_t b32;
|
||||
typedef int16_t b16;
|
||||
typedef int8_t b8;
|
||||
|
||||
typedef float f32;
|
||||
typedef double f64;
|
||||
|
||||
#define f32_max FLT_MAX
|
||||
#define f32_min FLT_MIN
|
||||
#define f64_max DBL_MAX
|
||||
#define f64_min DBL_MIN
|
||||
|
||||
#define i8_max INT8_MAX
|
||||
#define i8_min INT8_MIN
|
||||
#define i16_max INT16_MAX
|
||||
#define i16_min INT16_MIN
|
||||
#define i32_max INT32_MAX
|
||||
#define i32_min INT32_MIN
|
||||
#define i64_max INT64_MAX
|
||||
#define i64_min INT64_MIN
|
||||
|
||||
#define u8_max UINT8_MAX
|
||||
#define u8_min 0
|
||||
#define u16_max UINT16_MAX
|
||||
#define u16_min 0
|
||||
#define u32_max UINT32_MAX
|
||||
#define u32_min 0
|
||||
#define u64_max UINT64_MAX
|
||||
#define u64_min 0
|
||||
|
||||
|
||||
#ifndef true
|
||||
#define true 1
|
||||
#endif
|
||||
#ifndef false
|
||||
#define false 0
|
||||
#endif
|
||||
|
||||
#define fn
|
||||
#define fn_test
|
||||
#define gb
|
||||
#define locl static
|
||||
|
||||
typedef union convert_f64_u64_t convert_f64_u64_t;
|
||||
union convert_f64_u64_t { f64 f; u64 i; };
|
||||
typedef union convert_f64_i64_t convert_f64_i64_t;
|
||||
union convert_f64_i64_t { f64 f; i64 i; };
|
||||
typedef union convert_f32_u32_t convert_f32_u32_t;
|
||||
union convert_f32_u32_t { f32 f; u32 i; };
|
||||
typedef union convert_f32_i32_t convert_f32_i32_t;
|
||||
union convert_f32_i32_t { f32 f; i32 i; };
|
||||
|
||||
|
||||
#define U64_TO_F64(x) (((convert_f64_u64_t) { .i = (x) }).f)
|
||||
#define U32_TO_F32(x) (((convert_f32_u32_t) { .i = (x) }).f)
|
||||
#define F64_TO_U64(x) (((convert_f64_u64_t) { .f = (x) }).i)
|
||||
#define F32_TO_U32(x) (((convert_f32_u32_t) { .f = (x) }).i)
|
||||
|
||||
#define I64_TO_F64(x) (((convert_f64_i64_t) { .i = (x) }).f)
|
||||
#define I32_TO_F32(x) (((convert_f32_i32_t) { .i = (x) }).f)
|
||||
#define F64_TO_I64(x) (((convert_f64_i64_t) { .f = (x) }).i)
|
||||
#define F32_TO_I32(x) (((convert_f32_i32_t) { .f = (x) }).i)
|
||||
|
||||
#define MIN(x,y) ((x) > (y) ? (y) : (x))
|
||||
#define MAX(x,y) ((x) > (y) ? (x) : (y))
|
||||
|
||||
#define CLAMP_TOP(A,X) MIN(A,X)
|
||||
#define CLAMP_BOT(X,B) MAX(X,B)
|
||||
#define CLAMP(x,a,b) (((x)<(a))?(a):((x)>(b))?(b):(x))
|
||||
|
||||
#define set_bit(x) (1ULL << (x))
|
||||
#define lengthof(x) (sizeof((x))/sizeof((x)[0]))
|
||||
#ifndef offsetof
|
||||
#define offsetof(st, m) ((usize)&(((st *)0)->m))
|
||||
#endif
|
||||
#define expect(x) if (!(x))
|
||||
#define unused(x) (void)(x)
|
||||
|
||||
#define kib(x) (1024ULL * (x##ULL))
|
||||
#define mib(x) (1024ULL * kib(x))
|
||||
#define gib(x) (1024ULL * mib(x))
|
||||
#define thousand(n) ((n)*1000)
|
||||
#define million(n) ((n)*1000000)
|
||||
#define billion(n) ((n)*1000000000)
|
||||
|
||||
#define zero_struct(x) memory_zero((x), sizeof(*(x)))
|
||||
|
||||
|
||||
#define defer_if(begin, cond_end) for (b32 PASTE(_i_, __LINE__) = !!begin; PASTE(_i_, __LINE__); PASTE(_i_, __LINE__) = (cond_end, 0))
|
||||
#define defer_block(begin, end) for (i32 PASTE(_i_, __LINE__) = (begin, 0); !PASTE(_i_, __LINE__); PASTE(_i_, __LINE__) += (end, 1))
|
||||
|
||||
#define stack_t(type, size) struct { type data[size]; i32 len; }
|
||||
#define STACK_CAP(stack) (lengthof((stack).data))
|
||||
#define STACK_EMPTY(stack) ((stack).len == 0)
|
||||
#define STACK_FULL(stack) ((stack).len == STACK_CAP(stack))
|
||||
#define STACK_PUSH(stack, ...) (assert(!STACK_FULL(stack)), (stack).data[(stack).len++] = __VA_ARGS__)
|
||||
#define STACK_POP(stack) (assert(!STACK_EMPTY(stack)), (stack).data[--(stack).len])
|
||||
#define STACK_TOP(stack) (assert(!STACK_EMPTY(stack)), (stack).data[((stack).len-1)])
|
||||
|
||||
#define STRINGIFY_(S) #S
|
||||
#define STRINGIFY(S) STRINGIFY_(S)
|
||||
#define PASTE_(a, b) a##b
|
||||
#define PASTE(a, b) PASTE_(a, b)
|
||||
#define SWAP(t, a, b) do { t PASTE(temp__, __LINE__) = a; a = b; b = PASTE(temp__, __LINE__); } while(0)
|
||||
#define CODE(...) #__VA_ARGS__
|
||||
|
||||
#if PLATFORM_CL || (PLATFORM_CLANG && PLATFORM_WINDOWS)
|
||||
#pragma section(".rdata$", read)
|
||||
#define gb_read_only __declspec(allocate(".rdata$"))
|
||||
#elif PLATFORM_CLANG && PLATFORM_LINUX
|
||||
#define gb_read_only __attribute__((section(".rodata")))
|
||||
#else
|
||||
#define gb_read_only
|
||||
#endif
|
||||
|
||||
#if PLATFORM_CL
|
||||
#define fn_inline __forceinline
|
||||
#elif PLATFORM_CLANG || PLATFORM_GCC
|
||||
#define fn_inline __attribute__((always_inline))
|
||||
#else
|
||||
#define fn_inline
|
||||
#endif
|
||||
|
||||
#ifndef FILE_AND_LINE_GCC_FORMAT
|
||||
#define FILE_AND_LINE __FILE__"("STRINGIFY(__LINE__)")"
|
||||
#else
|
||||
#define FILE_AND_LINE __FILE__":"STRINGIFY(__LINE__)
|
||||
#endif
|
||||
|
||||
#if PLATFORM_CL
|
||||
#define debug__break() __debugbreak()
|
||||
#else
|
||||
#define debug__break() __builtin_trap()
|
||||
#endif
|
||||
#define debug_break() (debug__break(), 0)
|
||||
|
||||
#if PLATFORM_WASM
|
||||
#define gb_thread
|
||||
#elif PLATFORM_GCC | PLATFORM_CLANG
|
||||
#define gb_thread __thread
|
||||
#elif PLATFORM_CL
|
||||
#define gb_thread __declspec(thread)
|
||||
#else
|
||||
#define gb_thread _Thread_local
|
||||
#endif
|
||||
|
||||
#if PLATFORM_CL
|
||||
#pragma warning(disable: 4116)
|
||||
#endif
|
||||
|
||||
// Single linked list Queue
|
||||
#define SLLQ_APPEND_EX(f, l, n, next) \
|
||||
do { \
|
||||
assert((n)->next == NULL); \
|
||||
if ((f) == 0) { \
|
||||
(f) = (l) = (n); \
|
||||
} else { \
|
||||
(l) = (l)->next = (n); \
|
||||
} \
|
||||
} while (0)
|
||||
#define SLLQ_APPEND(f, l, n) SLLQ_APPEND_EX(f, l, n, next)
|
||||
|
||||
#define SLLQ_PREPEND_EX(f, l, n, next) \
|
||||
do { \
|
||||
assert((n)->next == NULL); \
|
||||
if ((f) == 0) { \
|
||||
(f) = (l) = (n); \
|
||||
} else { \
|
||||
(n)->next = (f); \
|
||||
(f) = (n); \
|
||||
} \
|
||||
} while (0)
|
||||
#define SLLQ_PREPEND(f, l, n) SLLQ_PREPEND_EX(f, l, n, next)
|
||||
|
||||
#define SLLQ_REMOVE_FIRST_EX(f, l, next) \
|
||||
do { \
|
||||
if ((f) == (l)) { \
|
||||
(f) = (l) = 0; \
|
||||
} else { \
|
||||
(f) = (f)->next; \
|
||||
} \
|
||||
} while (0)
|
||||
#define SLLQ_REMOVE_FIRST(f, l) SLLQ_REMOVE_FIRST_EX(f, l, next)
|
||||
|
||||
// Singly linked list stack
|
||||
#define SLLS_PUSH_EX(stack_base, new_stack_base, next) \
|
||||
do { \
|
||||
(new_stack_base)->next = (stack_base); \
|
||||
(stack_base) = (new_stack_base); \
|
||||
} while (0)
|
||||
#define SLLS_PUSH(stack_base, new_stack_base) \
|
||||
SLLS_PUSH_EX(stack_base, new_stack_base, next)
|
||||
|
||||
#define SLLS_POP(stack_base) ((stack_base) = (stack_base)->next)
|
||||
#define SLLS_POP_AND_STORE(stack_base, out_node) \
|
||||
do { \
|
||||
if (stack_base) { \
|
||||
(out_node) = (stack_base); \
|
||||
(stack_base) = (stack_base)->next; \
|
||||
(out_node)->next = 0; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
// Doubly linked list Queue
|
||||
#define DLLQ_APPEND_EX(f, l, node, next, prev) \
|
||||
do { \
|
||||
assert((node)->next == NULL); \
|
||||
assert((node)->prev == NULL); \
|
||||
if ((f) == 0) { \
|
||||
(f) = (l) = (node); \
|
||||
} else { \
|
||||
(l)->next = (node); \
|
||||
(node)->prev = (l); \
|
||||
(l) = (node); \
|
||||
} \
|
||||
} while (0)
|
||||
#define DLLQ_APPEND(f, l, node) DLLQ_APPEND_EX(f, l, node, next, prev)
|
||||
|
||||
#define DLLQ_PREPEND_EX(f, l, node, next, prev) \
|
||||
do { \
|
||||
assert((node)->next == NULL); \
|
||||
assert((node)->prev == NULL); \
|
||||
if ((f) == 0) { \
|
||||
(f) = (l) = (node); \
|
||||
} else { \
|
||||
(node)->next = (f); \
|
||||
(f)->prev = (node); \
|
||||
(f) = (node); \
|
||||
} \
|
||||
} while (0)
|
||||
#define DLLQ_PREPEND(f, l, node) DLLQ_PREPEND_EX(f, l, node, next, prev)
|
||||
|
||||
#define DLLQ_CONTAINS(f, l, n, next, prev) for (
|
||||
|
||||
#define DLLQ_REMOVE_EX(first, last, node, next, prev) \
|
||||
do { \
|
||||
if ((first) == (last)) { \
|
||||
assert((node) == (first)); \
|
||||
(first) = (last) = 0; \
|
||||
} else if ((last) == (node)) { \
|
||||
(last) = (last)->prev; \
|
||||
(last)->next = 0; \
|
||||
} else if ((first) == (node)) { \
|
||||
(first) = (first)->next; \
|
||||
(first)->prev = 0; \
|
||||
} else { \
|
||||
(node)->prev->next = (node)->next; \
|
||||
(node)->next->prev = (node)->prev; \
|
||||
} \
|
||||
if (node) { \
|
||||
(node)->prev = 0; \
|
||||
(node)->next = 0; \
|
||||
} \
|
||||
} while (0)
|
||||
#define DLLQ_REMOVE(first, last, node) DLLQ_REMOVE_EX(first, last, node, next, prev)
|
||||
|
||||
// Doubly linked list Stack
|
||||
#define DLLS_PUSH_EX(first, node, next, prev) \
|
||||
do { \
|
||||
assert((node)->next == NULL); \
|
||||
assert((node)->prev == NULL); \
|
||||
(node)->next = (first); \
|
||||
if ((first)) \
|
||||
(first)->prev = (node); \
|
||||
(first) = (node); \
|
||||
} while (0)
|
||||
#define DLLS_PUSH(first, node) DLLS_PUSH_EX(first, node, next, prev)
|
||||
#define DLLS_REMOVE_EX(first, node, next, prev) \
|
||||
do { \
|
||||
if ((node) == (first)) { \
|
||||
(first) = (first)->next; \
|
||||
if ((first)) \
|
||||
(first)->prev = 0; \
|
||||
} else { \
|
||||
(node)->prev->next = (node)->next; \
|
||||
if ((node)->next) \
|
||||
(node)->next->prev = (node)->prev; \
|
||||
} \
|
||||
if (node) { \
|
||||
(node)->prev = 0; \
|
||||
(node)->next = 0; \
|
||||
} \
|
||||
} while (0)
|
||||
#define DLLS_REMOVE(first, node) DLLS_REMOVE_EX(first, node, next, prev)
|
||||
#include "core_platform_defines.h"
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include "core_basic.h"
|
||||
#include "core_unicode.h"
|
||||
#include "core_arena.h"
|
||||
#include "core_string.h"
|
||||
#include "core_math.h"
|
||||
#include "core_type_info.h"
|
||||
#include "core_lexer.h"
|
||||
#include "core_log.h"
|
||||
#include "core_intrin.h"
|
||||
#include "core_platform.h"
|
||||
#include "core_hash_table.h"
|
||||
#include "core_ctx.h"
|
||||
297
src/core/core_basic.h
Normal file
297
src/core/core_basic.h
Normal file
@@ -0,0 +1,297 @@
|
||||
typedef uintptr_t usize;
|
||||
typedef uint64_t u64;
|
||||
typedef uint32_t u32;
|
||||
typedef uint16_t u16;
|
||||
typedef uint8_t u8;
|
||||
|
||||
typedef intptr_t isize;
|
||||
typedef int64_t i64;
|
||||
typedef int32_t i32;
|
||||
typedef int16_t i16;
|
||||
typedef int8_t i8;
|
||||
|
||||
typedef int64_t b64;
|
||||
typedef int32_t b32;
|
||||
typedef int16_t b16;
|
||||
typedef int8_t b8;
|
||||
|
||||
typedef float f32;
|
||||
typedef double f64;
|
||||
|
||||
#define f32_max FLT_MAX
|
||||
#define f32_min FLT_MIN
|
||||
#define f64_max DBL_MAX
|
||||
#define f64_min DBL_MIN
|
||||
|
||||
#define i8_max INT8_MAX
|
||||
#define i8_min INT8_MIN
|
||||
#define i16_max INT16_MAX
|
||||
#define i16_min INT16_MIN
|
||||
#define i32_max INT32_MAX
|
||||
#define i32_min INT32_MIN
|
||||
#define i64_max INT64_MAX
|
||||
#define i64_min INT64_MIN
|
||||
|
||||
#define u8_max UINT8_MAX
|
||||
#define u8_min 0
|
||||
#define u16_max UINT16_MAX
|
||||
#define u16_min 0
|
||||
#define u32_max UINT32_MAX
|
||||
#define u32_min 0
|
||||
#define u64_max UINT64_MAX
|
||||
#define u64_min 0
|
||||
|
||||
|
||||
#ifndef true
|
||||
#define true 1
|
||||
#endif
|
||||
#ifndef false
|
||||
#define false 0
|
||||
#endif
|
||||
|
||||
#define fn
|
||||
#define fn_test
|
||||
#define gb
|
||||
#define locl static
|
||||
|
||||
typedef union convert_f64_u64_t convert_f64_u64_t;
|
||||
union convert_f64_u64_t { f64 f; u64 i; };
|
||||
typedef union convert_f64_i64_t convert_f64_i64_t;
|
||||
union convert_f64_i64_t { f64 f; i64 i; };
|
||||
typedef union convert_f32_u32_t convert_f32_u32_t;
|
||||
union convert_f32_u32_t { f32 f; u32 i; };
|
||||
typedef union convert_f32_i32_t convert_f32_i32_t;
|
||||
union convert_f32_i32_t { f32 f; i32 i; };
|
||||
|
||||
|
||||
#define U64_TO_F64(x) (((convert_f64_u64_t) { .i = (x) }).f)
|
||||
#define U32_TO_F32(x) (((convert_f32_u32_t) { .i = (x) }).f)
|
||||
#define F64_TO_U64(x) (((convert_f64_u64_t) { .f = (x) }).i)
|
||||
#define F32_TO_U32(x) (((convert_f32_u32_t) { .f = (x) }).i)
|
||||
|
||||
#define I64_TO_F64(x) (((convert_f64_i64_t) { .i = (x) }).f)
|
||||
#define I32_TO_F32(x) (((convert_f32_i32_t) { .i = (x) }).f)
|
||||
#define F64_TO_I64(x) (((convert_f64_i64_t) { .f = (x) }).i)
|
||||
#define F32_TO_I32(x) (((convert_f32_i32_t) { .f = (x) }).i)
|
||||
|
||||
#define MIN(x,y) ((x) > (y) ? (y) : (x))
|
||||
#define MAX(x,y) ((x) > (y) ? (x) : (y))
|
||||
|
||||
#define CLAMP_TOP(A,X) MIN(A,X)
|
||||
#define CLAMP_BOT(X,B) MAX(X,B)
|
||||
#define CLAMP(x,a,b) (((x)<(a))?(a):((x)>(b))?(b):(x))
|
||||
|
||||
#define set_bit(x) (1ULL << (x))
|
||||
#define lengthof(x) (sizeof((x))/sizeof((x)[0]))
|
||||
#ifndef offsetof
|
||||
#define offsetof(st, m) ((usize)&(((st *)0)->m))
|
||||
#endif
|
||||
#define expect(x) if (!(x))
|
||||
#define unused(x) (void)(x)
|
||||
|
||||
#define kib(x) (1024ULL * (x##ULL))
|
||||
#define mib(x) (1024ULL * kib(x))
|
||||
#define gib(x) (1024ULL * mib(x))
|
||||
#define thousand(n) ((n)*1000)
|
||||
#define million(n) ((n)*1000000)
|
||||
#define billion(n) ((n)*1000000000)
|
||||
|
||||
#define zero_struct(x) memory_zero((x), sizeof(*(x)))
|
||||
|
||||
|
||||
#define defer_if(begin, cond_end) for (b32 PASTE(_i_, __LINE__) = !!begin; PASTE(_i_, __LINE__); PASTE(_i_, __LINE__) = (cond_end, 0))
|
||||
#define defer_block(begin, end) for (i32 PASTE(_i_, __LINE__) = (begin, 0); !PASTE(_i_, __LINE__); PASTE(_i_, __LINE__) += (end, 1))
|
||||
|
||||
#define stack_t(type, size) struct { type data[size]; i32 len; }
|
||||
#define STACK_CAP(stack) (lengthof((stack).data))
|
||||
#define STACK_EMPTY(stack) ((stack).len == 0)
|
||||
#define STACK_FULL(stack) ((stack).len == STACK_CAP(stack))
|
||||
#define STACK_PUSH(stack, ...) (assert(!STACK_FULL(stack)), (stack).data[(stack).len++] = __VA_ARGS__)
|
||||
#define STACK_POP(stack) (assert(!STACK_EMPTY(stack)), (stack).data[--(stack).len])
|
||||
#define STACK_TOP(stack) (assert(!STACK_EMPTY(stack)), (stack).data[((stack).len-1)])
|
||||
|
||||
#define STRINGIFY_(S) #S
|
||||
#define STRINGIFY(S) STRINGIFY_(S)
|
||||
#define PASTE_(a, b) a##b
|
||||
#define PASTE(a, b) PASTE_(a, b)
|
||||
#define SWAP(t, a, b) do { t PASTE(temp__, __LINE__) = a; a = b; b = PASTE(temp__, __LINE__); } while(0)
|
||||
#define CODE(...) #__VA_ARGS__
|
||||
|
||||
#if PLATFORM_CL || (PLATFORM_CLANG && PLATFORM_WINDOWS)
|
||||
#pragma section(".rdata$", read)
|
||||
#define gb_read_only __declspec(allocate(".rdata$"))
|
||||
#elif PLATFORM_CLANG && PLATFORM_LINUX
|
||||
#define gb_read_only __attribute__((section(".rodata")))
|
||||
#else
|
||||
#define gb_read_only
|
||||
#endif
|
||||
|
||||
#if PLATFORM_CL
|
||||
#define fn_inline __forceinline
|
||||
#elif PLATFORM_CLANG || PLATFORM_GCC
|
||||
#define fn_inline __attribute__((always_inline))
|
||||
#else
|
||||
#define fn_inline
|
||||
#endif
|
||||
|
||||
#ifndef FILE_AND_LINE_GCC_FORMAT
|
||||
#define FILE_AND_LINE __FILE__"("STRINGIFY(__LINE__)")"
|
||||
#else
|
||||
#define FILE_AND_LINE __FILE__":"STRINGIFY(__LINE__)
|
||||
#endif
|
||||
|
||||
#if PLATFORM_CL
|
||||
#define debug__break() __debugbreak()
|
||||
#else
|
||||
#define debug__break() __builtin_trap()
|
||||
#endif
|
||||
#define debug_break() (debug__break(), 0)
|
||||
|
||||
#if PLATFORM_WASM
|
||||
#define gb_thread
|
||||
#elif PLATFORM_GCC | PLATFORM_CLANG
|
||||
#define gb_thread __thread
|
||||
#elif PLATFORM_CL
|
||||
#define gb_thread __declspec(thread)
|
||||
#else
|
||||
#define gb_thread _Thread_local
|
||||
#endif
|
||||
|
||||
#if PLATFORM_CL
|
||||
#pragma warning(disable: 4116)
|
||||
#endif
|
||||
|
||||
// Single linked list Queue
|
||||
#define SLLQ_APPEND_EX(f, l, n, next) \
|
||||
do { \
|
||||
assert((n)->next == NULL); \
|
||||
if ((f) == 0) { \
|
||||
(f) = (l) = (n); \
|
||||
} else { \
|
||||
(l) = (l)->next = (n); \
|
||||
} \
|
||||
} while (0)
|
||||
#define SLLQ_APPEND(f, l, n) SLLQ_APPEND_EX(f, l, n, next)
|
||||
|
||||
#define SLLQ_PREPEND_EX(f, l, n, next) \
|
||||
do { \
|
||||
assert((n)->next == NULL); \
|
||||
if ((f) == 0) { \
|
||||
(f) = (l) = (n); \
|
||||
} else { \
|
||||
(n)->next = (f); \
|
||||
(f) = (n); \
|
||||
} \
|
||||
} while (0)
|
||||
#define SLLQ_PREPEND(f, l, n) SLLQ_PREPEND_EX(f, l, n, next)
|
||||
|
||||
#define SLLQ_REMOVE_FIRST_EX(f, l, next) \
|
||||
do { \
|
||||
if ((f) == (l)) { \
|
||||
(f) = (l) = 0; \
|
||||
} else { \
|
||||
(f) = (f)->next; \
|
||||
} \
|
||||
} while (0)
|
||||
#define SLLQ_REMOVE_FIRST(f, l) SLLQ_REMOVE_FIRST_EX(f, l, next)
|
||||
|
||||
// Singly linked list stack
|
||||
#define SLLS_PUSH_EX(stack_base, new_stack_base, next) \
|
||||
do { \
|
||||
(new_stack_base)->next = (stack_base); \
|
||||
(stack_base) = (new_stack_base); \
|
||||
} while (0)
|
||||
#define SLLS_PUSH(stack_base, new_stack_base) \
|
||||
SLLS_PUSH_EX(stack_base, new_stack_base, next)
|
||||
|
||||
#define SLLS_POP(stack_base) ((stack_base) = (stack_base)->next)
|
||||
#define SLLS_POP_AND_STORE(stack_base, out_node) \
|
||||
do { \
|
||||
if (stack_base) { \
|
||||
(out_node) = (stack_base); \
|
||||
(stack_base) = (stack_base)->next; \
|
||||
(out_node)->next = 0; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
// Doubly linked list Queue
|
||||
#define DLLQ_APPEND_EX(f, l, node, next, prev) \
|
||||
do { \
|
||||
assert((node)->next == NULL); \
|
||||
assert((node)->prev == NULL); \
|
||||
if ((f) == 0) { \
|
||||
(f) = (l) = (node); \
|
||||
} else { \
|
||||
(l)->next = (node); \
|
||||
(node)->prev = (l); \
|
||||
(l) = (node); \
|
||||
} \
|
||||
} while (0)
|
||||
#define DLLQ_APPEND(f, l, node) DLLQ_APPEND_EX(f, l, node, next, prev)
|
||||
|
||||
#define DLLQ_PREPEND_EX(f, l, node, next, prev) \
|
||||
do { \
|
||||
assert((node)->next == NULL); \
|
||||
assert((node)->prev == NULL); \
|
||||
if ((f) == 0) { \
|
||||
(f) = (l) = (node); \
|
||||
} else { \
|
||||
(node)->next = (f); \
|
||||
(f)->prev = (node); \
|
||||
(f) = (node); \
|
||||
} \
|
||||
} while (0)
|
||||
#define DLLQ_PREPEND(f, l, node) DLLQ_PREPEND_EX(f, l, node, next, prev)
|
||||
|
||||
#define DLLQ_CONTAINS(f, l, n, next, prev) for (
|
||||
|
||||
#define DLLQ_REMOVE_EX(first, last, node, next, prev) \
|
||||
do { \
|
||||
if ((first) == (last)) { \
|
||||
assert((node) == (first)); \
|
||||
(first) = (last) = 0; \
|
||||
} else if ((last) == (node)) { \
|
||||
(last) = (last)->prev; \
|
||||
(last)->next = 0; \
|
||||
} else if ((first) == (node)) { \
|
||||
(first) = (first)->next; \
|
||||
(first)->prev = 0; \
|
||||
} else { \
|
||||
(node)->prev->next = (node)->next; \
|
||||
(node)->next->prev = (node)->prev; \
|
||||
} \
|
||||
if (node) { \
|
||||
(node)->prev = 0; \
|
||||
(node)->next = 0; \
|
||||
} \
|
||||
} while (0)
|
||||
#define DLLQ_REMOVE(first, last, node) DLLQ_REMOVE_EX(first, last, node, next, prev)
|
||||
|
||||
// Doubly linked list Stack
|
||||
#define DLLS_PUSH_EX(first, node, next, prev) \
|
||||
do { \
|
||||
assert((node)->next == NULL); \
|
||||
assert((node)->prev == NULL); \
|
||||
(node)->next = (first); \
|
||||
if ((first)) \
|
||||
(first)->prev = (node); \
|
||||
(first) = (node); \
|
||||
} while (0)
|
||||
#define DLLS_PUSH(first, node) DLLS_PUSH_EX(first, node, next, prev)
|
||||
#define DLLS_REMOVE_EX(first, node, next, prev) \
|
||||
do { \
|
||||
if ((node) == (first)) { \
|
||||
(first) = (first)->next; \
|
||||
if ((first)) \
|
||||
(first)->prev = 0; \
|
||||
} else { \
|
||||
(node)->prev->next = (node)->next; \
|
||||
if ((node)->next) \
|
||||
(node)->next->prev = (node)->prev; \
|
||||
} \
|
||||
if (node) { \
|
||||
(node)->prev = 0; \
|
||||
(node)->next = 0; \
|
||||
} \
|
||||
} while (0)
|
||||
#define DLLS_REMOVE(first, node) DLLS_REMOVE_EX(first, node, next, prev)
|
||||
@@ -110,3 +110,57 @@ fn s8i_t *internf(ht_t *ht, char *str, ...) {
|
||||
S8_FMT(ht->arena, str, string);
|
||||
return intern_string(ht, string);
|
||||
}
|
||||
|
||||
///////////////////////////////
|
||||
// testing
|
||||
|
||||
fn_test void test_hash_table(void) {
|
||||
ma_temp_t scratch = ma_begin_scratch();
|
||||
{
|
||||
ht_t *ht = ht_create(scratch.arena, 16);
|
||||
|
||||
for (u64 i = 0; i < 128; i += 1) {
|
||||
ht_insert_u64(ht, i, i);
|
||||
ht_node_t *node = ht_search_u64_ex(ht, i);
|
||||
assert(node->kv.value_u64 == i);
|
||||
assert(node->kv.key_u64 == i);
|
||||
}
|
||||
for (u64 i = 0; i < 128; i += 1) {
|
||||
ht_node_t *node = ht_search_u64_ex(ht, i);
|
||||
assert(node->kv.value_u64 == i);
|
||||
assert(node->kv.key_u64 == i);
|
||||
}
|
||||
|
||||
ht_node_t *node = ht_search_u64_ex(ht, 1111);
|
||||
assert(node == NULL);
|
||||
}
|
||||
{
|
||||
ht_t *ht = ht_create(scratch.arena, 16);
|
||||
|
||||
for (i32 i = 0; i < 128; i += 1) {
|
||||
s8_t s = s8_printf(scratch.arena, "%d", i);
|
||||
ht_insert_string(ht, s, s);
|
||||
ht_node_t *node = ht_search_string_ex(ht, s);
|
||||
assert(s8_are_equal(node->kv.value_string, s));
|
||||
assert(s8_are_equal(node->kv.key_string, s));
|
||||
}
|
||||
|
||||
ht_node_t *node = ht_search_string_ex(ht, s8_lit("memes"));
|
||||
assert(node == NULL);
|
||||
}
|
||||
|
||||
ma_end_scratch(scratch);
|
||||
}
|
||||
|
||||
fn_test void test_intern_table(void) {
|
||||
ma_temp_t scratch = ma_begin_scratch();
|
||||
ht_t *ht = ht_create(scratch.arena, 4);
|
||||
assert(internf(ht, "asd") == internf(ht, "asd"));
|
||||
assert(internf(ht, "asdf") != internf(ht, "asd"));
|
||||
assert(internf(ht, "asdf") == internf(ht, "asdf"));
|
||||
assert(internf(ht, "123asdf") == internf(ht, "123asdf"));
|
||||
assert(internf(ht, "123asdf") != internf(ht, "133asdf"));
|
||||
assert(internf(ht, "") == internf(ht, ""));
|
||||
assert(internf(ht, "") != internf(ht, "a"));
|
||||
ma_end_scratch(scratch);
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
#include "core_platform_defines.h"
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include "core.h"
|
||||
#include "core_unicode.h"
|
||||
#include "core_arena.h"
|
||||
#include "core_string.h"
|
||||
#include "core_math.h"
|
||||
#include "core_type_info.h"
|
||||
#include "core_lexer.h"
|
||||
#include "core_log.h"
|
||||
#include "core_intrin.h"
|
||||
#include "core_platform.h"
|
||||
#include "core_hash_table.h"
|
||||
#include "core_ctx.h"
|
||||
@@ -380,6 +380,7 @@ fn sb8_node_t *sb8_create_node(ma_arena_t *ma, s8_t str) {
|
||||
}
|
||||
|
||||
fn sb8_node_t *sb8_append(sb8_t *list, s8_t string) {
|
||||
assert(list->arena != NULL);
|
||||
sb8_node_t *node = sb8_create_node(list->arena, string);
|
||||
SLLQ_APPEND(list->first, list->last, node);
|
||||
return node;
|
||||
@@ -530,4 +531,99 @@ fn fuzzy_pair_t *fuzzy_rate_array(ma_arena_t *arena, s8_t needle, s8_t *array, i
|
||||
}
|
||||
|
||||
return pairs;
|
||||
}
|
||||
}
|
||||
|
||||
fn_test void test_s8(void) {
|
||||
ma_arena_t *arena = ma_create(ma_default_reserve_size);
|
||||
|
||||
{
|
||||
ma_temp_t temp = ma_begin_temp(arena);
|
||||
sb8_t *sb = &(sb8_t){arena};
|
||||
|
||||
s8_t memes = s8_lit("memes");
|
||||
sb8_printf(sb, "%S", memes);
|
||||
assert(sb->first == sb->last);
|
||||
assert(sb->first->len == 5);
|
||||
assert(s8_are_equal(sb->first->string, memes));
|
||||
|
||||
sb8_printf(sb, "%S", s8_lit("things are going fine"));
|
||||
s8_t string = sb8_merge(temp.arena, sb);
|
||||
assert(s8_are_equal(string, s8_lit("memesthings are going fine")));
|
||||
|
||||
ma_end_temp(temp);
|
||||
}
|
||||
|
||||
{
|
||||
s8_t str = s8_lit("thing|another|");
|
||||
sb8_t sb = s8_split(arena, str, s8_lit("|"), s8_split_none);
|
||||
|
||||
assert(s8_are_equal(sb.first->string, s8_lit("thing")));
|
||||
assert(s8_are_equal(sb.first->next->string, s8_lit("another")));
|
||||
assert(sb.first->next->next == NULL);
|
||||
}
|
||||
|
||||
{
|
||||
s8_t str = s8_lit("thing|another|");
|
||||
sb8_t sb = s8_split(arena, str, s8_lit("|"), s8_split_inclusive);
|
||||
|
||||
assert(s8_are_equal(sb.first->string, s8_lit("thing")));
|
||||
assert(s8_are_equal(sb.first->next->string, s8_lit("|")));
|
||||
assert(s8_are_equal(sb.first->next->next->string, s8_lit("another")));
|
||||
assert(s8_are_equal(sb.first->next->next->next->string, s8_lit("|")));
|
||||
assert(sb.first->next->next->next->next == NULL);
|
||||
}
|
||||
|
||||
{
|
||||
s8_t str = s8_lit("aabaaBaa");
|
||||
sb8_t sb = s8_split(arena, str, s8_lit("b"), s8_split_inclusive | s8_split_ignore_case);
|
||||
|
||||
assert(s8_are_equal(sb.first->string, s8_lit("aa")));
|
||||
assert(s8_are_equal(sb.first->next->string, s8_lit("b")));
|
||||
assert(s8_are_equal(sb.first->next->next->string, s8_lit("aa")));
|
||||
assert(s8_are_equal(sb.first->next->next->next->string, s8_lit("B")));
|
||||
assert(s8_are_equal(sb.first->next->next->next->next->string, s8_lit("aa")));
|
||||
assert(sb.first->next->next->next->next->next == NULL);
|
||||
}
|
||||
|
||||
{
|
||||
s8_t str = s8_lit("aabaaBaa");
|
||||
sb8_t sb = s8_split(arena, str, s8_lit("b"), s8_split_inclusive);
|
||||
|
||||
assert(s8_are_equal(sb.first->string, s8_lit("aa")));
|
||||
assert(s8_are_equal(sb.first->next->string, s8_lit("b")));
|
||||
assert(s8_are_equal(sb.first->next->next->string, s8_lit("aaBaa")));
|
||||
}
|
||||
|
||||
{
|
||||
s8_t s = s8_lit("0123456789");
|
||||
assert(s8_are_equal(s8_slice(s, 0, 4), s8_lit("0123")));
|
||||
assert(s8_are_equal(s8_slice(s, -2, -1), s8_lit("89")));
|
||||
assert(s8_are_equal(s8_slice(s, -2, 10), s8_lit("89")));
|
||||
assert(s8_are_equal(s8_slice(s, 8, 10), s8_lit("89")));
|
||||
}
|
||||
|
||||
{
|
||||
s8_t s = s8_lit(" a \n");
|
||||
s = s8_trim(s);
|
||||
assert(s8_are_equal(s, s8_lit("a")));
|
||||
}
|
||||
|
||||
{
|
||||
s8_t s = s8_lit("C:/memes/the_thing.c");
|
||||
s8_t ss = s8_get_name_no_ext(s);
|
||||
assert(s8_are_equal(ss, s8_lit("the_thing")));
|
||||
}
|
||||
|
||||
{
|
||||
s8_t s = s8_printf(arena, "%d%Sv%s", 32, s8_lit("|"), ">");
|
||||
assert(s8_are_equal(s, s8_lit("32|v>")));
|
||||
}
|
||||
|
||||
{
|
||||
s8_t s0 = s8_lit("0123456789");
|
||||
s8_t s1 = s8_cut_start(&s0, 2);
|
||||
assert(s8_are_equal(s0, s8_lit("23456789")));
|
||||
assert(s8_are_equal(s1, s8_lit("01")));
|
||||
}
|
||||
ma_destroy(arena);
|
||||
}
|
||||
|
||||
@@ -1,171 +0,0 @@
|
||||
#include "core/core_inc.h"
|
||||
#include "core/core_inc.c"
|
||||
|
||||
void test_s8(void) {
|
||||
ma_arena_t *arena = ma_create(ma_default_reserve_size);
|
||||
|
||||
{
|
||||
ma_temp_t temp = ma_begin_temp(arena);
|
||||
sb8_t *sb = &(sb8_t){arena};
|
||||
|
||||
s8_t memes = s8_lit("memes");
|
||||
sb8_printf(sb, "%S", memes);
|
||||
assert(sb->first == sb->last);
|
||||
assert(sb->first->len == 5);
|
||||
assert(s8_are_equal(sb->first->string, memes));
|
||||
|
||||
sb8_printf(sb, "%S", s8_lit("things are going fine"));
|
||||
s8_t string = sb8_merge(temp.arena, sb);
|
||||
assert(s8_are_equal(string, s8_lit("memesthings are going fine")));
|
||||
|
||||
ma_end_temp(temp);
|
||||
}
|
||||
|
||||
{
|
||||
s8_t str = s8_lit("thing|another|");
|
||||
sb8_t sb = s8_split(arena, str, s8_lit("|"), s8_split_none);
|
||||
|
||||
assert(s8_are_equal(sb.first->string, s8_lit("thing")));
|
||||
assert(s8_are_equal(sb.first->next->string, s8_lit("another")));
|
||||
assert(sb.first->next->next == NULL);
|
||||
}
|
||||
|
||||
{
|
||||
s8_t str = s8_lit("thing|another|");
|
||||
sb8_t sb = s8_split(arena, str, s8_lit("|"), s8_split_inclusive);
|
||||
|
||||
assert(s8_are_equal(sb.first->string, s8_lit("thing")));
|
||||
assert(s8_are_equal(sb.first->next->string, s8_lit("|")));
|
||||
assert(s8_are_equal(sb.first->next->next->string, s8_lit("another")));
|
||||
assert(s8_are_equal(sb.first->next->next->next->string, s8_lit("|")));
|
||||
assert(sb.first->next->next->next->next == NULL);
|
||||
}
|
||||
|
||||
{
|
||||
s8_t str = s8_lit("aabaaBaa");
|
||||
sb8_t sb = s8_split(arena, str, s8_lit("b"), s8_split_inclusive | s8_split_ignore_case);
|
||||
|
||||
assert(s8_are_equal(sb.first->string, s8_lit("aa")));
|
||||
assert(s8_are_equal(sb.first->next->string, s8_lit("b")));
|
||||
assert(s8_are_equal(sb.first->next->next->string, s8_lit("aa")));
|
||||
assert(s8_are_equal(sb.first->next->next->next->string, s8_lit("B")));
|
||||
assert(s8_are_equal(sb.first->next->next->next->next->string, s8_lit("aa")));
|
||||
assert(sb.first->next->next->next->next->next == NULL);
|
||||
}
|
||||
|
||||
{
|
||||
s8_t str = s8_lit("aabaaBaa");
|
||||
sb8_t sb = s8_split(arena, str, s8_lit("b"), s8_split_inclusive);
|
||||
|
||||
assert(s8_are_equal(sb.first->string, s8_lit("aa")));
|
||||
assert(s8_are_equal(sb.first->next->string, s8_lit("b")));
|
||||
assert(s8_are_equal(sb.first->next->next->string, s8_lit("aaBaa")));
|
||||
}
|
||||
|
||||
{
|
||||
s8_t s = s8_lit("0123456789");
|
||||
assert(s8_are_equal(s8_slice(s, 0, 4), s8_lit("0123")));
|
||||
assert(s8_are_equal(s8_slice(s, -2, -1), s8_lit("89")));
|
||||
assert(s8_are_equal(s8_slice(s, -2, 10), s8_lit("89")));
|
||||
assert(s8_are_equal(s8_slice(s, 8, 10), s8_lit("89")));
|
||||
}
|
||||
|
||||
{
|
||||
s8_t s = s8_lit(" a \n");
|
||||
s = s8_trim(s);
|
||||
assert(s8_are_equal(s, s8_lit("a")));
|
||||
}
|
||||
|
||||
{
|
||||
s8_t s = s8_lit("C:/memes/the_thing.c");
|
||||
s8_t ss = s8_get_name_no_ext(s);
|
||||
assert(s8_are_equal(ss, s8_lit("the_thing")));
|
||||
}
|
||||
|
||||
{
|
||||
s8_t s = s8_printf(arena, "%d%Sv%s", 32, s8_lit("|"), ">");
|
||||
assert(s8_are_equal(s, s8_lit("32|v>")));
|
||||
}
|
||||
|
||||
{
|
||||
s8_t s0 = s8_lit("0123456789");
|
||||
s8_t s1 = s8_cut_start(&s0, 2);
|
||||
assert(s8_are_equal(s0, s8_lit("23456789")));
|
||||
assert(s8_are_equal(s1, s8_lit("01")));
|
||||
}
|
||||
ma_destroy(arena);
|
||||
}
|
||||
|
||||
void test_hash_table(void) {
|
||||
ma_temp_t scratch = ma_begin_scratch();
|
||||
{
|
||||
ht_t *ht = ht_create(scratch.arena, 16);
|
||||
|
||||
for (u64 i = 0; i < 128; i += 1) {
|
||||
ht_insert_u64(ht, i, i);
|
||||
ht_node_t *node = ht_search_u64_ex(ht, i);
|
||||
assert(node->kv.value_u64 == i);
|
||||
assert(node->kv.key_u64 == i);
|
||||
}
|
||||
for (u64 i = 0; i < 128; i += 1) {
|
||||
ht_node_t *node = ht_search_u64_ex(ht, i);
|
||||
assert(node->kv.value_u64 == i);
|
||||
assert(node->kv.key_u64 == i);
|
||||
}
|
||||
|
||||
ht_node_t *node = ht_search_u64_ex(ht, 1111);
|
||||
assert(node == NULL);
|
||||
}
|
||||
{
|
||||
ht_t *ht = ht_create(scratch.arena, 16);
|
||||
|
||||
for (i32 i = 0; i < 128; i += 1) {
|
||||
s8_t s = s8_printf(scratch.arena, "%d", i);
|
||||
ht_insert_string(ht, s, s);
|
||||
ht_node_t *node = ht_search_string_ex(ht, s);
|
||||
assert(s8_are_equal(node->kv.value_string, s));
|
||||
assert(s8_are_equal(node->kv.key_string, s));
|
||||
}
|
||||
|
||||
ht_node_t *node = ht_search_string_ex(ht, s8_lit("memes"));
|
||||
assert(node == NULL);
|
||||
}
|
||||
|
||||
ma_end_scratch(scratch);
|
||||
}
|
||||
|
||||
void test_intern_table(void) {
|
||||
ma_temp_t scratch = ma_begin_scratch();
|
||||
ht_t *ht = ht_create(scratch.arena, 4);
|
||||
assert(internf(ht, "asd") == internf(ht, "asd"));
|
||||
assert(internf(ht, "asdf") != internf(ht, "asd"));
|
||||
assert(internf(ht, "asdf") == internf(ht, "asdf"));
|
||||
assert(internf(ht, "123asdf") == internf(ht, "123asdf"));
|
||||
assert(internf(ht, "123asdf") != internf(ht, "133asdf"));
|
||||
assert(internf(ht, "") == internf(ht, ""));
|
||||
assert(internf(ht, "") != internf(ht, "a"));
|
||||
ma_end_scratch(scratch);
|
||||
}
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
core_init();
|
||||
printf("PLATFORM_WASM = %d\n", PLATFORM_WASM);
|
||||
printf("PLATFORM_WINDOWS = %d\n", PLATFORM_WINDOWS);
|
||||
printf("PLATFORM_LINUX = %d\n", PLATFORM_LINUX);
|
||||
printf("PLATFORM_POSIX = %d\n", PLATFORM_POSIX);
|
||||
printf("PLATFORM_MAC_OS = %d\n", PLATFORM_MAC_OS);
|
||||
printf("PLATFORM_CLANG = %d\n", PLATFORM_CLANG);
|
||||
printf("PLATFORM_GCC = %d\n", PLATFORM_GCC);
|
||||
printf("PLATFORM_CL = %d\n", PLATFORM_CL);
|
||||
printf("PLATFORM_TCC = %d\n", PLATFORM_TCC);
|
||||
|
||||
|
||||
test_s8();
|
||||
test_hash_table();
|
||||
test_intern_table();
|
||||
|
||||
printf("all done!\n");
|
||||
}
|
||||
Reference in New Issue
Block a user