Program Listing for File common.h

Return to documentation for file (src/lovejoy/common.h)

IntArray xs = AMAKE(IntArray, 5);

int elem1 = 5;
int elem2 = 3;
push(&xs, &elem1, sizeof(int));
push(&xs, &elem2, sizeof(int));

FOR_EACH(x, xs) {
    printf("%d\n", *x);
}

#ifndef COMMON_HEADER
#define COMMON_HEADER

#undef  _GNU_SOURCE
#define _GNU_SOURCE 1

#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#include <limits.h>
#include <string.h>
#include <assert.h>

/* Misc macros */
#define TSTR_HELPER(x) #x
#define TSTR(x) TSTR_HELPER(x)

/* Version number */
#define V_MAJOR 0
#define V_MINOR 1
#define V_PATCH 0

#define VERSION "v" TSTR(V_MAJOR) "." TSTR(V_MINOR) "." TSTR(V_PATCH)

#define REALLOC_FACTOR 1.5

/* Syntax helpers */
#define loop while (1)
#define unless(cond) if (!(cond))
#define until(cond) while (!(cond))
#define newtype(NT, T) typedef struct _##NT { T value; } NT
#define newarray(NT, T) typedef struct _##NT { \
    usize len; \
    usize cap; \
    T (*value);  \
} NT
#define newslice(NT, T) typedef struct _##NT { \
    usize len; \
    T (*value); \
} NT
#define newhashable(NT, T) typedef struct _##NT { \
    u64 hash; \
    T value; \
} NT
#define unqualify(D, T) typedef D T T
#define nil NULL

#define UNUSED(x) (void)(x)
#define NO_ERROR EXIT_SUCCESS;

#define PANIC(lit, ...) \
    panic("\n[**] Panicking!\n[**] CAUSE:\n -- \t%s(): " \
          lit "\n[**] Aborting...\n", __func__, ## __VA_ARGS__)
#define print(...) novel_fprintf(stdout, __VA_ARGS__)
#define println(...) novel_fprintf_newline(stdout, __VA_ARGS__)
#define eprintf(...) novel_fprintf(stderr, __VA_ARGS__)
#define eprint(...) eprintf(__VA_ARGS__)
#define eprintln(...) novel_fprintf_newline(stderr, __VA_ARGS__)

/* Types */
newtype(atomic_t, int);

typedef void u0;
#define UNIT ;

typedef int ierr;

#define __UCHAR8__ char

#if (CHAR_BIT == 8)
    typedef   signed char i8;
    typedef unsigned char u8;

    #if (CHAR_MIN < 0)
        #undef  __UCHAR8__
        #define __UCHAR8__ unsigned char
    #endif
#else
    typedef  __int8_t i8;
    typedef __uint8_t u8;

    #undef  __UCHAR8__
    #define __UCHAR8__ __uint8_t;
#endif

#ifndef IMPLEMENTATION
    typedef __UCHAR8__ byte;
#else
    typedef __uint8_t byte;
#endif

typedef unsigned char umin;
typedef   signed char imin;

typedef  __int16_t i16;
typedef __uint16_t u16;

typedef  __int32_t i32;
typedef __uint32_t u32;

typedef u32 rune;

#if (__LONG_WIDTH__ == 64)
    typedef   signed long i64;
    typedef unsigned long u64;
#elif (__LONG_LONG_WIDTH__ == 64)
    typedef   signed long long i64;
    typedef unsigned long long u64;
#else
    typedef  __int64_t i64;
    typedef __uint64_t u64;
#endif

#ifdef __SIZEOF_INT128__
    typedef  __int128_t i128;
    typedef __uint128_t u128;
#endif

typedef ptrdiff_t isize;
typedef    size_t usize;

typedef  intptr_t iptr;
typedef uintptr_t uptr;

typedef  intmax_t imax;
typedef uintmax_t umax;

#ifdef __STDC_IEC_559__
    typedef  float f32;
    typedef double f64;
#endif

#define _LDOUBLE_BIT (__SIZEOF_LONG_DOUBLE__ * CHAR_BIT)

#if (_LDOUBLE_BIT == 80)
    typedef long double f80;
#elif (_LDOUBLE_BIT == 128)
    typedef long double f128;
#endif

newarray(GenericArray, u0);
newslice(GenericSlice, u0);

newslice(string, byte);
newslice(runic, rune);

newhashable(symbol, string);

/* Common Constants */
static const byte NUL_BYTE = '\0';
static const string NUL_STRING = { .len = 0, .value = (byte *)&NUL_BYTE };

/* Common Functions */
extern u0 panic(const byte *, ...);
extern bool is_zero(imax);
extern bool is_zerof(f64);
extern bool is_zeroed(imax *, usize);
extern u0 zero(u0 *blk, usize width);
extern u0 *emalloc(usize, usize);
extern usize push(u0 *self, const u0 *element, usize width);
//                   elements that are being appended to the array.
extern usize extend(u0 *self, const u0 *slice, usize width);
extern u0 *pop(u0 *array, usize width);
extern ierr eputs(const byte *);
extern usize sizeof_specifier(const byte *);
extern string novel_vsprintf(byte *, va_list);
extern string novel_sprintf(byte *, ...);
extern ierr novel_vfprintf(FILE *, byte *, va_list);
extern ierr novel_fprintf(FILE *, byte *, ...);
extern ierr novel_fprintf_newline(FILE *, byte *, ...);
extern ierr novel_printf(byte *, ...);
extern bool string_eq(const string, const string);
extern i16 string_cmp(const string, const string);
extern u64 hash_string(const string);

/* Common Macros */

// ANSI colour code.
#define ANSI(CODE) "\x1b[" CODE "m"
#define BOLD   "1"
#define FAINT  "2"
#define ITALIC "3"
#define UNDER  "4"
#define BLINK  "5"
#define RAPID  "6"
#define INVERT "7"
#define HIDDEN "8"
#define STRIKE "9"
#define BOLD_OFF   "21"  // Or sometimes, double-underline...
#define FAINT_OFF  "22"
#define ITALIC_OFF "23"
#define UNDER_OFF  "24"
#define BLINK_OFF  "25"
#define RAPID_OFF  "26"
#define INVERT_OFF "27"
#define HIDDEN_OFF "28"
#define STRIKE_OFF "29"
#define RESET "0"

#define MIN(A, B) (((A) > (B)) ? (B) : (A))
#define MAX(A, B) (((A) > (B)) ? (A) : (B))

#define UNWRAP(STRUCTURE) (STRUCTURE).value
#define INIT(TYPE, ...) { \
    .len = sizeof((TYPE[])__VA_ARGS__)/sizeof(TYPE), \
    .value = (TYPE[])__VA_ARGS__ \
}
#define STRING(...) { \
    .len = sizeof((byte[]){ __VA_ARGS__ }) - 1, \
    .value = (byte[]){ __VA_ARGS__ } \
}

