|
- #define new(type) new type
- #define proc auto
-
- #ifdef _DEBUG
- # define if_debug if constexpr (true)
- #else
- # define if_debug if constexpr (false)
- #endif
-
-
- #ifdef _MSC_VER
- # define debug_break() if_debug __debugbreak()
- # define if_windows if constexpr (true)
- # define if_linux if constexpr (false)
- #else
- # define debug_break() if_debug raise(SIGTRAP)
- # define if_windows if constexpr (false)
- # define if_linux if constexpr (true)
- #endif
-
- #define concat_( a, b) a##b
- #define label(prefix, lnum) concat_(prefix,lnum)
-
- #define try_or_else_return(val) \
- if (1) \
- goto label(body,__LINE__); \
- else \
- while (1) \
- if (1) { \
- if (Globals::error) { \
- if (Globals::log_level == Log_Level::Debug) { \
- printf("in %s:%d\n", __FILE__, __LINE__); \
- } \
- return val; \
- } \
- break; \
- } \
- else label(body,__LINE__):
- ;
-
- #define try_struct try_or_else_return({})
- #define try_void try_or_else_return()
- #define try try_or_else_return(0)
-
- #define dont_break_on_errors fluid_let(Globals::breaking_on_errors, false)
- #define ignore_logging fluid_let(Globals::log_level, Log_Level::None)
-
- #define define_array_list(type, name) \
- \
- struct name##_Array_List { \
- type* data; \
- int length; \
- int next_index; \
- }; \
- \
- proc remove_index_from_array_list(name##_Array_List* arraylist, int index) -> void { \
- arraylist->data[index] = \
- arraylist->data[--(arraylist->next_index)]; \
- } \
- \
- proc append_to_array_list(name##_Array_List* arraylist, type element) -> void { \
- if (arraylist->next_index == arraylist->length) { \
- arraylist->length *= 2; \
- arraylist->data = \
- (type*)realloc(arraylist->data, arraylist->length * sizeof(type)); \
- } \
- arraylist->data[arraylist->next_index] = element; \
- arraylist->next_index++; \
- } \
- \
- proc _merge_array_lists(name##_Array_List* arr, int start, int mid, int end) -> void { \
- int start2 = mid + 1; \
- \
- /* If the direct merge is already sorted */ \
- if ((size_t)arr->data[mid] <= (size_t)arr->data[start2]) { \
- return; \
- } \
- \
- /* Two pointers to maintain start of both arrays to merge */ \
- while (start <= mid && start2 <= end) { \
- if ((size_t)arr->data[start] <= (size_t)arr->data[start2]) { \
- start++; \
- } \
- else { \
- type value = arr->data[start2]; \
- int index = start2; \
- \
- /* Shift all the elements between element 1; element 2, right by 1. */ \
- while (index != start) { \
- arr->data[index] = arr->data[index - 1]; \
- index--; \
- } \
- arr->data[start] = value; \
- \
- /* Update all the pointers */ \
- start++; \
- mid++; \
- start2++; \
- } \
- } \
- } \
- \
- proc sort_array_list(name##_Array_List* arraylist, int left=-1, int right=-1) -> void { \
- if (left == -1) { \
- sort_array_list(arraylist, 0, arraylist->next_index - 1); \
- return; \
- } else if (left == right) { \
- return; \
- } \
- \
- int middle = left + (right-left) / 2; \
- \
- sort_array_list(arraylist, left, middle); \
- sort_array_list(arraylist, middle+1, right); \
- \
- _merge_array_lists(arraylist, left, middle, right); \
- } \
- \
- proc sorted_array_list_find(name##_Array_List* arraylist, type elem, int left=-1, int right=-1) -> int { \
- if (left == -1) { \
- return sorted_array_list_find(arraylist, elem, 0, arraylist->next_index - 1); \
- } else if (left == right) { \
- if ((size_t)arraylist->data[left] == (size_t)elem) \
- return left; \
- return -1; \
- } else if (right < left) \
- return -1; \
- \
- int middle = left + (right-left) / 2; \
- \
- if ((size_t)arraylist->data[middle] < (size_t)elem) \
- return sorted_array_list_find(arraylist, elem, middle+1, right); \
- if ((size_t)arraylist->data[middle] > (size_t)elem) \
- return sorted_array_list_find(arraylist, elem, left, middle-1); \
- return middle; \
- } \
- \
- proc create_##name##_array_list(int initial_capacity = 16) -> name##_Array_List { \
- name##_Array_List ret; \
- ret.data = (type*)malloc(initial_capacity * sizeof(type)); \
- ret.next_index = 0; \
- ret.length = initial_capacity; \
- return ret; \
- }
-
-
- /*
- * iterate over array lists
- */
- #define for_array_list(l) \
- if (int it_index = 0); else \
- for (auto it = (l).data[0]; \
- it_index < (l).next_index; \
- it=(l).data[++it_index])
-
- /*
- * iterate over lisp vectors
- */
- #define for_lisp_vector(v) \
- if (!v); else \
- if (int it_index = 0); else \
- for (auto it = v->value.vector.data; \
- it_index < v->value.vector.length; \
- it=v->value.vector.data+(++it_index))
-
- /*
- * iterate over lisp lists
- */
- #define for_lisp_list(l) \
- if (!l); else \
- if (int it_index = 0); else \
- for (Lisp_Object* head = l, *it; \
- Memory::get_type(head) == Lisp_Object_Type::Pair && (it = head->value.pair.first); \
- head = head->value.pair.rest, ++it_index)
-
- /**
- Usage of the create_error_macros:
- */
- #define __create_error(keyword, ...) \
- create_error( \
- __FILE__, __LINE__, \
- Memory::get_or_create_lisp_object_keyword(keyword), \
- __VA_ARGS__)
-
- #define create_out_of_memory_error(...) \
- __create_error("out-of-memory", __VA_ARGS__)
-
- #define create_generic_error(...) \
- __create_error("generic", __VA_ARGS__)
-
- #define create_not_yet_implemented_error() \
- __create_error("not-yet-implemented", "This feature has not yet been implemented.")
-
- #define create_parsing_error(...) \
- __create_error("parsing-error", __VA_ARGS__)
-
- #define create_symbol_undefined_error(...) \
- __create_error("symbol-undefined", __VA_ARGS__)
-
- #define create_type_missmatch_error(expected, actual) \
- __create_error("type-missmatch", \
- "Type missmatch: expected %s, got %s", \
- expected, actual)
-
- #define create_wrong_number_of_arguments_error(expected, actual) \
- __create_error("wrong-number-of-arguments", \
- "Wrong number of arguments: expected %d, got %d", \
- expected, actual)
-
- #define create_too_many_arguments_error(expected, actual) \
- __create_error("wrong-number-of-arguments", \
- "Wrong number of arguments: expected less or equal to %d, got %d", \
- expected, actual)
-
- #define create_too_few_arguments_error(expected, actual) \
- __create_error("wrong-number-of-arguments", \
- "Wrong number of arguments: expected greater or equal to %d, got %d", \
- expected, actual)
-
-
- #define assert_arguments_length(expected, actual) \
- do { \
- if (expected != actual) { \
- create_wrong_number_of_arguments_error(expected, actual); \
- } \
- } while(0)
-
- #define assert_arguments_length_less_equal(expected, actual) \
- do { \
- if (expected < actual) { \
- create_too_many_arguments_error(expected, actual); \
- } \
- } while(0)
-
- #define assert_arguments_length_greater_equal(expected, actual) \
- do { \
- if (expected > actual) { \
- create_too_few_arguments_error(expected, actual); \
- } \
- } while(0)
-
-
- #define assert_type(_node, _type) \
- do { \
- if (Memory::get_type(_node) != _type) { \
- create_type_missmatch_error( \
- Lisp_Object_Type_to_string(_type), \
- Lisp_Object_Type_to_string(Memory::get_type(_node))); \
- } \
- } while(0)
-
- #define assert(condition) \
- do { \
- if (!(condition)) { \
- create_generic_error("Assertion-error."); \
- } \
- } while(0)
-
- /*
- #define assert(cond) \
- if_debug { \
- if (!cond) { \
- if (log_level == Log_Level::Debug) { \
- printf("Assertion failed: %s %d", __FILE__, __LINE__); \
- } \
- debug_break(); \
- } \
- } else {} \
- */
-
-
- #define console_normal "\x1B[0m"
- #define console_red "\x1B[31m"
- #define console_green "\x1B[32m"
- #define console_cyan "\x1B[36m"
- // #define console_normal ""
- // #define console_red ""
- // #define console_green ""
- // #define console_cyan ""
|