rutile/compiler/pre.h
2025-01-30 17:59:26 -03:00

99 lines
2.4 KiB
C

#ifndef _pre_h_
#define _pre_h_
/* Prelude file, containing some useful macros and types. */
#include <stdint.h>
#include <stddef.h>
#include <stdarg.h>
typedef int8_t i8;
typedef uint8_t u8;
typedef int16_t i16;
typedef uint16_t u16;
typedef int32_t i32;
typedef uint32_t u32;
typedef int64_t i64;
typedef uint64_t u64;
typedef float f32;
typedef double f64;
typedef uintptr_t uptr;
typedef ptrdiff_t isize;
typedef size_t usize;
typedef _Bool bool;
typedef struct {
u8 *s;
isize len;
} Str;
#define true ((bool)1)
#define false ((bool)0)
#define nil ((void *)0)
#define U64_MAX ((u64)-1)
#define Optional(T) struct {T val; bool ok;}
#define Some(T, v) (T){v, true}
#define None(T) (T){.ok = false}
/* Meant for use with stb_ds */
#define Vec(T) T *
#define HashMap(K, V) struct { K key; V value; }
#define HashMapStr(V) struct { char *key; V value; }
/* Length of an array */
#define countof(arr) (isize)(sizeof(arr) / sizeof(*(arr)))
/* Length of string literal */
#define lengthof(s) (countof(s) - 1)
#define foreach(val, arr) for(__typeof__(*(arr)) *__p = (arr), (val) = *__p; __p < (arr)+(arrlen((arr))); (val) = *(__p++))
#define foreach_getindex(val, arr) (&(val) - (arr))
/* Useful integer operations good to have. */
#define max(x, y) ((x) > (y) ? (x) : (y))
#define min(x, y) ((x) < (y) ? (x) : (y))
#define clamp(x, lo, hi) max(lo, min(x, hi))
#define BitPos(pos) (1 << (pos))
#if defined(__GNUC__) || defined(__clang__)
# define debugtrap() __builtin_trap()
# define unreachable() __builtin_unreachable()
#else /* not optimal... */
# define debugtrap() abort()
# define unreachable() abort()
#endif
#ifndef NDEBUG
# if defined (__GNUC__) || defined(__clang__)
# define Assert(pred) if (!(pred)) { __builtin_trap(); }
# else
# define Assert(pred) if (!(pred)) { *(volatile int *)0 = 0; }
# endif
# define trace(...) do { \
fprintf(stderr, "%s:%-5i", __FILE__, __LINE__); \
fprintf(stderr, __VA_ARGS__); \
} while (0)
#else
# define Assert(pred)
# define trace(...)
#endif
/* Creates a `Str` from a string literal */
#define Sl(s) ((Str){ (u8 *)s, (isize)lengthof(s) })
/* Creates a `Str` from a C string. */
#define Str_from_c(s) ((Str){ (u8 *)s, (isize)(s != nil ? strlen(s) : 0) })
#define Str_empty(s) ((s).len == 0)
#define Str_default(s, sor) (!Str_empty(s) ? (s) : (sor))
Str
Str_from_buf(u8 *buf, isize len);
char *
Str_to_c(Str s);
bool
Str_equal(Str s1, Str s2);
Str
Str_new(const u8 *data, isize len);
Str
Strafmt(const char *fmt, ...);
#endif