mirror of
https://github.com/zekexiao/pocketlang.git
synced 2025-02-06 12:46:53 +08:00
5aee9616c1
now it's easier to re-use cli modules into another hosting application and a little python script have added to generate native api to support native extension library.
106 lines
3.5 KiB
C
106 lines
3.5 KiB
C
/*
|
|
* Copyright (c) 2020-2022 Thakee Nathees
|
|
* Copyright (c) 2021-2022 Pocketlang Contributors
|
|
* Distributed Under The MIT License
|
|
*/
|
|
|
|
#ifndef PK_COMMON_H
|
|
#define PK_COMMON_H
|
|
|
|
#include <stdio.h> //< Only needed here for ASSERT() macro and for release mode
|
|
//< TODO; macro use this to print a crash report.
|
|
|
|
#define TOSTRING(x) #x
|
|
#define STRINGIFY(x) TOSTRING(x)
|
|
|
|
// CONCAT_LINE(X) will result evaluvated X<__LINE__>.
|
|
#define __CONCAT_LINE_INTERNAL_R(a, b) a ## b
|
|
#define __CONCAT_LINE_INTERNAL_F(a, b) __CONCAT_LINE_INTERNAL_R(a, b)
|
|
#define CONCAT_LINE(X) __CONCAT_LINE_INTERNAL_F(X, __LINE__)
|
|
|
|
// The internal assertion macro, this will print error and break regardless of
|
|
// the build target (debug or release). Use ASSERT() for debug assertion and
|
|
// use __ASSERT() for TODOs.
|
|
#define __ASSERT(condition, message) \
|
|
do { \
|
|
if (!(condition)) { \
|
|
fprintf(stderr, "Assertion failed: %s\n\tat %s() (%s:%i)\n", \
|
|
message, __func__, __FILE__, __LINE__); \
|
|
DEBUG_BREAK(); \
|
|
abort(); \
|
|
} \
|
|
} while (false)
|
|
|
|
#define NO_OP do {} while (false)
|
|
|
|
#ifdef DEBUG
|
|
|
|
#ifdef _MSC_VER
|
|
#define DEBUG_BREAK() __debugbreak()
|
|
#else
|
|
#define DEBUG_BREAK() __builtin_trap()
|
|
#endif
|
|
|
|
// This will terminate the compilation if the [condition] is false, because of
|
|
// char _assertion_failure_<__LINE__>[-1] evaluated.
|
|
#define STATIC_ASSERT(condition) \
|
|
static char CONCAT_LINE(_assertion_failure_)[2*!!(condition) - 1]
|
|
|
|
#define ASSERT(condition, message) __ASSERT(condition, message)
|
|
|
|
#define ASSERT_INDEX(index, size) \
|
|
ASSERT(index >= 0 && index < size, "Index out of bounds.")
|
|
|
|
#define UNREACHABLE() \
|
|
do { \
|
|
fprintf(stderr, "Execution reached an unreachable path\n" \
|
|
"\tat %s() (%s:%i)\n", __func__, __FILE__, __LINE__); \
|
|
DEBUG_BREAK(); \
|
|
abort(); \
|
|
} while (false)
|
|
|
|
#else
|
|
|
|
#define STATIC_ASSERT(condition) NO_OP
|
|
|
|
#define DEBUG_BREAK() NO_OP
|
|
#define ASSERT(condition, message) NO_OP
|
|
#define ASSERT_INDEX(index, size) NO_OP
|
|
|
|
#if defined(_MSC_VER)
|
|
#define UNREACHABLE() __assume(0)
|
|
#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
|
|
#define UNREACHABLE() __builtin_unreachable()
|
|
#elif defined(__EMSCRIPTEN__) || defined(__clang__)
|
|
#if __has_builtin(__builtin_unreachable)
|
|
#define UNREACHABLE() __builtin_unreachable()
|
|
#else
|
|
#define UNREACHABLE() NO_OP
|
|
#endif
|
|
#else
|
|
#define UNREACHABLE() NO_OP
|
|
#endif
|
|
|
|
#endif // DEBUG
|
|
|
|
#if defined(_MSC_VER)
|
|
#define forceinline __forceinline
|
|
#else
|
|
#define forceinline __attribute__((always_inline))
|
|
#endif
|
|
|
|
// To use dynamic variably-sized struct with a tail array add an array at the
|
|
// end of the struct with size DYNAMIC_TAIL_ARRAY. This method was a legacy
|
|
// standard called "struct hack".
|
|
#if defined(_MSC_VER) || __STDC_VERSION__ >= 199901L // stdc >= c99
|
|
#define DYNAMIC_TAIL_ARRAY
|
|
#else
|
|
#define DYNAMIC_TAIL_ARRAY 0
|
|
#endif
|
|
|
|
// Using __ASSERT() for make it crash in release binary too.
|
|
#define TODO __ASSERT(false, "TODO: It hasn't implemented yet.")
|
|
#define OOPS "Oops a bug!! report please."
|
|
|
|
#endif //PK_COMMON_H
|