#define STR(...) ((string)STRING(__VA_ARGS__))

#define SEMPTY(TYPE) ((TYPE){ .len = 0, .value = nil })
#define AEMPTY(TYPE) ((TYPE){ .len = 0, .cap = 0, .value = nil })

#define IS_EMPTY(ARR) ((ARR).len == 0)

#define AMAKE(TYPE, CAP) { \
    .len = 0, \
    .cap = (CAP), \
    .value = emalloc((CAP), sizeof(TYPE)) \
}

#define SMAKE(TYPE, LEN) { \
    .len = (LEN), \
    .value = emalloc((LEN), sizeof(TYPE)) \
}

#define SLICE(TYPE, OBJ, START, END) ((TYPE){ \
    .len = (((isize)(END) < 0) ? (OBJ).len + 1 : 0) + (END) - (START), \
    .value = (OBJ).value + (START) \
})

#define VIEW(TYPE, PTR, START, END) ((TYPE){ \
    .len = (END) - (START), \
    .value = (PTR) + (START) \
})

#define SYMBOLIC(str) ((symbol){ \
    .hash = hash_string(str), \
    .value = str \
})

#define SYMBOL_LITERAL(STR_LIT) ((symbol){ \
    .hash = hash_string(STRING(STR_LIT)), \
    .value = STRING(STR_LIT) \
})

#define FOR_EACH(ELEM, ELEMS) \
    for (typeof((ELEMS).value) ELEM = (ELEMS).value, _frst = ELEM; \
        (usize)(ELEM - _frst) < (ELEMS).len; \
        ++ELEM)

#define foreach FOR_EACH

/* NOTES: */
/*
 * Read this: https://www.cprogramming.com/tutorial/unicode.html
 * by Jeff Bezanson, about modern unicode in C.
 *
 */
#endif