mirror of
https://github.com/Ed94/metadesk.git
synced 2026-06-12 23:51:37 -07:00
various progress
This commit is contained in:
Vendored
+4
-2
@@ -9,10 +9,12 @@
|
||||
"_DEBUG",
|
||||
"UNICODE",
|
||||
"_UNICODE",
|
||||
"MD_INTELLISENSE_DIRECTIVES"
|
||||
"INTELLISENSE_DIRECTIVES"
|
||||
],
|
||||
"windowsSdkVersion": "10.0.22621.0",
|
||||
"compilerPath": "cl.exe"
|
||||
"compilerPath": "cl.exe",
|
||||
"cStandard": "c11",
|
||||
"cppStandard": "c++17"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
|
||||
@@ -6,7 +6,7 @@ This is a fork that aims to make the latest version of metadesk available from t
|
||||
|
||||
The library will be provided in 3 forms:
|
||||
|
||||
* As-is: (the way its laid out in this repo)
|
||||
* default: (the way its laid out in this repo)
|
||||
* c11: Setup ergonomically as a c11 library (both segregtated and as a single-header)
|
||||
* cpp17: Setup ergonoically for usage as a C++ 17 library (both segregated and as a single-header)
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#ifdef MD_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "arena.h"
|
||||
#endif
|
||||
|
||||
+7
-7
@@ -1,4 +1,4 @@
|
||||
#ifdef MD_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "macros.h"
|
||||
# include "base_types.h"
|
||||
@@ -63,20 +63,20 @@ internal Arena* arena_alloc_(ArenaParams *params);
|
||||
internal void arena_release(Arena *arena);
|
||||
|
||||
//- rjf: arena push/pop/pos core functions
|
||||
internal void *arena_push(Arena *arena, U64 size, U64 align);
|
||||
internal U64 arena_pos(Arena *arena);
|
||||
internal void *arena_push (Arena *arena, U64 size, U64 align);
|
||||
internal U64 arena_pos (Arena *arena);
|
||||
internal void arena_pop_to(Arena *arena, U64 pos);
|
||||
|
||||
//- rjf: arena push/pop helpers
|
||||
internal void arena_clear(Arena *arena);
|
||||
internal void arena_pop(Arena *arena, U64 amt);
|
||||
internal void arena_pop (Arena *arena, U64 amt);
|
||||
|
||||
//- rjf: temporary arena scopes
|
||||
internal TempArena temp_arena_begin(Arena *arena);
|
||||
internal void temp_arena_end(TempArena temp);
|
||||
|
||||
//- rjf: push helper macros
|
||||
#define push_array_no_zero_aligned(a, T, c, align) (T *)arena_push((a), sizeof(T)*(c), (align))
|
||||
#define push_array_aligned(a, T, c, align) (T *)memory_zero(push_array_no_zero_aligned(a, T, c, align), sizeof(T)*(c))
|
||||
#define push_array_no_zero_aligned(a, T, c, align) (T *)arena_push((a), sizeof(T) * (c), (align))
|
||||
#define push_array_aligned(a, T, c, align) (T *)memory_zero(push_array_no_zero_aligned(a, T, c, align), sizeof(T) * (c))
|
||||
#define push_array_no_zero(a, T, c) push_array_no_zero_aligned(a, T, c, max(8, align_of(T)))
|
||||
#define push_array(a, T, c) push_array_aligned(a, T, c, max(8, align_of(T)))
|
||||
#define push_array(a, T, c) push_array_aligned (a, T, c, max(8, align_of(T)))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#ifdef MD_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "context_cracking.h"
|
||||
# include "linkage.h"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#ifdef MD_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# include "command_line.h"
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#ifdef MD_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "strings.h"
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#ifdef MD_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "context_cracking.h"
|
||||
# include "linkage.h"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#if MD_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#ifdef MD_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# include "entry_point.h"
|
||||
# include "arena.h"
|
||||
# include "thread_context.h"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#ifdef MD_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "context_cracking.h"
|
||||
# include "linkage.h"
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
#ifdef MD_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "context_cracking.h"
|
||||
#endif
|
||||
@@ -36,7 +36,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef global // Global variables
|
||||
# ifdef MD_DYN_EXPORT
|
||||
# if defined(MD_DYN_EXPORT) || defined(MD_STATIC_LINK)
|
||||
# define global
|
||||
# else
|
||||
# define global static
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#ifdef MD_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "base_types.h"
|
||||
# include "strings.h"
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
#if MD_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "context_cracking.h"
|
||||
# include "linkage.h"
|
||||
@@ -23,8 +23,8 @@
|
||||
# define expect(expr, val) (expr)
|
||||
#endif
|
||||
|
||||
#define likely(expr) expect(expr,1)
|
||||
#define unlikely(expr) expect(expr,0)
|
||||
#define likely(expr) expect(expr, 1)
|
||||
#define unlikely(expr) expect(expr, 0)
|
||||
|
||||
////////////////////////////////
|
||||
//~ erg: type casting
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#ifdef MD_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# include "markup.h"
|
||||
#endif
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#ifdef MD_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "linkage.h"
|
||||
# include "strings.h"
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#ifdef MD_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "context_cracking.h"
|
||||
# include "linkage.h"
|
||||
|
||||
+112
-82
@@ -1,4 +1,4 @@
|
||||
#ifdef MD_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "context_cracking.h"
|
||||
# include "linkage.h"
|
||||
@@ -112,12 +112,6 @@
|
||||
//~ rjf: Atomic Operations
|
||||
|
||||
#if MD_OS_WINDOWS
|
||||
|
||||
// # include <windows.h>
|
||||
// # include <tmmintrin.h>
|
||||
// # include <wmmintrin.h>
|
||||
// # include <intrin.h>
|
||||
|
||||
# if MD_ARCH_X64
|
||||
# define ins_atomic_u64_eval(x) InterlockedAdd64((volatile __int64 *)(x), 0)
|
||||
# define ins_atomic_u64_inc_eval(x) InterlockedIncrement64((volatile __int64 *)(x))
|
||||
@@ -146,16 +140,19 @@
|
||||
//~ rjf: Linked List Building Macros
|
||||
|
||||
//- rjf: linked list macro helpers
|
||||
|
||||
#define check_nil(nil,p) ((p) == 0 || (p) == nil)
|
||||
#define set_nil(nil,p) ((p) = nil)
|
||||
|
||||
//- rjf: doubly-linked-lists
|
||||
|
||||
// insert next-previous with nil
|
||||
#define dll_insert_npz(nil, f, l, p, n, next, prev) ( \
|
||||
check_nil(nil, f) ? ( \
|
||||
(f) = (l) = (n), \
|
||||
set_nil(nil, (n)->next), \
|
||||
set_nil(nil, (n)->prev) \
|
||||
) \
|
||||
(f) = (l) = (n), \
|
||||
set_nil(nil, (n)->next), \
|
||||
set_nil(nil, (n)->prev) \
|
||||
) \
|
||||
: ( \
|
||||
check_nil(nil,p) ? ( \
|
||||
(n)->next = (f), \
|
||||
@@ -164,11 +161,11 @@
|
||||
set_nil(nil,(n)->prev) \
|
||||
) \
|
||||
: ((p) == (l)) ? ( \
|
||||
(l)->next = (n), \
|
||||
(n)->prev = (l), \
|
||||
(l) = (n), \
|
||||
set_nil(nil, (n)->next) \
|
||||
) \
|
||||
(l)->next = (n), \
|
||||
(n)->prev = (l), \
|
||||
(l) = (n), \
|
||||
set_nil(nil, (n)->next) \
|
||||
) \
|
||||
: ( \
|
||||
( \
|
||||
( ! check_nil(nil, p) && check_nil(nil, (p)->next) ) ? \
|
||||
@@ -180,83 +177,116 @@
|
||||
((n)->prev = (p)) \
|
||||
) \
|
||||
) \
|
||||
) \
|
||||
|
||||
)
|
||||
// push-back next-previous with nil
|
||||
#define dll_push_back_npz(nil, f, l, n, next, prev) dll_insert_npz(nil, f, l, l, n, next, prev)
|
||||
// push-fornt next-previous with nil
|
||||
#define dll_push_front_npz(nil, f, l, n, next, prev) dll_insert_npz(nil, l, f, f, n, prev, next)
|
||||
#define dll_remove_npz(nil,f,l,n,next,prev) \
|
||||
( \
|
||||
( \
|
||||
(n) == (f) ? \
|
||||
(f) = (n)->next \
|
||||
: (0) \
|
||||
), \
|
||||
( \
|
||||
(n) == (l) ? \
|
||||
(l) = (l)->prev \
|
||||
: (0) \
|
||||
), \
|
||||
( \
|
||||
CheckNil(nil,(n)->prev) ? \
|
||||
(0) \
|
||||
: ((n)->prev->next = (n)->next) \
|
||||
), \
|
||||
( \
|
||||
CheckNil(nil,(n)->next) ? \
|
||||
(0) \
|
||||
: ((n)->next->prev = (n)->prev) \
|
||||
) \
|
||||
// remove next-previous with nil
|
||||
#define dll_remove_npz(nil, f, l, n, next, prev) \
|
||||
( \
|
||||
( \
|
||||
(n) == (f) ? \
|
||||
(f) = (n)->next \
|
||||
: (0) \
|
||||
), \
|
||||
( \
|
||||
(n) == (l) ? \
|
||||
(l) = (l)->prev \
|
||||
: (0) \
|
||||
), \
|
||||
( \
|
||||
check_nil(nil,(n)->prev) ? \
|
||||
(0) \
|
||||
: ((n)->prev->next = (n)->next) \
|
||||
), \
|
||||
( \
|
||||
check_nil(nil,(n)->next) ? \
|
||||
(0) \
|
||||
: ((n)->next->prev = (n)->prev) \
|
||||
) \
|
||||
)
|
||||
|
||||
//- rjf: singly-linked, doubly-headed lists (queues)
|
||||
#define SLLQueuePush_NZ(nil,f,l,n,next) ( \
|
||||
CheckNil(nil,f)?\
|
||||
((f)=(l)=(n),SetNil(nil,(n)->next)):\
|
||||
((l)->next=(n),(l)=(n),SetNil(nil,(n)->next)))
|
||||
#define SLLQueuePushFront_NZ(nil,f,l,n,next) (CheckNil(nil,f)?\
|
||||
((f)=(l)=(n),SetNil(nil,(n)->next)):\
|
||||
((n)->next=(f),(f)=(n)))
|
||||
#define SLLQueuePop_NZ(nil,f,l,next) ((f)==(l)?\
|
||||
(SetNil(nil,f),SetNil(nil,l)):\
|
||||
((f)=(f)->next))
|
||||
|
||||
// queue-push next with nil
|
||||
#define sll_queue_push_nz(nil, f, l, n, next) \
|
||||
( \
|
||||
check_nil(nil, f) ? ( \
|
||||
(f) = (l) = (n), \
|
||||
set_nil(nil, (n)->next) \
|
||||
) \
|
||||
: ( \
|
||||
(l)->next=(n), \
|
||||
(l) = (n), \
|
||||
set_nil(nil,(n)->next) \
|
||||
) \
|
||||
)
|
||||
// queue-push-front next with nil
|
||||
#define sll_queue_push_front_nz(nil, f, l, n, next) \
|
||||
( \
|
||||
check_nil(nil, f) ? ( \
|
||||
(f) = (l) = (n), \
|
||||
set_nil(nil,(n)->next) \
|
||||
) \
|
||||
: ( \
|
||||
(n)->next = (f), \
|
||||
(f) = (n) \
|
||||
) \
|
||||
)
|
||||
// queue-pop next with nil
|
||||
#define sll_queue_pop_nz(nil, f, l, next) \
|
||||
( \
|
||||
(f) == (l) ? ( \
|
||||
set_nil(nil,f), \
|
||||
set_nil(nil,l) \
|
||||
) \
|
||||
: ( \
|
||||
(f)=(f)->next \
|
||||
) \
|
||||
)
|
||||
|
||||
//- rjf: singly-linked, singly-headed lists (stacks)
|
||||
|
||||
#define sll_stack_push_n(f,n,next) ( (n)->next = (f), (f) = (n) )
|
||||
#define sll_stack_pop_n(f,next) ( (f) = (f)->next )
|
||||
|
||||
//- rjf: doubly-linked-list helpers
|
||||
#define dll_insert_np(f, l, p, n, next, prev) DLLInsert_NPZ (0, f, l, p, n, next, prev)
|
||||
#define dll_push_back_np(f, l, n, next, prev) DLLPushBack_NPZ (0, f, l, n, next, prev)
|
||||
#define dll_push_front_np(f, l, n, next, prev) DLLPushFront_NPZ(0, f, l, n, next, prev)
|
||||
#define dll_remove_np(f, l, n, next, prev) DLLRemove_NPZ (0, f, l, n, next, prev)
|
||||
#define dll_insert(f, l, p, n) DLLInsert_NPZ (0, f, l, p, n, next, prev)
|
||||
#define dll_push_back(f, l, n) DLLPushBack_NPZ (0, f, l, n, next, prev)
|
||||
#define dll_push_front(f, l, n) DLLPushFront_NPZ(0, f, l, n, next, prev)
|
||||
#define dll_remove(f, l, n) DLLRemove_NPZ (0, f, l, n, next, prev)
|
||||
|
||||
#define dll_insert_np(f, l, p, n, next, prev) dll_insert_npz (0, f, l, p, n, next, prev)
|
||||
#define dll_push_back_np(f, l, n, next, prev) dll_push_back_npz (0, f, l, n, next, prev)
|
||||
#define dll_push_front_np(f, l, n, next, prev) dll_push_front_npz(0, f, l, n, next, prev)
|
||||
#define dll_remove_np(f, l, n, next, prev) dll_remove_npz (0, f, l, n, next, prev)
|
||||
#define dll_insert(f, l, p, n) dll_insert_npz (0, f, l, p, n, next, prev)
|
||||
#define dll_push_back(f, l, n) dll_push_back_npz (0, f, l, n, next, prev)
|
||||
#define dll_push_front(f, l, n) dll_push_front_npz(0, f, l, n, next, prev)
|
||||
#define dll_remove(f, l, n) dll_remove_npz (0, f, l, n, next, prev)
|
||||
|
||||
//- rjf: singly-linked, doubly-headed list helpers
|
||||
#define SLLQueuePush_N(f,l,n,next) SLLQueuePush_NZ(0,f,l,n,next)
|
||||
#define SLLQueuePushFront_N(f,l,n,next) SLLQueuePushFront_NZ(0,f,l,n,next)
|
||||
#define SLLQueuePop_N(f,l,next) SLLQueuePop_NZ(0,f,l,next)
|
||||
#define SLLQueuePush(f,l,n) SLLQueuePush_NZ(0,f,l,n,next)
|
||||
#define SLLQueuePushFront(f,l,n) SLLQueuePushFront_NZ(0,f,l,n,next)
|
||||
#define SLLQueuePop(f,l) SLLQueuePop_NZ(0,f,l,next)
|
||||
|
||||
#define sll_queue_push_n(f, l, n, next) sll_queue_push_nz (0, f, l, n, next)
|
||||
#define sll_queue_push_fornt_n(f, l, n, next) sll_queue_push_front_nz(0, f, l, n, next)
|
||||
#define sll_queue_pop_n(f, l, next) sll_queue_pop_nzs (0, f, l, next)
|
||||
#define sll_queue_push(f, l, n) sll_queue_push_nz (0, f, l, n, next)
|
||||
#define sll_queue_push_front(f, l ,n) sll_queue_push_front_nz(0, f, l, n, next)
|
||||
#define sll_queue_pop(f, l) sll_queue_pop_nz (0, f, l, next)
|
||||
|
||||
//- rjf: singly-linked, singly-headed list helpers
|
||||
#define SLLStackPush(f,n) SLLStackPush_N(f,n,next)
|
||||
#define SLLStackPop(f) SLLStackPop_N(f,next)
|
||||
|
||||
#define sll_stack_push(f, n) sll_stack_push_n(f, n, next)
|
||||
#define sll_stack_pop(f) sll_stack_pop_n (f, next)
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Address Sanitizer Markup
|
||||
|
||||
#if COMPILER_MSVC
|
||||
#if MD_COMPILER_MSVC
|
||||
# if defined(__SANITIZE_ADDRESS__)
|
||||
# define ASAN_ENABLED 1
|
||||
# define NO_ASAN __declspec(no_sanitize_address)
|
||||
# else
|
||||
# define NO_ASAN
|
||||
# endif
|
||||
#elif COMPILER_CLANG
|
||||
#elif MD_COMPILER_CLANG
|
||||
# if defined(__has_feature)
|
||||
# if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
|
||||
# define ASAN_ENABLED 1
|
||||
@@ -272,18 +302,18 @@
|
||||
MD_C_API void __asan_poison_memory_region(void const volatile *addr, size_t size);
|
||||
MD_C_API void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
|
||||
|
||||
# define AsanPoisonMemoryRegion(addr, size) __asan_poison_memory_region((addr), (size))
|
||||
# define AsanUnpoisonMemoryRegion(addr, size) __asan_unpoison_memory_region((addr), (size))
|
||||
# define asan_poison_memory_region(addr, size) __asan_poison_memory_region((addr), (size))
|
||||
# define asan_unpoison_memory_region(addr, size) __asan_unpoison_memory_region((addr), (size))
|
||||
#else
|
||||
# define AsanPoisonMemoryRegion(addr, size) ((void)(addr), (void)(size))
|
||||
# define AsanUnpoisonMemoryRegion(addr, size) ((void)(addr), (void)(size))
|
||||
# define asan_poison_memory_region(addr, size) ((void)(addr), (void)(size))
|
||||
# define asan_unpoison_memory_region(addr, size) ((void)(addr), (void)(size))
|
||||
#endif
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Misc. Helper Macros
|
||||
|
||||
#define stringify_(S) #S
|
||||
#define stringify(S) Stringify_(S)
|
||||
#define stringify(S) stringify_(S)
|
||||
|
||||
#define glue_(A,B) A ## B
|
||||
#define glue(A,B) glue_(A,B)
|
||||
@@ -304,22 +334,22 @@
|
||||
|
||||
#define ptr_from_int(i) (void*)((U8*)0 + (i))
|
||||
|
||||
#define Compose64Bit(a,b) ((((U64)a) << 32) | ((U64)b));
|
||||
#define AlignPow2(x,b) (((x) + (b) - 1)&(~((b) - 1)))
|
||||
#define AlignDownPow2(x,b) ((x)&(~((b) - 1)))
|
||||
#define AlignPadPow2(x,b) ((0-(x)) & ((b) - 1))
|
||||
#define IsPow2(x) ((x)!=0 && ((x)&((x)-1))==0)
|
||||
#define IsPow2OrZero(x) ((((x) - 1)&(x)) == 0)
|
||||
#define compose_64bit(a,b) ((((U64)a) << 32) | ((U64)b));
|
||||
#define align_pow_2(x,b) (((x) + (b) - 1)&( ~((b) - 1)))
|
||||
#define align_down_pow_2(x,b) ((x) & (~((b) - 1)))
|
||||
#define align_pad_pow_2(x,b) ((0-(x)) & ((b) - 1))
|
||||
#define is_pow_2(x) ((x) != 0 && ((x )& ((x) - 1)) == 0)
|
||||
#define is_pow_2_or_zero(x) ((((x) - 1) & (x)) == 0)
|
||||
|
||||
#define ExtractBit(word, idx) (((word) >> (idx)) & 1)
|
||||
#define extract_bit(word, idx) (((word) >> (idx)) & 1)
|
||||
|
||||
#if LANG_CPP
|
||||
#if MD_LANG_CPP
|
||||
# define zero_struct {}
|
||||
#else
|
||||
# define zero_struct {0}
|
||||
#endif
|
||||
|
||||
#if COMPILER_MSVC && COMPILER_MSVC_YEAR < 2015
|
||||
#if MD_COMPILER_MSVC && MD_COMPILER_MSVC_YEAR < 2015
|
||||
# define this_function_name "unknown"
|
||||
#else
|
||||
# define this_function_name __func__
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#ifdef MD_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "context_cracking.h"
|
||||
# include "linkage.h"
|
||||
@@ -22,19 +22,20 @@
|
||||
#define MD__HAS_ZERO( x ) ( ( ( x ) - MD__ONES ) & ~( x ) & MD__HIGHS )
|
||||
|
||||
#if MD_COMPILER_MSVC || (MD_COMPILER_CLANG && MD_OS_WINDOWS)
|
||||
# pragma section(".rdata$", read)
|
||||
# define read_only __declspec(allocate(".rdata$"))
|
||||
# pragma section(".rdata$", read)
|
||||
# define read_only __declspec(allocate(".rdata$"))
|
||||
#elif (MD_COMPILER_CLANG && MD_OS_LINUX)
|
||||
# define read_only __attribute__((section(".rodata")))
|
||||
# define read_only __attribute__((section(".rodata")))
|
||||
#else
|
||||
// NOTE(rjf): I don't know of a useful way to do this in GCC land.
|
||||
// __attribute__((section(".rodata"))) looked promising, but it introduces a
|
||||
// strange warning about malformed section attributes, and it doesn't look
|
||||
// like writing to that section reliably produces access violations, strangely
|
||||
// enough. (It does on Clang)
|
||||
# define read_only
|
||||
# define read_only
|
||||
#endif
|
||||
|
||||
typedef U32 AllocType;
|
||||
enum AllocType enum_underlying(U32)
|
||||
{
|
||||
EAllocType_ALLOC,
|
||||
@@ -42,10 +43,10 @@ enum AllocType enum_underlying(U32)
|
||||
EAllocType_FREE_ALL,
|
||||
EAllocType_RESIZE,
|
||||
};
|
||||
typedef U32 AllocType;
|
||||
|
||||
typedef void*(AllocatorProc)( void* allocator_data, AllocType type, SSIZE size, SSIZE alignment, void* old_memory, SSIZE old_size, U64 flags );
|
||||
|
||||
typedef struct AllocatorInfo;
|
||||
struct AllocatorInfo
|
||||
{
|
||||
AllocatorProc* proc;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#ifdef MD_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "context_cracking.h"
|
||||
#endif
|
||||
|
||||
// C++ namespace support
|
||||
#if MD_DONT_USE_NAMESPACE || MD_LANG_C
|
||||
# if MD_COMPILER_C
|
||||
#if defined(MD_DONT_USE_NAMESPACE) || MD_LANG_C
|
||||
# if MD_LANG_C
|
||||
# define MD_NS
|
||||
# define MD_NS_BEGIN
|
||||
# define MD_NS_END
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#ifdef MD_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "platform.h"
|
||||
#endif
|
||||
|
||||
+17
-1
@@ -1,4 +1,4 @@
|
||||
#if MD_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "context_cracking.h"
|
||||
# include "linkage.h"
|
||||
@@ -10,6 +10,22 @@
|
||||
|
||||
#if defined( MD_OS_WINDOWS )
|
||||
# include <intrin.h>
|
||||
# include <tmmintrin.h>
|
||||
# include <wmmintrin.h>
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# ifndef NOMINMAX
|
||||
# define NOMINMAX
|
||||
# endif
|
||||
#
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_MEAN_AND_LEAN
|
||||
# define VC_EXTRALEAN
|
||||
# include <Windows.h>
|
||||
# endif
|
||||
# undef NOMINMAX
|
||||
# undef WIN32_LEAN_AND_MEAN
|
||||
# undef WIN32_MEAN_AND_LEAN
|
||||
# undef VC_EXTRALEAN
|
||||
#endif
|
||||
|
||||
#if MD_LANG_C
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#ifdef MD_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
|
||||
+2
-4
@@ -1,6 +1,5 @@
|
||||
#ifdef MD_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "math.h"
|
||||
#endif
|
||||
|
||||
////////////////////////////////
|
||||
@@ -58,5 +57,4 @@ typedef enum Dir2
|
||||
Dir2;
|
||||
|
||||
#define axis2_from_dir2(d) (((d) & 1) ? Axis2_Y : Axis2_X)
|
||||
#define side_from_dir2(d) (((d) < Dir2_Right) ? Side_Min : Side_Max)
|
||||
|
||||
#define side_from_dir2(d) (((d) < Dir2_Right) ? Side_Min : Side_Max)
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#ifdef MD_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
#pragma once
|
||||
#include "base/strings.h"
|
||||
#endif
|
||||
|
||||
+30
-31
@@ -1,4 +1,4 @@
|
||||
#ifdef MD_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "context_cracking.h"
|
||||
# include "linkage.h"
|
||||
@@ -7,6 +7,7 @@
|
||||
# include "base_types.h"
|
||||
# include "constants.h"
|
||||
# include "math.h"
|
||||
# include "space.h"
|
||||
# include "thread_context.h"
|
||||
# include "memory.h"
|
||||
# include "arena.h"
|
||||
@@ -27,22 +28,22 @@
|
||||
typedef struct String8 String8;
|
||||
struct String8
|
||||
{
|
||||
U8 *str;
|
||||
U64 size;
|
||||
U8 *str;
|
||||
U64 size;
|
||||
};
|
||||
|
||||
typedef struct String16 String16;
|
||||
struct String16
|
||||
{
|
||||
U16 *str;
|
||||
U64 size;
|
||||
U16 *str;
|
||||
U64 size;
|
||||
};
|
||||
|
||||
typedef struct String32 String32;
|
||||
struct String32
|
||||
{
|
||||
U32 *str;
|
||||
U64 size;
|
||||
U32 *str;
|
||||
U64 size;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
@@ -51,31 +52,31 @@ struct String32
|
||||
typedef struct String8Node String8Node;
|
||||
struct String8Node
|
||||
{
|
||||
String8Node *next;
|
||||
String8 string;
|
||||
String8Node *next;
|
||||
String8 string;
|
||||
};
|
||||
|
||||
typedef struct String8MetaNode String8MetaNode;
|
||||
struct String8MetaNode
|
||||
{
|
||||
String8MetaNode *next;
|
||||
String8Node *node;
|
||||
String8MetaNode *next;
|
||||
String8Node *node;
|
||||
};
|
||||
|
||||
typedef struct String8List String8List;
|
||||
struct String8List
|
||||
{
|
||||
String8Node *first;
|
||||
String8Node *last;
|
||||
U64 node_count;
|
||||
U64 total_size;
|
||||
String8Node *first;
|
||||
String8Node *last;
|
||||
U64 node_count;
|
||||
U64 total_size;
|
||||
};
|
||||
|
||||
typedef struct String8Array String8Array;
|
||||
struct String8Array
|
||||
{
|
||||
String8 *v;
|
||||
U64 count;
|
||||
String8 *v;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
@@ -114,9 +115,9 @@ PathStyle;
|
||||
typedef struct StringJoin StringJoin;
|
||||
struct StringJoin
|
||||
{
|
||||
String8 pre;
|
||||
String8 sep;
|
||||
String8 post;
|
||||
String8 pre;
|
||||
String8 sep;
|
||||
String8 post;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
@@ -125,8 +126,8 @@ struct StringJoin
|
||||
typedef struct UnicodeDecode UnicodeDecode;
|
||||
struct UnicodeDecode
|
||||
{
|
||||
U32 inc;
|
||||
U32 codepoint;
|
||||
U32 inc;
|
||||
U32 codepoint;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
@@ -135,18 +136,18 @@ struct UnicodeDecode
|
||||
typedef struct FuzzyMatchRangeNode FuzzyMatchRangeNode;
|
||||
struct FuzzyMatchRangeNode
|
||||
{
|
||||
FuzzyMatchRangeNode *next;
|
||||
Rng1U64 range;
|
||||
FuzzyMatchRangeNode *next;
|
||||
Rng1U64 range;
|
||||
};
|
||||
|
||||
typedef struct FuzzyMatchRangeList FuzzyMatchRangeList;
|
||||
struct FuzzyMatchRangeList
|
||||
{
|
||||
FuzzyMatchRangeNode *first;
|
||||
FuzzyMatchRangeNode *last;
|
||||
U64 count;
|
||||
U64 needle_part_count;
|
||||
U64 total_dim;
|
||||
FuzzyMatchRangeNode *first;
|
||||
FuzzyMatchRangeNode *last;
|
||||
U64 count;
|
||||
U64 needle_part_count;
|
||||
U64 total_dim;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
@@ -331,8 +332,6 @@ internal String8 string_from_elapsed_time (Arena* arena, DateTime dt);
|
||||
|
||||
internal String8 indented_from_string(Arena *arena, String8 string);
|
||||
|
||||
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: String <-> Color
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#ifdef MD_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
#include "text.h"
|
||||
#endif
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#ifdef MD_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "linkage.h"
|
||||
# include "strings.h"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#ifdef MD_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "linkage.h"
|
||||
# include "base_types.h"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#ifdef MD_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
#include "toolchain.h"
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#ifdef MD_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
@@ -35,4 +35,3 @@ typedef enum Compiler
|
||||
Compiler_COUNT,
|
||||
}
|
||||
Compiler;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#ifdef MD_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
#pragma once
|
||||
#include "base/memory.h"
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifdef MD_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
#include "mdesk.h"
|
||||
#endif
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#if MD_INTELLISENSE_DIRECTIVES
|
||||
#if INTELLISENSE_DIRECTIVES
|
||||
#pragma once
|
||||
#include "base/base_types.h"
|
||||
#include "base/math.h"
|
||||
|
||||
+5
-1
@@ -15,9 +15,13 @@
|
||||
MD_NS_BEGIN
|
||||
|
||||
#include "base/base_types.h"
|
||||
#include "base/memory_substrate.h"
|
||||
#include "base/memory.h"
|
||||
#include "base/memory_substrate.h"
|
||||
#include "base/arena.h"
|
||||
#include "base/space.h"
|
||||
#include "base/toolchain.h"
|
||||
#include "base/strings.h"
|
||||
#include "base/text.h"
|
||||
|
||||
MD_NS_END
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#ifdef MD_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
#pragma once
|
||||
#include "base/macros.h"
|
||||
#include "base/base_types.h"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#ifdef MD_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "base/cracking_arch.h"
|
||||
# include "base/cracking_compiler.h"
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
<?xml version="1.0"?>
|
||||
<N10X>
|
||||
<Workspace>
|
||||
<IncludeFilter>*.c,*.cc,*.cpp,*.c++,*.cp,*.cxx,*.h,*.hh,*.hpp,*.h++,*.hp,*.hxx,*.inl,*.cs,*.rs,*.java,*.jav,*.js,*.jsc,*.jsx,*.json,*.cls,*.py,*.rpy,*.php,*.php3,*.phl,*.phtml,*.rhtml,*.tpl,*.phps,*.lua,*.html,*.html5,*.htm,*.xml,*.xaml,*.css,*.ssi,*.haml,*.yaml,*.bat,*.wbf,*.wbt,*.txt,*.cmake,*.make,*.makefile,*.mak,*.mk,*.sh,*.bash,*.csv,*.asp,*.pl,*.mac,*.ws,*.vbs,*.perl,*.src,*.rss,*.inc,*.f,*.go,*.prl,*.plx,*.rb,*.lsp,*.lpx,*.ps1,*.command,*.cbl,*.cob,*.qs,*.wxs,*.ph,*.msc,*.glsl,*.hlsl,*.fx,*.vert,*.tesc,*.tese,*.geom,*.frag,*.comp,*.pssl,*.scons,*.cu,*.jai,</IncludeFilter>
|
||||
<ExcludeFilter></ExcludeFilter>
|
||||
<SyncFiles>true</SyncFiles>
|
||||
<Recursive>true</Recursive>
|
||||
<ShowEmptyFolders>true</ShowEmptyFolders>
|
||||
<IncludeFilesWithoutExt>false</IncludeFilesWithoutExt>
|
||||
<IsFolder>false</IsFolder>
|
||||
<BuildCommand></BuildCommand>
|
||||
<RebuildCommand></RebuildCommand>
|
||||
<BuildFileCommand></BuildFileCommand>
|
||||
<CleanCommand></CleanCommand>
|
||||
<BuildWorkingDirectory></BuildWorkingDirectory>
|
||||
<CancelBuild></CancelBuild>
|
||||
<Exe></Exe>
|
||||
<Args></Args>
|
||||
<WorkingDirectory></WorkingDirectory>
|
||||
<DebugCommand></DebugCommand>
|
||||
<DebugSln></DebugSln>
|
||||
<UseVisualStudioEnvBat>false</UseVisualStudioEnvBat>
|
||||
<CaptureExeOutput>false</CaptureExeOutput>
|
||||
<Configurations>
|
||||
<Configuration>Debug</Configuration>
|
||||
<Configuration>Release</Configuration>
|
||||
</Configurations>
|
||||
<Platforms>
|
||||
<Platform>x64</Platform>
|
||||
<Platform>Win32</Platform>
|
||||
</Platforms>
|
||||
<AdditionalIncludePaths>
|
||||
<AdditionalIncludePath>C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.42.34433\include</AdditionalIncludePath>
|
||||
<AdditionalIncludePath>C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.42.34433\ATLMFC\include</AdditionalIncludePath>
|
||||
<AdditionalIncludePath>C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Auxiliary\VS\include</AdditionalIncludePath>
|
||||
<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\10\include\10.0.22621.0\ucrt</AdditionalIncludePath>
|
||||
<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\um</AdditionalIncludePath>
|
||||
<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\shared</AdditionalIncludePath>
|
||||
<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\winrt</AdditionalIncludePath>
|
||||
<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\cppwinrt</AdditionalIncludePath>
|
||||
<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\include\um</AdditionalIncludePath>
|
||||
</AdditionalIncludePaths>
|
||||
<Defines></Defines>
|
||||
<ConfigProperties>
|
||||
<ConfigAndPlatform>
|
||||
<Name>Debug:x64</Name>
|
||||
<Defines></Defines>
|
||||
<ForceIncludes></ForceIncludes>
|
||||
</ConfigAndPlatform>
|
||||
<Config>
|
||||
<Name>Debug</Name>
|
||||
<Defines></Defines>
|
||||
</Config>
|
||||
<Platform>
|
||||
<Name>x64</Name>
|
||||
<Defines>
|
||||
<Define>__STDC__</Define>
|
||||
<Define>_MSC_VER</Define>
|
||||
<Define>_M_AMD64</Define>
|
||||
<Define>_WIN64</Define>
|
||||
<Define>INTELLISENSE_DIRECTIVES</Define>
|
||||
</Defines>
|
||||
</Platform>
|
||||
</ConfigProperties>
|
||||
<Children></Children>
|
||||
</Workspace>
|
||||
</N10X>
|
||||
Vendored
-59
@@ -1,59 +0,0 @@
|
||||
## Navigation
|
||||
|
||||
[Top](../Readme.md)
|
||||
|
||||
<- [docs - General](Readme.md)
|
||||
|
||||
## Current Design
|
||||
|
||||
`AST` is the actual managed node object for the library.
|
||||
Its raw and really not meant to be used directly.
|
||||
|
||||
All user interaction must be with its pointer so the type they deal with is `AST*`.
|
||||
In order to abstract away constant use of `AST*` its wrapped in a Code type which can be either:
|
||||
|
||||
When its the [C generated variant of the library](../gen_c_library/)
|
||||
```c
|
||||
typedef AST* Code;
|
||||
typedef AST_<name>* Code<name>;
|
||||
...
|
||||
```
|
||||
|
||||
**or**
|
||||
|
||||
For C++:
|
||||
```cpp
|
||||
struct Code {
|
||||
AST* ast;
|
||||
};
|
||||
struct Code<name> {
|
||||
...
|
||||
|
||||
AST_<name>* ast;
|
||||
};
|
||||
```
|
||||
|
||||
The full definitions of all asts are within:
|
||||
|
||||
* [`ast.hpp`](../base/components/ast.hpp)
|
||||
* [`ast_types.hpp`](../base/components/ast_types.hpp)
|
||||
* [`code_types.hpp`](../base/components/code_types.hpp)
|
||||
|
||||
The C/C++ interface procedures are located with `ast.hpp` (for the Code type), and `code_types.hpp` for all others.
|
||||
|
||||
## Serialization
|
||||
|
||||
All code types can either serialize using a function of the pattern:
|
||||
|
||||
```c
|
||||
StrBuilder <prefix>_to_strbuilder(Code code);
|
||||
// or
|
||||
<prefix>_to_strbuilder(Code code, StrBuilder& result);
|
||||
```
|
||||
|
||||
Where the first generates strings allocated using Allocator_StringArena and the other appends an existing strings with their backed allocator.
|
||||
|
||||
Serialization of for the AST is defined for `Code` in [`ast.cpp`](../base/components/ast.cpp) with `code_to_strbuilder_ptr` & `code_to_strbuilder`.
|
||||
Serializtion for the rest of the code types is within [`code_serialization.cpp`](../base/components/code_serialization.cpp).
|
||||
|
||||
Gencpp's serialization does not provide coherent formatting of the code. The user should use a formatter after serializing.
|
||||
Vendored
-788
@@ -1,788 +0,0 @@
|
||||
## Navigation
|
||||
|
||||
[Top](../Readme.md)
|
||||
|
||||
<- [docs - General](Readme.md)
|
||||
|
||||
# AST Types Documentation
|
||||
|
||||
While the Readme for docs covers the data layout per AST, this will focus on the AST types available, and their nuances.
|
||||
|
||||
## Body
|
||||
|
||||
These are containers representing a scope body of a definition that can be of the following `CodeType` type:
|
||||
|
||||
* Class_Body
|
||||
* Enum_Body
|
||||
* Export_Body
|
||||
* Extern_Linkage_Body
|
||||
* Function_Body
|
||||
* Global_Body
|
||||
* Namespace_Body
|
||||
* Struct_Body
|
||||
* Union_Body
|
||||
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
StrCached Name;
|
||||
Code Front;
|
||||
Code Back;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
s32 NumEntries;
|
||||
```
|
||||
|
||||
The `Front` member represents the start of the link list and `Back` the end.
|
||||
NumEntries is the number of entries in the body.
|
||||
|
||||
Parent should have a compatible CodeType type for the type of definition used.
|
||||
|
||||
Serialization:
|
||||
|
||||
Will output only the entries, the braces are handled by the parent.
|
||||
|
||||
```cpp
|
||||
<Front>
|
||||
...
|
||||
<Back>
|
||||
```
|
||||
|
||||
## Attributes
|
||||
|
||||
Represent standard or vendor specific C/C++ attributes.
|
||||
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
StrCached Content;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
|
||||
```cpp
|
||||
<Content>
|
||||
```
|
||||
|
||||
While the parser supports the `__declspec` and `__attribute__` syntax, the upfront constructor ( def_attributes ) must have the user specify the entire attribute, including the `[[]]`, `__declspec` or `__attribute__` parts.
|
||||
|
||||
## Comment
|
||||
|
||||
Stores a comment.
|
||||
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
StrCached Content;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
|
||||
```cpp
|
||||
<Content>
|
||||
```
|
||||
|
||||
The parser will preserve comments found if residing with a body or in accepted inline-to-definition locations.
|
||||
Otherwise they will be skipped by the TokArray::__eat and TokArray::current( skip foramtting enabled ) functions.
|
||||
|
||||
The upfront constructor: `def_comment` expects to recieve a comment without the `//` or `/* */` parts. It will add them during construction.
|
||||
|
||||
## Class & Struct
|
||||
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
CodeComment InlineCmt; // Only supported by forward declarations
|
||||
CodeAttributes Attributes;
|
||||
CodeType ParentType;
|
||||
CodeBody Body;
|
||||
StrCached Name;
|
||||
CodeType Prev;
|
||||
CodeType Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
AccessSpec ParentAccess;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
|
||||
```cpp
|
||||
// Class_Fwd
|
||||
<ModuleFlags> <class/struct> <Name>; <InlineCmt>
|
||||
|
||||
// Class
|
||||
<ModuleFlags> <class/struct> <Attributes> <Name> : <ParentAccess> <ParentType>, public <ParentType->Next>, ... <InlineCmt>
|
||||
{
|
||||
<Body>
|
||||
};
|
||||
```
|
||||
|
||||
You'll notice that only one parent type is supported only with parent access. This library only supports single inheritance, the rest are assumed to be interfaces and are given public acess specifiers.
|
||||
|
||||
## Constructor
|
||||
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
CodeComment InlineCmt; // Only supported by forward declarations
|
||||
Code InitializerList;
|
||||
CodeParams Params;
|
||||
Code Body;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
|
||||
```cpp
|
||||
// Constructor_Fwd
|
||||
<Specs> <Parent->Name>( <Params> ); <InlineCmt>
|
||||
|
||||
// Constructor
|
||||
<Specs> <Parent->Name>( <Params> ) <InlineCmt>
|
||||
: <InitializerList>
|
||||
{
|
||||
<Body>
|
||||
}
|
||||
|
||||
// Constructor Source Implementation
|
||||
<Specs> <Parent>::~<Parent->Name>( <Params> ) <Specs>
|
||||
{
|
||||
<Body>
|
||||
}
|
||||
```
|
||||
|
||||
## Define
|
||||
|
||||
Represents a preprocessor define
|
||||
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
CodeDefineParams Params;
|
||||
Code Body;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
|
||||
```cpp
|
||||
#define <Name> <Content>
|
||||
```
|
||||
|
||||
## DefineParams
|
||||
|
||||
Preprocessor define's parameters.
|
||||
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
StrCached Name;
|
||||
Code Last;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
s32 NumEntries;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
|
||||
```cpp
|
||||
<Name>, <Next> ...
|
||||
```
|
||||
|
||||
## Destructor
|
||||
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
CodeComment InlineCmt;
|
||||
CodeSpecifiers Specs;
|
||||
Code Body;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
|
||||
```cpp
|
||||
// Destructor_Fwd
|
||||
<Specs> ~<Parent->Name>( <Params> ) <Specs>; <InlineCmt>
|
||||
|
||||
// Destructor
|
||||
<Specs> ~<Parent->Name>( <Params> ) <Specs>
|
||||
{
|
||||
<Body>
|
||||
}
|
||||
|
||||
// Destructor Source Implementation
|
||||
<Specs> <Parent>::~<Parent->Name>( <Params> ) <Specs>
|
||||
{
|
||||
<Body>
|
||||
}
|
||||
```
|
||||
|
||||
## Enum
|
||||
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
CodeComment InlineCmt;
|
||||
CodeAttributes Attributes;
|
||||
CodeType UnderlyingType;
|
||||
Code UnderlyingTypeMacro;
|
||||
CodeBody Body;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
StrCached Name;
|
||||
CodeType Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
```
|
||||
|
||||
UnderlyingTypeMacro is a macro the library natively supports: `enum_underlying(type)` that is meant to behave as a wrapper for underlying type assignment.
|
||||
The `enum_underlying_sig` is a `Str` global var that can be set which will be defined within `PreprocessorDefines` and used in `parser_parse_enum` to identify a valid macro.
|
||||
|
||||
Serialization:
|
||||
|
||||
```cpp
|
||||
// Enum_Fwd
|
||||
<ModuleFlags> enum class <Name> : <UnderlyingType> or <UnderlyingTypeMacro> ; <InlineCmt>
|
||||
|
||||
// Enum
|
||||
<ModuleFlags> <enum or enum class> <Name> : <UnderlyingType> or <UnderlyingTypeMacro>
|
||||
{
|
||||
<Body>
|
||||
};
|
||||
```
|
||||
|
||||
## Execution
|
||||
|
||||
Just represents an execution body. Equivalent to an untyped body.
|
||||
Will be obsolete when function body parsing is implemented.
|
||||
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
StrCached Content;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
|
||||
```cpp
|
||||
<Content>
|
||||
```
|
||||
|
||||
## External Linkage (Extern)
|
||||
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
CodeBody Body;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
|
||||
```cpp
|
||||
extern "<Name>"
|
||||
{
|
||||
<Body>
|
||||
}
|
||||
```
|
||||
|
||||
## Include
|
||||
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
StrCached Content;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Code Parent;
|
||||
Token* Tok;
|
||||
CodeType Type;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
|
||||
```cpp
|
||||
#include <Content>
|
||||
```
|
||||
|
||||
## Friend
|
||||
|
||||
This library (until its necessary become some third-party library to do otherwise) does not support friend declarations with in-statment function definitions.
|
||||
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
CodeComment InlineCmt;
|
||||
Code Declaration;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
|
||||
```cpp
|
||||
friend <Declaration>; <InlineCmt>
|
||||
```
|
||||
|
||||
## Function
|
||||
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
CodeComment InlineCmt;
|
||||
CodeAttributes Attributes;
|
||||
CodeSpecifiers Specs;
|
||||
CodeType ReturnType;
|
||||
CodeParams Params;
|
||||
CodeBody Body;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
|
||||
```cpp
|
||||
// Function_Fwd
|
||||
<ModuleFlags> <Attributes> <Specs> <ReturnType> <Name>( <Params> ) <Specs>; <InlineCmt>
|
||||
|
||||
// Function
|
||||
<ModuleFlags> <Attributes> <Specs> <ReturnType> <Name>( <Params> ) <Specs>
|
||||
{
|
||||
<Body>
|
||||
}
|
||||
```
|
||||
|
||||
## Module
|
||||
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
|
||||
```cpp
|
||||
<ModuleFlags> module <Name>;
|
||||
```
|
||||
|
||||
## Namespace
|
||||
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
CodeBody Body;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
|
||||
```cpp
|
||||
<ModuleFlags> namespace <Name>
|
||||
{
|
||||
<Body>
|
||||
}
|
||||
```
|
||||
|
||||
## Operator Overload (Operator)
|
||||
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
CodeComment InlineCmt;
|
||||
CodeAttributes Attributes;
|
||||
CodeSpecifiers Specs;
|
||||
CodeType ReturnType;
|
||||
CodeParams Params;
|
||||
CodeBody Body;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
OperatorT Op;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
|
||||
```cpp
|
||||
// Operator_Fwd
|
||||
<ModuleFlags> <Attributes> <Specs> <ReturnType> operator <Op>( <Params> ) <Specs>; <InlineCmt>
|
||||
|
||||
// Operator
|
||||
<ModuleFlags> <Attributes> <Specs> <ReturnType> <Name>operator <Op>( <Params> ) <Specs>
|
||||
{
|
||||
<Body>
|
||||
}
|
||||
```
|
||||
|
||||
## Operator Cast Overload ( User-Defined Type Conversion, OpCast )
|
||||
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
CodeComment InlineCmt;
|
||||
CodeSpecifiers Specs;
|
||||
CodeType ValueType;
|
||||
CodeBody Body;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
|
||||
```cpp
|
||||
// Operator_Cast_Fwd
|
||||
<Specs> operator <ValueType>() <Specs>; <InlineCmt>
|
||||
|
||||
// Operator_Cast
|
||||
<Specs> <Name>operator <ValueType>() <Specs>
|
||||
{
|
||||
<Body>
|
||||
}
|
||||
```
|
||||
|
||||
## Parameters (AST_Params)
|
||||
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
CodeType ValueType;
|
||||
Code Macro;
|
||||
Code Value;
|
||||
Code PostNameMacro;
|
||||
StrCached Name;
|
||||
CodeParams Last;
|
||||
CodeParams Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
s32 NumEntries;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
|
||||
```cpp
|
||||
<Macro>, <Next> ... <Last>
|
||||
|
||||
<Macro> <ValueType> <Name> <PostNameMacro> = <Value>, <Next>... <Last>
|
||||
```
|
||||
|
||||
## Pragma
|
||||
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
StrCached Content;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
|
||||
```cpp
|
||||
#pragma <Content>
|
||||
```
|
||||
|
||||
## Preprocessor Conditional
|
||||
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
StrCached Content;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
|
||||
```cpp
|
||||
#<based off Type> <Content>
|
||||
```
|
||||
|
||||
## Specifiers
|
||||
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
SpecifierT ArrSpecs[ AST_ArrSpecs_Cap ];
|
||||
CodeSpecifiers NextSpecs;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
s32 NumEntries;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
|
||||
```cpp
|
||||
<Spec>, ...
|
||||
```
|
||||
|
||||
## Template
|
||||
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
CodeParams Params;
|
||||
Code Declaration;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
|
||||
```cpp
|
||||
<ModuleFlags>
|
||||
template< <Params> >
|
||||
<Declaration>
|
||||
```
|
||||
|
||||
## Typename
|
||||
|
||||
Typenames represent the type "symbol".
|
||||
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
CodeAttributes Attributes;
|
||||
CodeSpecifiers Specs;
|
||||
CodeReturnType ReturnType;
|
||||
CodeParams Params;
|
||||
Code ArrExpr;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
StrCached Name;
|
||||
CodeType Type;
|
||||
b32 IsParamPack;
|
||||
ETypenameTag TypeTag;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
|
||||
```cpp
|
||||
<Attributes> <TypeTag> <Name> <Specs> <IsParamPack ?: ...>
|
||||
// Function
|
||||
<Attributes> <ReturnType> <Name> <Params> <Specs>
|
||||
```
|
||||
|
||||
`<Name>` currently has the full serialization of anything with
|
||||
|
||||
*Note: ArrExpr is not used in serialization by `typename_to_strbuilder_ref` its instead handled by a parent AST's serailization (variable, typedef, using).*
|
||||
|
||||
## Typedef
|
||||
|
||||
Behave as usual except function or macro typedefs.
|
||||
Those (macros) don't use the underlying type field as everything was serialized under the Name field.
|
||||
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
CodeComment InlineCmt;
|
||||
Code UnderlyingType;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
b32 IsFunction;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
|
||||
```cpp
|
||||
// Regular
|
||||
<ModuleFlags> typedef <UnderlyingType> <Name> <UnderlyingType-ArrExpr>; <InlineCmt>
|
||||
|
||||
// Functions
|
||||
|
||||
// Currently:
|
||||
<ModuleFlags> typedef <UnderlyingType (Serialized expression)>; <InlineCmt>
|
||||
|
||||
// Desired: Not handled yet
|
||||
<ModuleFlags> typedef <UnderlyingType->ReturnType> UnderlyingType->Name> <UnderlyingType-ArrExpr> ( <UnderlyingType->Parameters> ); <InlineCmt>
|
||||
<ModuleFlags> typedef <UnderlyingType->ReturnType> ( <Name->Namespace> for<Specs->has(Spec_Ptr) ?: *> <UnderlyingType->Name> <UnderlyingType-ArrExpr> ) ( <UnderlyingType->Parameters> ); <InlineCmt>
|
||||
```
|
||||
|
||||
## Union
|
||||
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
CodeAttributes Attributes;
|
||||
CodeBody Body;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
|
||||
```cpp
|
||||
<ModuleFlags> union <Attributes> <Name>
|
||||
{
|
||||
<Body>
|
||||
}
|
||||
```
|
||||
|
||||
## Using
|
||||
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
CodeComment InlineCmt;
|
||||
CodeAttributes Attributes;
|
||||
CodeType UnderlyingType;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
|
||||
```cpp
|
||||
// Regular
|
||||
<ModuleFlags> using <Attributes> <Name> = <UnderlyingType>; <InlineCmt>
|
||||
|
||||
// Namespace
|
||||
<ModuleFlags> using namespace <Name>; <InlineCmt>
|
||||
```
|
||||
|
||||
## Variable
|
||||
|
||||
[Algo](./Parser_Algo.md:)
|
||||
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
CodeComment InlineCmt;
|
||||
CodeAttributes Attributes;
|
||||
CodeSpecifiers Specs;
|
||||
CodeType ValueType;
|
||||
Code BitfieldSize;
|
||||
Code Value;
|
||||
StrCached Name;
|
||||
CodeVar NextVar;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
s32 VarParenthesizedInit;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
|
||||
```cpp
|
||||
// Regular
|
||||
<ModuleFlags> <Attributes> <Specs> <ValueType> <Name> = <Value>, NextVar ...; <InlineCmt>
|
||||
|
||||
// Bitfield
|
||||
<ModuleFlags> <Attributes> <Specs> <ValueType> <Name> : <BitfieldSize> = <Value>, NextVar ...; <InlineCmt>
|
||||
|
||||
// VarParenthesizedInit
|
||||
<Attributes> <Specs> <ValueType> <Name>( <Value>, NextVar ... ); <InlineCmt>
|
||||
```
|
||||
Vendored
-1221
File diff suppressed because it is too large
Load Diff
Vendored
-159
@@ -1,159 +0,0 @@
|
||||
## Navigation
|
||||
|
||||
[Top](../Readme.md)
|
||||
|
||||
<- [docs - General](Readme.md)
|
||||
|
||||
# Parsing
|
||||
|
||||
The library features a naive single-pass parser, tailored for only what the library needs; for construction of C++ code into gencpp's AST for *"front-end"* meta-programming purposes.
|
||||
|
||||
This parser does not, and should not do the compiler's job. By only supporting this minimal set of features, the parser is kept (so far) around ~7000 loc. I hope to keep it under 10-15k loc worst case.
|
||||
|
||||
You can think of this parser as *frontend parser* vs a *semantic parser*. Its intuitively similar to WYSIWYG. What you ***perceive*** as the syntax from the user-side before the compiler gets a hold of it, is what you get.
|
||||
|
||||
User exposed interface:
|
||||
|
||||
```cpp
|
||||
CodeClass parse_class ( Str class_def );
|
||||
CodeConstructor parse_constructor ( Str constructor_def );
|
||||
CodeDefine parse_define ( Str define_def );
|
||||
CodeDestructor parse_destructor ( Str destructor_def );
|
||||
CodeEnum parse_enum ( Str enum_def );
|
||||
CodeBody parse_export_body ( Str export_def );
|
||||
CodeExtern parse_extern_link ( Str exten_link_def );
|
||||
CodeFriend parse_friend ( Str friend_def );
|
||||
CodeFn parse_function ( Str fn_def );
|
||||
CodeBody parse_global_body ( Str body_def );
|
||||
CodeNS parse_namespace ( Str namespace_def );
|
||||
CodeOperator parse_operator ( Str operator_def );
|
||||
CodeOpCast parse_operator_cast( Str operator_def );
|
||||
CodeStruct parse_struct ( Str struct_def );
|
||||
CodeTemplate parse_template ( Str template_def );
|
||||
CodeType parse_type ( Str type_def );
|
||||
CodeTypedef parse_typedef ( Str typedef_def );
|
||||
CodeUnion parse_union ( Str union_def );
|
||||
CodeUsing parse_using ( Str using_def );
|
||||
CodeVar parse_variable ( Str var_def );
|
||||
```
|
||||
|
||||
To parse file buffers, use the `parse_global_body` function.
|
||||
|
||||
***Parsing will aggregate any tokens within a function body or expression statement to an untyped Code AST.***
|
||||
|
||||
Everything is done in one pass for both the preprocessor directives and the rest of the language.
|
||||
The parser performs no macro expansion as the scope of gencpp feature-set is to only support the preprocessor for the goal of having rudimentary awareness of preprocessor ***conditionals***, ***defines***, ***includes***, and ***pragmas***.
|
||||
|
||||
The keywords supported for the preprocessor are:
|
||||
|
||||
* include
|
||||
* define
|
||||
* if
|
||||
* ifdef
|
||||
* elif
|
||||
* endif
|
||||
* pragma
|
||||
|
||||
Each directive `#` line is considered one preproecessor unit, and will be treated as one Preprocessor AST node.
|
||||
If a directive is used with an unsupported keyword its will be processed as an untyped AST.
|
||||
|
||||
The preprocessor lines are stored as members of their associated scope they are parsed within ( Global, Namespace, Class/Struct ).
|
||||
***Again: These ASTs will be considered members or entries of braced scope they reside within***
|
||||
|
||||
Any preprocessor definition abuse that changes the syntax of the core language is unsupported and will fail to parse if not kept within an execution scope (function body, or expression assignment).
|
||||
Exceptions:
|
||||
|
||||
* variable definitions are allowed for a preprocessed macro `extern MACRO();`
|
||||
* function definitions are allowed for a preprocessed macro: `neverinline MACRO() { ... }`
|
||||
* Disable with: `#define GEN_PARSER_DISABLE_MACRO_FUNCTION_SIGNATURES`
|
||||
* typedefs allow for a preprocessed macro: `typedef MACRO();`
|
||||
* Disable with: `#define GEN_PARSER_DISABLE_MACRO_TYPEDEF`
|
||||
* Macros can behave as typenames
|
||||
* There is some macro support in parameters for functions or templates *(Specifically added to support parsing Unreal Engine source)*.
|
||||
|
||||
*(Exceptions are added on an on-demand basis)*
|
||||
*(See functions `parse_operator_function_or_variable` and `parse_typedef` )*
|
||||
|
||||
Adding your own exceptions is possible by simply modifying the parser to allow for the syntax you need.
|
||||
|
||||
*Note: You could interpret this strictness as a feature. This would allow the user to see if their codebase or a third-party's codebase contains some egregious preprocessor abuse.*
|
||||
|
||||
Macros used within a file should be registered by the user before parsing. This can be done two ways:
|
||||
|
||||
1. The register macro interface within [interface.hpp](../base/components/interface.hpp).
|
||||
2. Using `def_define` to create a CodeDefine and making sure to not set `opts.dont_register_to_preprocess_macros` to `true`.
|
||||
|
||||
## Registering macros
|
||||
|
||||
While the registeration of macros in the meta-program's side for parsing can be considered tedius, its necessary for the parser to accurately resolve the macros intent in one pass (and it provides some hygenics by verifying that they are used as intended).
|
||||
|
||||
The following can be used to register a macro:
|
||||
|
||||
```c
|
||||
GEN_API void register_macro( Macro macro );
|
||||
GEN_API void register_macros( s32 num, ... );
|
||||
GEN_API void register_macros_arr( s32 num, Macro* macros );
|
||||
```
|
||||
|
||||
The Macro typename is defined with the following in [parser_types.hpp](../base/components/parser_types.hpp):
|
||||
|
||||
```c
|
||||
struct Macro
|
||||
{
|
||||
StrCached Name;
|
||||
MacroType Type;
|
||||
MacroFlags Flags;
|
||||
};
|
||||
```
|
||||
|
||||
The macro can be designated one of the following types:
|
||||
|
||||
* `MT_Expression`: Intended to resolve to an expression expansion.
|
||||
* `MT_Statement`: Intended to resolve an statement expansion.
|
||||
* `MT_Typename`: Intended to resolve to a typename.
|
||||
|
||||
Additioonally tthe following flags may be set:
|
||||
|
||||
* `MF_Functional`: The macro intended to be passed arguments are at least have the calling `()` as part of its usage.
|
||||
* `MF_Expects_Body`: The parser should expect a braced-body `{ ... }` after the macro signature `<name> <params>`
|
||||
* `MF_Allow_As_Identifier`: Will allow the macro to be an acceptable token/s when an `Tok_Identifier` is expected.
|
||||
* `MF_Allow_As_Attribute`: Will allow the macro to be an acceptable token/s when an attribute token/s is expected.
|
||||
* `MF_Allow_As_Definition`: Will allow the macro be an acceptable token/s when the parser expects a declartion or definition to resolve after attributes or specifiers have been identified beforehand.
|
||||
* This flag requires that the macro is of type `MT_Statement` to make any sense of usage.
|
||||
|
||||
If a macro is not defined the following warning will be issued if `GEN_BUILD_DEBUG=1` during lexing within [lexer.cpp](../base/components/lexer.cpp) - `lex_preprocessor_define`:
|
||||
|
||||
```c
|
||||
log_fmt("Warning: '%S' was not registered before the lexer processed its #define directive, it will be registered as a expression macro\n"
|
||||
, name.Text
|
||||
);
|
||||
```
|
||||
|
||||
Further within the same scope, the lexer will issue a warning if it detects a macro was not flagged as function but has an open parenthesis `(` token right after is name with no whitespace:
|
||||
|
||||
```c
|
||||
log_fmt("Warning: %S registered macro is not flagged as functional yet the definition detects opening parenthesis '(' for arguments\n"
|
||||
, name.Text
|
||||
);
|
||||
```
|
||||
|
||||
Macros are tracked using a `MacroTable Macros;` defined as a member of the library's `Context`.
|
||||
|
||||
```c
|
||||
typedef HashTable(Macro) MacroTable;
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
* Empty lines used throughout the file are preserved for formatting purposes during ast serialization (they have a dedicated Token: `Tok_NewLine`).
|
||||
* Numeric literals are not checked for validity.
|
||||
* The parse API treats any execution scope definitions with no validation and are turned into untyped Code ASTs. (There is a [todo](https://github.com/Ed94/gencpp/issues/49) to add support)
|
||||
* *This includes the assignment of variables.*
|
||||
* Attributes ( `[[]]` (standard), `__declspec` (Microsoft), or `__attribute__` (GNU) )
|
||||
* Assumed to *come before specifiers* (`const`, `constexpr`, `extern`, `static`, etc) for a function or right afterthe return type.
|
||||
* Or in the usual spot for class, structs, (*right after the declaration keyword*)
|
||||
* typedefs have attributes with the type (`parse_type`)
|
||||
* Parsing attributes can be extended to support user defined macros by defining `GEN_DEFINE_ATTRIBUTE_TOKENS` (see `gen.hpp` for the formatting)
|
||||
* This is useful for example: parsing Unreal `Module_API` macros.
|
||||
|
||||
**The lexer & parser do not gracefully attempt to continue when it comes across incorrect code, and doesn't properly track errors into a listing (yet).**
|
||||
Vendored
-147
@@ -1,147 +0,0 @@
|
||||
## Navigation
|
||||
|
||||
[Top](../Readme.md)
|
||||
|
||||
* [docs](../docs/Readme.md)
|
||||
|
||||
# C Library Generation
|
||||
|
||||
`c_library.cpp` generates both *segemnted* and *singleheader* variants of the library compliant with C11.
|
||||
|
||||
The output will be in the `gen_segmented/gen` directory (if the directory does not exist, it will create it).
|
||||
|
||||
If using the library's provided build scripts:
|
||||
|
||||
```ps1
|
||||
.\build.ps1 <compiler> <debug or omit> c_lib
|
||||
```
|
||||
|
||||
To generate a static or dynamic library:
|
||||
|
||||
```ps1
|
||||
.\build.ps1 <compiler> <debug or omit> c_lib_static c_lib_dyn
|
||||
```
|
||||
.
|
||||
All free from tag identifiers will be prefixed with `gen_` or `GEN_` as the namespace. This can either be changed after generation with a `.refactor` script (or your preferred subst method), OR by modifying [c_library.refactor](./c_library.refactor).
|
||||
|
||||
**If c_library.refactor is modified you may need to modify c_library.cpp and its [components](./components/). As some of the container generation relies on that prefix.**
|
||||
|
||||
## Generation structure
|
||||
|
||||
1. Files are scanned in or parsed.
|
||||
* If they are parsed, its due to requiring some changes to either naming, or adding additonal definitions (container generation, typedefs, etc).
|
||||
2. All scanned or parsed code is refactored (identifiers substs) and/or formatted.
|
||||
3. Singleheader generated.
|
||||
4. Segmented headers and source generated.
|
||||
|
||||
## Templated container generation
|
||||
|
||||
The array and hashtable containers used across this library are generated using the following implementatioon:
|
||||
|
||||
* [containers.array.hpp](./components/containers.array.hpp)
|
||||
* [containers.hashtable.hpp](./components/containers.hashtable.hpp)
|
||||
|
||||
These are functionally (and interface wise) equivalent to the library's `Array<Type>` `HashTable<Type>` within [containers.hpp](../base/dependencies/containers.hpp)
|
||||
|
||||
Both files follow the same pattern of providing three procedures:
|
||||
|
||||
* `gen_<container>_base` : Intended to be called once, defines universal "base" definitions.
|
||||
* `gen_<container>` : Called per instatiation of the container for a given set of dependent args.
|
||||
* `gen_<container>_generic_selection_interface` : Intended to be called once after all of the instantiated containers have finished generating. It will generate a set of generic selection macros as described by Macro Usage section below.
|
||||
|
||||
A simple `<container>_DefinitionCounter` is used to know how many instantiations of the template have occured. This is used to determine how to define `GENERIC_SLOT_<ID>_<functionID>` for the generic interface along with how many slots the `_Generic` macro will need to have generated.
|
||||
|
||||
## Macro Usage
|
||||
|
||||
For the most part macros are kept minimal with exception to `_Generic`...
|
||||
|
||||
The `_Generic` macro plays a key role in reducing direct need of the user to wrangle with mangled definition identifiers of 'templated' containers or for type coercion to map distinct data types to a common code path.
|
||||
|
||||
Many C11 libraries don't use it.. and, of those that do. they usually end up obfuscate it with excessive preprocessor abuse; Effort was put into minimizing how much of these macros are handled by the preprocessor vs gencpp itself.
|
||||
|
||||
*(I will be explaining this thing for the rest of this seciton along with gencpp c library's usage of it)*
|
||||
|
||||
|
||||
The usual presentation (done bare) is the following:
|
||||
|
||||
```c
|
||||
#define macro_that_selects_typeof_arg(arg, y) \
|
||||
_Generic( (arg), \
|
||||
int : some expression, \
|
||||
double : some other expression, \
|
||||
struct Whatnot : something else again, \
|
||||
default : fallback expression \
|
||||
)
|
||||
```
|
||||
|
||||
Where `_Generic` can be considered the follwoing (psuedo-C):
|
||||
|
||||
```c
|
||||
#define type_expr_pair(type, expr) type: expr
|
||||
|
||||
C_Expression _Generic( selector_arg, a_type_expr_pair, ... ) {
|
||||
switch( typeof(selector_arg)) {
|
||||
case a_type_expr_pair:
|
||||
return a_type_expr_pari.expr;
|
||||
...
|
||||
default:
|
||||
return default.expr;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The first `arg` of _Generic behaves as the "controlling expression" or the expression that resolves to a type which will dictate which of the following expressions provided after to `_Generic` will be resolved as the one used inline for the implemenation.
|
||||
|
||||
|
||||
For this library's purposes we'll be using the functional macro equivalent *(if there is an exception I'll link it at the end of this section)*:
|
||||
|
||||
```c
|
||||
#define macro_that_uses_selector_arg_for_resolving_a_fucntion( selecting_exp) \
|
||||
_Generic( (selecting_exp), \
|
||||
int : func_use_int, \
|
||||
double : func_use_double, \
|
||||
struct Whatnot : func_use_Whatnot, \
|
||||
default : struct SIGNALS_FAILURE \
|
||||
) (selecting_exp)
|
||||
```
|
||||
|
||||
In this case, we directly added `(selecting_exp)` to the end there.. as we want to directly have the macro resolve to calling a resolved procedure. A default has been set to a struct as that leads to a neat compiler message that would otherwise be impossible beause static_assert is a statement and thus cannot be used within a slot.
|
||||
|
||||
Now, even with gencpp generating this type-expression table, we still need wrapper macros to achieve function 'overloading' for the templated containers as _Generic has a [significant drawback](https://www.chiark.greenend.org.uk/~sgtatham/quasiblog/c11-generic/):
|
||||
|
||||
> Discarded expressions still have to be semantically valid.
|
||||
|
||||
The only way to absolve this issue [(without resorting to nasty preprocessor hacks)](https://github.com/JacksonAllan/CC/blob/main/articles/Better_C_Generics_Part_1_The_Extendible_Generic.md) is with wrapping expressions in 'slot' resolving macros that do not expand if the slot is not defined:
|
||||
|
||||
```c
|
||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_1__function_sig )
|
||||
```
|
||||
|
||||
`GENERIC_SLOT_1__function_sig` is our warpper of a "`int, func_use_int`" pair. The `GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT` is a verbse named macro to indicate that that pair will be expanded ***ONLY IF*** its defined.
|
||||
|
||||
So for any given templated container interface. Expect the follwoing (taken straight from generation, and just cleaned up formatting):
|
||||
|
||||
```c
|
||||
#define gen_array_append( selector_arg, ... ) _Generic( \
|
||||
(selector_arg ), \
|
||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GEN_GENERIC_SLOT_1__array_append ) \
|
||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GEN_GENERIC_SLOT_2__array_append ) \
|
||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GEN_GENERIC_SLOT_3__array_append ) \
|
||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GEN_GENERIC_SLOT_4__array_append ) \
|
||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GEN_GENERIC_SLOT_5__array_append ) \
|
||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GEN_GENERIC_SLOT_6__array_append ) \
|
||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GEN_GENERIC_SLOT_7__array_append ) \
|
||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GEN_GENERIC_SLOT_8__array_append ) \
|
||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GEN_GENERIC_SLOT_9__array_append ) \
|
||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GEN_GENERIC_SLOT_10__array_append ) \
|
||||
default: gen_generic_selection_fail \
|
||||
) GEN_RESOLVED_FUNCTION_CALL( &selector_arg, __VA_ARGS__ )
|
||||
|
||||
```
|
||||
|
||||
*Note(Ed): Unfortunately I cannot get clang-format to output these macros sanely like the above..*
|
||||
*Eventually I'll add some basic builtin formatting but if the user has suggestions for something better I'm open ears...*
|
||||
|
||||
`GEN_RESOLVED_FUNCTION_CALL` is an empty define, its just to indicate that its intended to expand to a function call.
|
||||
|
||||
To see the the actual macro definitions used - see: [generic_macros.h](./components/generic_macros.h). They'll be injected right after the usual macros in the generated header file.
|
||||
Vendored
-453
@@ -1,453 +0,0 @@
|
||||
# General Docs
|
||||
|
||||
[Top](../Readme.md)
|
||||
|
||||
Contains:
|
||||
|
||||
* [AST_Design](./AST_Design.md): Overview of ASTs
|
||||
* [AST Types](./AST_Types.md): Listing of all AST types along with their Code type interface.
|
||||
* [Parsing](./Parsing.md): Overview of the parsing interface.
|
||||
* [Parser Algo](./Parser_Algo.md): In-depth breakdown of the parser's implementation.
|
||||
|
||||
### *CURRENTLY UNSUPPORTED*
|
||||
|
||||
**There is no support for validating expressions.**
|
||||
Its a [todo](https://github.com/Ed94/gencpp/issues/49)
|
||||
|
||||
**Only trivial template support is provided.**
|
||||
The intention is for only simple, non-recursive substitution.
|
||||
The parameters of the template are treated like regular parameter AST entries.
|
||||
This means that the typename entry for the parameter AST would be either:
|
||||
|
||||
* `class`
|
||||
* `typename`
|
||||
* A fundamental type, function, or pointer type.
|
||||
|
||||
***Concepts and Constraints are not supported***
|
||||
Its a [todo](https://github.com/Ed94/gencpp/issues/21)
|
||||
|
||||
### Feature Macros
|
||||
|
||||
* `GEN_DEFINE_ATTRIBUTE_TOKENS` : Allows user to define their own attribute macros for use in parsing.
|
||||
* This can be generated using base.cpp.
|
||||
* `GEN_DEFINE_LIBRARY_CORE_CONSTANTS` : Optional typename codes as they are non-standard to C/C++ and not necessary to library usage
|
||||
* `GEN_DONT_ENFORCE_GEN_TIME_GUARD` : By default, the library ( gen.hpp/ gen.cpp ) expects the macro `GEN_TIME` to be defined, this disables that.
|
||||
* `GEN_ENFORCE_STRONG_CODE_TYPES` : Enforces casts to filtered code types.
|
||||
* `GEN_EXPOSE_BACKEND` : Will expose symbols meant for internal use only.
|
||||
* `GEN_ROLL_OWN_DEPENDENCIES` : Optional override so that user may define the dependencies themselves.
|
||||
* `GEN_DONT_ALLOW_INVALID_CODE` (Not implemented yet) : Will fail when an invalid code is constructed, parsed, or serialized.
|
||||
* `GEN_C_LIKE_CPP` : Setting to `<true or 1>` Will prevent usage of function defnitions using references and structs with member functions. Structs will still have user-defined operator conversions, for-range support, and other operator overloads
|
||||
|
||||
### The Data & Interface
|
||||
|
||||
The library's persistent state is managed tracked by a context struct: `global Context* _ctx;` defined within [static_data.cpp](../base/components/static_data.cpp)
|
||||
|
||||
https://github.com/Ed94/gencpp/blob/967a044637f1615c709cb723dc61118fcc08dcdb/base/components/interface.hpp#L39-L97
|
||||
|
||||
The interface for the context:
|
||||
|
||||
* `init`: Initializtion
|
||||
* `deinit`: De-initialization.
|
||||
* `reset`: Clears the allocations, but doesn't free the memoery, then calls `init()` on `_ctx` again.
|
||||
* `get_context`: Retreive the currently tracked context.
|
||||
* `set_context`: Swap out the current tracked context.
|
||||
|
||||
|
||||
#### Allocato usage
|
||||
|
||||
* `Allocator_DyanmicContainers`: Growing arrays, hash tables. (Unbounded sized containers)
|
||||
* `Allocator_Pool`: Fixed-sized object allocations (ASTs, etc)
|
||||
* `Allocator_StrCache`: StrCached allocations
|
||||
* `Allocator_Temp`: Temporary alloations mostly intended for StrBuilder usage. Manually cleared by the user by their own discretion.
|
||||
|
||||
The allocator definitions used are exposed to the user incase they want to dictate memory usage
|
||||
|
||||
* Allocators are defined with the `AllocatorInfo` structure found in [`memory.hpp`](../base/dependencies/memory.hpp)
|
||||
* Most of the work is just defining the allocation procedure:
|
||||
|
||||
```cpp
|
||||
void* ( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags );
|
||||
```
|
||||
|
||||
For any allocator above that the user does not define before `init`, a fallback allocator will be assigned that utiizes the `fallback_allocator_proc` wtihin [interface.cpp](../base/components/interface.cpp).
|
||||
|
||||
As mentioned in root readme, the user is provided Code objects by calling the constructor's functions to generate them or find existing matches.
|
||||
|
||||
The AST is managed by the library and provided to the user via its interface.
|
||||
However, the user may specifiy memory configuration.
|
||||
|
||||
[Data layout of AST struct (Subject to heavily change with upcoming todos)](../base/components/ast.hpp#L396-461)
|
||||
|
||||
https://github.com/Ed94/gencpp/blob/967a044637f1615c709cb723dc61118fcc08dcdb/base/components/ast.hpp#L369-L435
|
||||
|
||||
*`StringCahced` is a typedef for `Str` (a string slice), to denote it is an interned string*
|
||||
*`CodeType` is enum taggin the type of code. Has an underlying type of `u32`*
|
||||
*`OperatorT` is a typedef for `EOperator::Type` which has an underlying type of `u32`*
|
||||
*`StrBuilder` is the dynamically allocating string builder type for the library*
|
||||
|
||||
AST widths are setup to be AST_POD_Size (128 bytes by default).
|
||||
The width dictates how much the static array can hold before it must give way to using an allocated array:
|
||||
|
||||
```cpp
|
||||
constexpr static
|
||||
int AST_ArrSpecs_Cap =
|
||||
(
|
||||
AST_POD_Size
|
||||
- sizeof(Code)
|
||||
- sizeof(StrCached)
|
||||
- sizeof(Code) * 2
|
||||
- sizeof(Token*)
|
||||
- sizeof(Code)
|
||||
- sizeof(CodeType)
|
||||
- sizeof(ModuleFlag)
|
||||
- sizeof(u32)
|
||||
)
|
||||
/ sizeof(Specifier) - 1;
|
||||
```
|
||||
Data Notes:
|
||||
|
||||
* ASTs are wrapped for the user in a Code struct which is a wrapper for a AST* type.
|
||||
* Code types have member symbols but their data layout is enforced to be POD types.
|
||||
* This library treats memory failures as fatal.
|
||||
* Cached Strings are stored in their own set of arenas. AST constructors use cached strings for names, and content.
|
||||
* Strings used for serialization and file buffers are not contained by those used for cached strings.
|
||||
* `_ctx->Allocator_Temp` is used.
|
||||
* Its intended to generate the AST in one go and serialize after. The constructors and serializer are designed to be a "one pass, front to back" setup.
|
||||
* Any modifcations to an existing AST should be to just construct another with the modifications done on-demand while traversing the AST (non-destructive).
|
||||
|
||||
The following CodeTypes are used which the user may optionally use strong typing with if they enable: `GEN_ENFORCE_STRONG_CODE_TYPES`
|
||||
|
||||
* CodeBody : Has support for `for : range` iterating across Code objects.
|
||||
* CodeAttributes
|
||||
* CodeComment
|
||||
* CodeClass
|
||||
* CodeConstructor
|
||||
* CodeDefine
|
||||
* CodeDefineParams
|
||||
* CodeDestructor
|
||||
* CodeEnum
|
||||
* CodeExec
|
||||
* CodeExtern
|
||||
* CodeInclude
|
||||
* CodeFriend
|
||||
* CodeFn
|
||||
* CodeModule
|
||||
* CodeNS
|
||||
* CodeOperator
|
||||
* CodeOpCast : User defined member operator conversion
|
||||
* CodeParams : Has support for `for : range` iterating across parameters.
|
||||
* CodePreprocessCond
|
||||
* CodePragma
|
||||
* CodeSpecifiers : Has support for `for : range` iterating across specifiers.
|
||||
* CodeStruct
|
||||
* CodeTemplate
|
||||
* CodeTypename
|
||||
* CodeTypedef
|
||||
* CodeUnion
|
||||
* CodeUsing
|
||||
* CodeVar
|
||||
|
||||
Each `struct Code<Name>` has an associated "filtered AST" with the naming convention: `AST_<CodeName>`
|
||||
Unrelated fields of the AST for that node type are omitted and only necessary padding members are defined otherwise.
|
||||
|
||||
For the interface related to these code types see:
|
||||
|
||||
* [ast.hpp](../base/components/ast.hpp): Under the region pragma `Code C-Interface`
|
||||
* [code_types.hpp](../base/components/code_types.hpp): Under the region pragma `Code C-Interface`. Additional functionlity for c++ will be within the struct definitions or at the end of the file.
|
||||
|
||||
## There are three categories of interfaces for Code AST generation & reflection
|
||||
|
||||
* Upfront
|
||||
* Parsing
|
||||
* Untyped
|
||||
|
||||
### Upfront Construction
|
||||
|
||||
All component ASTs must be previously constructed, and provided on creation of the code AST.
|
||||
The construction will fail and return CodeInvalid otherwise.
|
||||
|
||||
Interface :``
|
||||
|
||||
* def_attributes
|
||||
* *This is pre-appended right before the function symbol, or placed after the class or struct keyword for any flavor of attributes used.*
|
||||
* *Its up to the user to use the desired attribute formatting: `[[]]` (standard), `__declspec` (Microsoft), or `__attribute__` (GNU).*
|
||||
* def_comment
|
||||
* def_class
|
||||
* def_constructor
|
||||
* def_define
|
||||
* def_define_params
|
||||
* def_destructor
|
||||
* def_enum
|
||||
* def_execution
|
||||
* *This is equivalent to untyped_str, except that its intended for use only in execution scopes.*
|
||||
* def_extern_link
|
||||
* def_friend
|
||||
* def_function
|
||||
* def_include
|
||||
* def_module
|
||||
* def_namespace
|
||||
* def_operator
|
||||
* def_operator_cast
|
||||
* def_param
|
||||
* def_params
|
||||
* def_pragma
|
||||
* def_preprocess_cond
|
||||
* def_specifier
|
||||
* def_specifiers
|
||||
* def_struct
|
||||
* def_template
|
||||
* def_type
|
||||
* def_typedef
|
||||
* def_union
|
||||
* def_using
|
||||
* def_using_namespace
|
||||
* def_variable
|
||||
|
||||
Bodies:
|
||||
|
||||
* def_body
|
||||
* def_class_body
|
||||
* def_enum_body
|
||||
* def_export_body
|
||||
* def_extern_link_body
|
||||
* def_function_body
|
||||
* *Use this for operator bodies as well*
|
||||
* def_global_body
|
||||
* def_namespace_body
|
||||
* def_struct_body
|
||||
* def_union_body
|
||||
|
||||
Usage:
|
||||
|
||||
```cpp
|
||||
<name> = def_<function type>( ... );
|
||||
|
||||
Code <name>
|
||||
{
|
||||
...
|
||||
<name> = def_<function name>( ... );
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
All optional parmeters are defined within `struct Opts_def_<functon name>`. This was done to setup a [macro trick](https://x.com/vkrajacic/status/1749816169736073295) for default optional parameers in the C library:
|
||||
|
||||
```cpp
|
||||
struct gen_Opts_def_struct
|
||||
{
|
||||
gen_CodeBody body;
|
||||
gen_CodeTypename parent;
|
||||
gen_AccessSpec parent_access;
|
||||
gen_CodeAttributes attributes;
|
||||
gen_CodeTypename* interfaces;
|
||||
gen_s32 num_interfaces;
|
||||
gen_ModuleFlag mflags;
|
||||
};
|
||||
typedef struct gen_Opts_def_struct gen_Opts_def_struct;
|
||||
|
||||
GEN_API gen_CodeClass gen_def__struct( gen_Str name, gen_Opts_def_struct opts GEN_PARAM_DEFAULT );
|
||||
#define gen_def_struct( name, ... ) gen_def__struct( name, ( gen_Opts_def_struct ) { __VA_ARGS__ } )
|
||||
```
|
||||
|
||||
In the C++ library, the `def_<funtion name>` is not wrapped in a macro.
|
||||
|
||||
When using the body functions, its recommended to use the args macro to auto determine the number of arguments for the varadic:
|
||||
|
||||
```cpp
|
||||
def_global_body( args( ht_entry, array_ht_entry, hashtable ));
|
||||
|
||||
// instead of:
|
||||
def_global_body( 3, ht_entry, array_ht_entry, hashtable );
|
||||
```
|
||||
|
||||
If a more incremental approach is desired for the body ASTs, `Code def_body( CodeT type )` can be used to create an empty bodyss
|
||||
When the members have been populated use: `code_validate_body` to verify that the members are valid entires for that type.
|
||||
|
||||
### Parse construction
|
||||
|
||||
A string provided to the API is parsed for the intended language construct.
|
||||
|
||||
Interface :
|
||||
|
||||
* parse_class
|
||||
* parse_constructor
|
||||
* parse_define
|
||||
* parse_destructor
|
||||
* parse_enum
|
||||
* parse_export_body
|
||||
* parse_extern_link
|
||||
* parse_friend
|
||||
* parse_function
|
||||
* parse_global_body
|
||||
* parse_namespace
|
||||
* parse_operator
|
||||
* parse_operator_cast
|
||||
* parse_struct
|
||||
* parse_template
|
||||
* parse_type
|
||||
* parse_typedef
|
||||
* parse_union
|
||||
* parse_using
|
||||
* parse_variable
|
||||
|
||||
Usage:
|
||||
|
||||
```cpp
|
||||
Code <name> = parse_<function name>( string with code );
|
||||
|
||||
Code <name> = def_<function name>( ..., parse_<function name>(
|
||||
<string with code>
|
||||
));
|
||||
```
|
||||
|
||||
### Untyped constructions
|
||||
|
||||
Code ASTs are constructed using unvalidated strings.
|
||||
|
||||
Interface :
|
||||
|
||||
* token_fmt_va
|
||||
* token_fmt
|
||||
* untyped_str
|
||||
* untyped_fmt
|
||||
* untyped_token_fmt
|
||||
|
||||
During serialization any untyped Code AST has its string value directly injected inline of whatever context the content existed as an entry within.
|
||||
Even though these are not validated from somewhat correct c/c++ syntax or components, it doesn't mean that Untyped code can be added as any component of a Code AST:
|
||||
|
||||
* Untyped code cannot have children, thus there cannot be recursive injection this way.
|
||||
* Untyped code can only be a child of a parent of body AST, or for values of an assignment (ex: variable assignment).
|
||||
|
||||
These restrictions help prevent abuse of untyped code to some extent.
|
||||
|
||||
Usage Conventions:
|
||||
|
||||
```cpp
|
||||
Code <name> = def_variable( <type>, <name>, untyped_<function name>(
|
||||
<string with code>
|
||||
));
|
||||
|
||||
Code <name> = untyped_str( code(
|
||||
<some code without "" quotes>
|
||||
));
|
||||
```
|
||||
|
||||
Optionally, `code_str`, and `code_fmt` macros can be used so that the code macro doesn't have to be used:
|
||||
|
||||
```cpp
|
||||
Code <name> = code_str( <some code without "" quotes > )
|
||||
```
|
||||
|
||||
Template metaprogramming in the traditional sense becomes possible with the use of `token_fmt` and parse constructors:
|
||||
|
||||
```cpp
|
||||
Str value = txt("Something");
|
||||
|
||||
char const* template_str = txt(
|
||||
Code with <key> to replace with token_values
|
||||
...
|
||||
);
|
||||
char const* gen_code_str = token_fmt( "key", value, template_str );
|
||||
Code <name> = parse_<function name>( gen_code_str );
|
||||
```
|
||||
|
||||
## Predefined Codes
|
||||
|
||||
The following are provided predefined by the library as they are commonly used:
|
||||
|
||||
* `enum_underlying_macro`
|
||||
* `access_public`
|
||||
* `access_protected`
|
||||
* `access_private`
|
||||
* `attrib_api_export`
|
||||
* `attrib_api_import`
|
||||
* `module_global_fragment`
|
||||
* `module_private_fragment`
|
||||
* `fmt_newline`
|
||||
* `pragma_once`
|
||||
* `param_varaidc` (Used for varadic definitions)
|
||||
* `preprocess_else`
|
||||
* `preprocess_endif`
|
||||
* `spec_const`
|
||||
* `spec_consteval`
|
||||
* `spec_constexpr`
|
||||
* `spec_constinit`
|
||||
* `spec_extern_linkage` (extern)
|
||||
* `spec_final`
|
||||
* `spec_forceinline`
|
||||
* `spec_global` (global macro)
|
||||
* `spec_inline`
|
||||
* `spec_internal_linkage` (internal macro)
|
||||
* `spec_local_persist` (local_persist macro)
|
||||
* `spec_mutable`
|
||||
* `spec_neverinline`
|
||||
* `spec_noexcept`
|
||||
* `spec_override`
|
||||
* `spec_ptr`
|
||||
* `spec_pure`
|
||||
* `spec_ref`
|
||||
* `spec_register`
|
||||
* `spec_rvalue`
|
||||
* `spec_static_member` (static)
|
||||
* `spec_thread_local`
|
||||
* `spec_virtual`
|
||||
* `spec_volatile`
|
||||
* `t_empty` (Used for varaidc macros)
|
||||
* `t_auto`
|
||||
* `t_void`
|
||||
* `t_int`
|
||||
* `t_bool`
|
||||
* `t_char`
|
||||
* `t_wchar_t`
|
||||
* `t_class`
|
||||
* `t_typename`
|
||||
|
||||
Optionally the following may be defined if `GEN_DEFINE_LIBRARY_CODE_CONSTANTS` is defined
|
||||
|
||||
* `t_b32`
|
||||
* `t_s8`
|
||||
* `t_s16`
|
||||
* `t_s32`
|
||||
* `t_s64`
|
||||
* `t_u8`
|
||||
* `t_u16`
|
||||
* `t_u32`
|
||||
* `t_u64`
|
||||
* `t_ssize` (ssize_t)
|
||||
* `t_usize` (size_t)
|
||||
* `t_f32`
|
||||
* `t_f64`
|
||||
|
||||
## Extent of operator overload validation
|
||||
|
||||
The AST and constructors will be able to validate that the arguments provided for the operator type match the expected form:
|
||||
|
||||
* If return type must match a parameter
|
||||
* If number of parameters is correct
|
||||
* If added as a member symbol to a class or struct, that operator matches the requirements for the class (types match up)
|
||||
* There is no support for validating new & delete operations (yet)
|
||||
|
||||
The user is responsible for making sure the code types provided are correct
|
||||
and have the desired specifiers assigned to them beforehand.
|
||||
|
||||
## Code generation and modification
|
||||
|
||||
There are two provided auxiliary interfaces:
|
||||
|
||||
* Builder
|
||||
* Scanner
|
||||
|
||||
### Builder is a similar object to the jai language's strbuilder_builder
|
||||
|
||||
* The purpose of it is to generate a file.
|
||||
* A file is specified and opened for writing using the open( file_path) function.
|
||||
* The code is provided via print( code ) function will be serialized to its buffer.
|
||||
* When all serialization is finished, use the write() command to write the buffer to the file.
|
||||
|
||||
### Scanner
|
||||
|
||||
* The purpose is to scan or parse files
|
||||
* Some with two basic functions to convert a fil to code: `scan_file` and `parse_file`
|
||||
* `scan_file`: Merely grabs the file and stores it in an untyped Code.
|
||||
* `parse_file`: Will parse the file using `parse_global_body` and return a `CodeBody`.
|
||||
* Two basic functions for grabbing columns from a CSV: `parse_csv_one_column` and `parse_csv_two_columns`
|
||||
+712
-608
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user