#ifndef _DEFS_H_ #define _DEFS_H_ #define INT_TYPE intmax_t #define FLAG_NATIVE 0x1u #define FLAG_IMMEDIATE 0x2u #define FLAG_PARAM_WORD 0x4u #define SIZE_ARR(a) (sizeof(a) / sizeof(*(a))) #define STRIP_FINAL_NL(s) s[strcspn(s, "\r\n")] = '\0' #define unbox_exsp(ctype, type, err) (*(ctype *)unbox_ex(pop_stack(), type, err)) #define unbox_exb(box, ctype, type, err) (*(ctype *)unbox_ex(box, type, err)) #define strnil(s) ((s) == NULL || *(s) == '\0') #define UNREACHABLE() fatal_error("%s:%d: unreachable clause\n", __func__, __LINE__) #define fatal_error(fmt, ...) \ do { \ error(fmt, ##__VA_ARGS__); \ exit(EXIT_FAILURE); \ } while (0); typedef void (*dict_fn)(void); struct dict_ent { uint8_t flags; char *word_name; dict_fn nat_fn; struct comp_word *fn_def; }; struct dict_table { struct dict_table *prev; // previous environment struct dict_ent *entries; // symbols in this environment size_t level; size_t capacity; size_t used; }; struct comp_word { size_t len; size_t capacity; struct value_box *ents; }; enum comp_ent_type { CET_WORD, CET_NUMBER, CET_ADDR, }; struct value_box { enum comp_ent_type type; union { struct dict_ent *word; // pointer to a word entry in the dictionary void *addr; INT_TYPE number; }; }; void *xcalloc(size_t nmemb, size_t size); void *reallocarray(void *ptr, size_t nmemb, size_t size); #endif