mirror of
https://github.com/Ed94/gencpp.git
synced 2024-12-21 23:34:44 -08:00
More dependency movement from zpl, incremental design improvements.
Made token_fmt more ergonomic, going to have to use a similar behavior with the upfront body constructors.
This commit is contained in:
parent
20d307759b
commit
7828e6d2ea
84
.vscode/gencpp_lldbvis.py
vendored
84
.vscode/gencpp_lldbvis.py
vendored
@ -1,84 +0,0 @@
|
||||
import lldb
|
||||
|
||||
class String_SyntheticChildrenProvider:
|
||||
def __init__(self, valobj, internal_dict):
|
||||
self.valobj = valobj
|
||||
|
||||
def num_children(self):
|
||||
return 3
|
||||
|
||||
def get_child_index(self, name):
|
||||
if name == "Data":
|
||||
return 0
|
||||
if name == "Length":
|
||||
return 1
|
||||
if name == "Capacity":
|
||||
return 2
|
||||
|
||||
return None
|
||||
|
||||
def get_child_at_index(self, index):
|
||||
if index == 0:
|
||||
return self.valobj.GetChildMemberWithName("Data")
|
||||
|
||||
data = self.valobj.GetChildMemberWithName("Data")
|
||||
header_ptr = data.GetValueAsUnsigned() - 16
|
||||
target = self.valobj.GetTarget()
|
||||
header_type = target.FindFirstType("gen::String::Header")
|
||||
header = self.valobj.CreateValueFromAddress("Header", header_ptr, header_type)
|
||||
|
||||
if index == 1:
|
||||
return header.GetChildMemberWithName("Length")
|
||||
|
||||
if index == 2:
|
||||
return header.GetChildMemberWithName("Capacity")
|
||||
|
||||
return None
|
||||
|
||||
def update(self):
|
||||
pass
|
||||
|
||||
def list_synthetic_providers(debugger):
|
||||
print("Listing synthetic providers (start)")
|
||||
|
||||
num_categories = debugger.GetNumCategories()
|
||||
print("Debugger language categories count:", num_categories)
|
||||
|
||||
cpp_category = None
|
||||
for i in range(num_categories):
|
||||
print("WERE HERE")
|
||||
print(debugger)
|
||||
cat = debugger.GetCategoryAtIndex(i)
|
||||
print("Category name: {}, language: {}".format(cat.GetName(), cat.GetLanguage()))
|
||||
if cat.GetLanguage() == lldb.eLanguageTypeC_plus_plus:
|
||||
cpp_category = cat
|
||||
break
|
||||
|
||||
if not cpp_category:
|
||||
print("Could not get C++ category")
|
||||
return
|
||||
|
||||
synthetic_providers = cpp_category.GetSyntheticChildren()
|
||||
if not synthetic_providers:
|
||||
print("Could not get synthetic children")
|
||||
return
|
||||
|
||||
num_providers = synthetic_providers.GetSize()
|
||||
print("Number of synthetic providers:", num_providers)
|
||||
|
||||
for i in range(num_providers):
|
||||
provider = synthetic_providers.GetSyntheticChildAtIndex(i)
|
||||
print("Provider regex: {}, class name: {}".format(provider.GetRegex(), provider.GetDescription()))
|
||||
|
||||
print("Listing synthetic providers (finish)")
|
||||
|
||||
|
||||
|
||||
|
||||
def __lldb_init_module(debugger, internal_dict):
|
||||
print("Importing the String visualization")
|
||||
debugger.HandleCommand("type synthetic add -x '^gen::String$' -l gencpp_libvis.String_SyntheticChildrenProvider")
|
||||
print("Before list_synthetic_providers")
|
||||
list_synthetic_providers(debugger)
|
||||
|
||||
lldb.debugger = None
|
12
.vscode/launch.json
vendored
12
.vscode/launch.json
vendored
@ -12,7 +12,6 @@
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}/test/gen/",
|
||||
"postRunCommands": [
|
||||
"command script import \"${workspaceFolder}/.vscode/gencpp_lldbvis.py\""
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -22,16 +21,7 @@
|
||||
"program": "${workspaceFolder}/test/gen/build/gencpp.exe",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}/test/gen/",
|
||||
"visualizerFile": "${workspaceFolder}/.vscode/gencpp.natvis"
|
||||
},
|
||||
{
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"name": "Debug gentime parsed vsdbg",
|
||||
"program": "${workspaceFolder}/test/gen/build/gencpp_parsed.exe",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}/test/gen/",
|
||||
"visualizerFile": "${workspaceFolder}/.vscode/gencpp.natvis"
|
||||
"visualizerFile": "${workspaceFolder}/scripts/gencpp.natvis"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -204,7 +204,7 @@ Data layout of AST struct:
|
||||
```cpp
|
||||
union {
|
||||
AST* ArrStatic[AST::ArrS_Cap];
|
||||
Array<AST*> ArrDyn;
|
||||
Array< AST* > ArrDyn;
|
||||
StringCached Content;
|
||||
SpecifierT ArrSpecs[AST::ArrSpecs_Cap];
|
||||
};
|
||||
|
@ -113,12 +113,12 @@
|
||||
<ClInclude Include="project\Bloat.hpp" />
|
||||
<ClInclude Include="project\gen.hpp" />
|
||||
<ClInclude Include="test\DummyInclude.hpp" />
|
||||
<ClInclude Include="test\NonParsed\Array.NonParsed.hpp" />
|
||||
<ClInclude Include="test\NonParsed\Buffer.NonParsed.hpp" />
|
||||
<ClInclude Include="test\NonParsed\HashTable.NonParsed.hpp" />
|
||||
<ClInclude Include="test\NonParsed\Memory.NonParsed.hpp" />
|
||||
<ClInclude Include="test\NonParsed\Ring.NonParsed.hpp" />
|
||||
<ClInclude Include="test\NonParsed\Sanity.NonParsed.hpp" />
|
||||
<ClInclude Include="test\Upfront\Array.Upfront.hpp" />
|
||||
<ClInclude Include="test\Upfront\Buffer.Upfront.hpp" />
|
||||
<ClInclude Include="test\Upfront\HashTable.Upfront.hpp" />
|
||||
<ClInclude Include="test\Upfront\Memory.Upfront.hpp" />
|
||||
<ClInclude Include="test\Upfront\Ring.Upfront.hpp" />
|
||||
<ClInclude Include="test\Upfront\Sanity.Upfront.hpp" />
|
||||
<ClInclude Include="test\Parsed\Array.Parsed.hpp" />
|
||||
<ClInclude Include="test\Parsed\Sanity.Parsed.hpp" />
|
||||
<ClInclude Include="thirdparty\zpl.h" />
|
||||
@ -129,7 +129,7 @@
|
||||
<ClCompile Include="singleheader\gen\gen.singleheader.cpp" />
|
||||
<ClCompile Include="test\gen\build\meson-private\sanitycheckc.c" />
|
||||
<ClCompile Include="test\gen\build\meson-private\sanitycheckcpp.cc" />
|
||||
<ClCompile Include="test\test.NonParsed.cpp" />
|
||||
<ClCompile Include="test\test.Upfront.cpp" />
|
||||
<ClCompile Include="test\test.Parsed.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -50,7 +50,7 @@
|
||||
<ClInclude Include="thirdparty\zpl.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="test\NonParsed\Sanity.hpp">
|
||||
<ClInclude Include="test\Upfront\Sanity.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
|
1152
project/Bloat.cpp
1152
project/Bloat.cpp
File diff suppressed because it is too large
Load Diff
@ -9,7 +9,7 @@
|
||||
# define ZPL_IMPLEMENTATION
|
||||
#endif
|
||||
|
||||
// TODO: This will be removed when making the library have zero dependencies.
|
||||
// TODO : This will be removed when making the library have zero dependencies.
|
||||
#pragma region ZPL INCLUDE
|
||||
#if __clang__
|
||||
# pragma clang diagnostic push
|
||||
@ -27,10 +27,16 @@
|
||||
# define ZPL_MODULE_HASHING
|
||||
#include "zpl.h"
|
||||
|
||||
#undef Array
|
||||
#undef heap
|
||||
#undef alloc_item
|
||||
#undef alloc_array
|
||||
#undef Array
|
||||
#undef heap
|
||||
#undef malloc
|
||||
#undef mfree
|
||||
#undef ZPL_ASSERT_MSG
|
||||
#undef ZPL_ASSERT_NOT_NULL
|
||||
#undef ZPL_DEBUG_TRAP
|
||||
#undef ZPL_PANIC
|
||||
|
||||
using zpl::b32;
|
||||
using zpl::s8;
|
||||
@ -38,12 +44,15 @@ using zpl::s16;
|
||||
using zpl::s32;
|
||||
using zpl::s64;
|
||||
using zpl::u8;
|
||||
using zpl::u16;
|
||||
using zpl::u32;
|
||||
using zpl::u64;
|
||||
using zpl::uw;
|
||||
using zpl::sw;
|
||||
using zpl::sptr;
|
||||
using zpl::uptr;
|
||||
using zpl::f32;
|
||||
using zpl::f64;
|
||||
|
||||
// using zpl::AllocType;
|
||||
// using zpl::Arena;
|
||||
@ -63,39 +72,40 @@ using zpl::uptr;
|
||||
|
||||
// using zpl::ZPL_ALLOCATOR_FLAG_CLEAR_TO_ZERO;
|
||||
|
||||
using zpl::align_forward;
|
||||
using zpl::align_forward_i64;
|
||||
// using zpl::align_forward;
|
||||
// using zpl::align_forward_i64;
|
||||
// using zpl::alloc;
|
||||
// using zpl::alloc_align;
|
||||
// using zpl::arena_allocator;
|
||||
// using zpl::arena_init_from_memory;
|
||||
// using zpl::arena_init_from_allocator;
|
||||
// using zpl::arena_free;
|
||||
using zpl::assert_crash;
|
||||
using zpl::char_first_occurence;
|
||||
using zpl::char_is_alpha;
|
||||
using zpl::char_is_alphanumeric;
|
||||
using zpl::char_is_digit;
|
||||
using zpl::char_is_hex_digit;
|
||||
using zpl::char_is_space;
|
||||
using zpl::crc32;
|
||||
// using zpl::assert_crash;
|
||||
// using zpl::char_first_occurence;
|
||||
// using zpl::char_is_alpha;
|
||||
// using zpl::char_is_alphanumeric;
|
||||
// using zpl::char_is_digit;
|
||||
// using zpl::char_is_hex_digit;
|
||||
// using zpl::char_is_space;
|
||||
// using zpl::crc32;
|
||||
// using zpl::free_all;
|
||||
using zpl::is_power_of_two;
|
||||
using zpl::mem_copy;
|
||||
using zpl::mem_move;
|
||||
using zpl::mem_set;
|
||||
using zpl::pointer_add;
|
||||
// using zpl::is_power_of_two;
|
||||
// using zpl::mem_copy;
|
||||
// using zpl::mem_move;
|
||||
// using zpl::mem_set;
|
||||
// using zpl::pointer_add;
|
||||
// using zpl::pool_allocator;
|
||||
// using zpl::pool_init;
|
||||
// using zpl::pool_free;
|
||||
using zpl::process_exit;
|
||||
using zpl::str_compare;
|
||||
using zpl::str_copy;
|
||||
using zpl::str_fmt_buf;
|
||||
using zpl::str_fmt_va;
|
||||
using zpl::str_fmt_out_va;
|
||||
// using zpl::process_exit;
|
||||
// using zpl::str_compare;
|
||||
// using zpl::str_copy;
|
||||
// using zpl::str_fmt_buf;
|
||||
// using zpl::str_fmt_va;
|
||||
// using zpl::str_fmt_out_va;
|
||||
using zpl::str_fmt_out_err;
|
||||
using zpl::str_fmt_out_err_va;
|
||||
using zpl::str_len;
|
||||
// using zpl::str_len;
|
||||
using zpl::zero_size;
|
||||
|
||||
#if __clang__
|
||||
@ -114,6 +124,27 @@ using zpl::zero_size;
|
||||
#endif
|
||||
|
||||
|
||||
/* Platform compiler */
|
||||
|
||||
#if defined( _MSC_VER )
|
||||
# define ZPL_COMPILER_MSVC 1
|
||||
#elif defined( __GNUC__ )
|
||||
# define ZPL_COMPILER_GCC 1
|
||||
#elif defined( __clang__ )
|
||||
# define ZPL_COMPILER_CLANG 1
|
||||
#elif defined( __MINGW32__ )
|
||||
# define ZPL_COMPILER_MINGW 1
|
||||
#elif defined( __TINYC__ )
|
||||
# define ZPL_COMPILER_TINYC 1
|
||||
#else
|
||||
# error Unknown compiler
|
||||
#endif
|
||||
|
||||
#ifndef zpl_cast
|
||||
# define zpl_cast( Type ) ( Type )
|
||||
#endif
|
||||
|
||||
|
||||
#include "Banned.define.hpp"
|
||||
|
||||
|
||||
@ -163,8 +194,7 @@ using zpl::zero_size;
|
||||
#define rcast( Type_, Value_ ) reinterpret_cast< Type_ >( Value_ )
|
||||
#define pcast( Type_, Value_ ) ( * (Type_*)( & (Value_) ) )
|
||||
#define GEN_STRINGIZE_VA( ... ) #__VA_ARGS__
|
||||
#define txt( ... ) GEN_STRINGIZE_VA( __VA_ARGS__ )
|
||||
#define txt_to_StrC( ... ) sizeof( GEN_STRINGIZE_VA( __VA_ARGS__ ) ), GEN_STRINGIZE_VA( __VA_ARGS__ )
|
||||
#define stringize( ... ) GEN_STRINGIZE_VA( __VA_ARGS__ )
|
||||
#define do_once() \
|
||||
do \
|
||||
{ \
|
||||
@ -194,7 +224,73 @@ namespace gen
|
||||
constexpr
|
||||
char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED";
|
||||
|
||||
#pragma region Debug
|
||||
|
||||
#ifndef ZPL_DEBUG_TRAP
|
||||
# if defined( _MSC_VER )
|
||||
# if _MSC_VER < 1300
|
||||
# define ZPL_DEBUG_TRAP() __asm int 3 /* Trap to debugger! */
|
||||
# else
|
||||
# define ZPL_DEBUG_TRAP() __debugbreak()
|
||||
# endif
|
||||
# elif defined( ZPL_COMPILER_TINYC )
|
||||
# define ZPL_DEBUG_TRAP() process_exit( 1 )
|
||||
# else
|
||||
# define ZPL_DEBUG_TRAP() __builtin_trap()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef ZPL_ASSERT_MSG
|
||||
# define ZPL_ASSERT_MSG( cond, msg, ... ) \
|
||||
do \
|
||||
{ \
|
||||
if ( ! ( cond ) ) \
|
||||
{ \
|
||||
assert_handler( #cond, __FILE__, zpl_cast( s64 ) __LINE__, msg, ##__VA_ARGS__ ); \
|
||||
ZPL_DEBUG_TRAP(); \
|
||||
} \
|
||||
} while ( 0 )
|
||||
#endif
|
||||
|
||||
#ifndef ZPL_ASSERT_NOT_NULL
|
||||
# define ZPL_ASSERT_NOT_NULL( ptr ) ZPL_ASSERT_MSG( ( ptr ) != NULL, #ptr " must not be NULL" )
|
||||
#endif
|
||||
|
||||
// NOTE: Things that shouldn't happen with a message!
|
||||
#ifndef ZPL_PANIC
|
||||
# define ZPL_PANIC( msg, ... ) ZPL_ASSERT_MSG( 0, msg, ##__VA_ARGS__ )
|
||||
#endif
|
||||
|
||||
void assert_handler( char const* condition, char const* file, s32 line, char const* msg, ... );
|
||||
s32 assert_crash( char const* condition );
|
||||
void process_exit( u32 code );
|
||||
|
||||
#pragma endregion Debug
|
||||
|
||||
#pragma region Memory
|
||||
//! Checks if value is power of 2.
|
||||
ZPL_DEF_INLINE b32 is_power_of_two( sw x );
|
||||
|
||||
//! Aligns address to specified alignment.
|
||||
ZPL_DEF_INLINE void* align_forward( void* ptr, sw alignment );
|
||||
|
||||
//! Aligns value to a specified alignment.
|
||||
ZPL_DEF_INLINE s64 align_forward_i64( s64 value, sw alignment );
|
||||
|
||||
//! Moves pointer forward by bytes.
|
||||
ZPL_DEF_INLINE void* pointer_add( void* ptr, sw bytes );
|
||||
|
||||
//! Copy non-overlapping memory from source to destination.
|
||||
void* mem_copy( void* dest, void const* source, sw size );
|
||||
|
||||
//! Search for a constant value within the size limit at memory location.
|
||||
ZPL_DEF void const* mem_find( void const* data, u8 byte_value, sw size );
|
||||
|
||||
//! Copy memory from source to destination.
|
||||
ZPL_DEF_INLINE void* mem_move( void* dest, void const* source, sw size );
|
||||
|
||||
//! Set constant value at memory location with specified size.
|
||||
ZPL_DEF_INLINE void* mem_set( void* data, u8 byte_value, sw size );
|
||||
|
||||
enum AllocType : u8
|
||||
{
|
||||
@ -246,7 +342,6 @@ namespace gen
|
||||
# define alloc_array( allocator_, Type, count ) ( Type* )alloc( allocator_, size_of( Type ) * ( count ) )
|
||||
#endif
|
||||
|
||||
|
||||
/* heap memory analysis tools */
|
||||
/* define ZPL_HEAP_ANALYSIS to enable this feature */
|
||||
/* call zpl_heap_stats_init at the beginning of the entry point */
|
||||
@ -266,17 +361,168 @@ namespace gen
|
||||
//! The heap allocator backed by operating system's memory manager.
|
||||
constexpr AllocatorInfo heap( void ) { return { heap_allocator_proc, nullptr }; }
|
||||
|
||||
// #ifndef malloc
|
||||
#ifndef malloc
|
||||
//! Helper to allocate memory using heap allocator.
|
||||
# define malloc( sz ) alloc( heap(), sz )
|
||||
|
||||
// //! Helper to allocate memory using heap allocator.
|
||||
// # define malloc( sz ) ZPL_NS( alloc )( ZPL_NS( heap_allocator )(), sz )
|
||||
//! Helper to free memory allocated by heap allocator.
|
||||
# define mfree( ptr ) free( heap(), ptr )
|
||||
#endif
|
||||
|
||||
// //! Helper to free memory allocated by heap allocator.
|
||||
// # define mfree( ptr ) ZPL_NS( free )( ZPL_NS( heap_allocator )(), ptr )
|
||||
ZPL_IMPL_INLINE b32 is_power_of_two( sw x )
|
||||
{
|
||||
if ( x <= 0 )
|
||||
return false;
|
||||
return ! ( x & ( x - 1 ) );
|
||||
}
|
||||
|
||||
// //! Alias to heap allocator.
|
||||
// # define heap ZPL_NS( heap_allocator )
|
||||
// #endif
|
||||
ZPL_IMPL_INLINE void* align_forward( void* ptr, sw alignment )
|
||||
{
|
||||
uptr p;
|
||||
|
||||
ZPL_ASSERT( is_power_of_two( alignment ) );
|
||||
|
||||
p = zpl_cast( uptr ) ptr;
|
||||
return zpl_cast( void* )( ( p + ( alignment - 1 ) ) & ~( alignment - 1 ) );
|
||||
}
|
||||
|
||||
ZPL_IMPL_INLINE s64 align_forward_i64( s64 value, sw alignment )
|
||||
{
|
||||
return value + ( alignment - value % alignment ) % alignment;
|
||||
}
|
||||
|
||||
ZPL_IMPL_INLINE void* pointer_add( void* ptr, sw bytes )
|
||||
{
|
||||
return zpl_cast( void* )( zpl_cast( u8* ) ptr + bytes );
|
||||
}
|
||||
|
||||
ZPL_IMPL_INLINE void* mem_move( void* dest, void const* source, sw n )
|
||||
{
|
||||
if ( dest == NULL )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
u8* d = zpl_cast( u8* ) dest;
|
||||
u8 const* s = zpl_cast( u8 const* ) source;
|
||||
|
||||
if ( d == s )
|
||||
return d;
|
||||
if ( s + n <= d || d + n <= s ) // NOTE: Non-overlapping
|
||||
return mem_copy( d, s, n );
|
||||
|
||||
if ( d < s )
|
||||
{
|
||||
if ( zpl_cast( uptr ) s % size_of( sw ) == zpl_cast( uptr ) d % size_of( sw ) )
|
||||
{
|
||||
while ( zpl_cast( uptr ) d % size_of( sw ) )
|
||||
{
|
||||
if ( ! n-- )
|
||||
return dest;
|
||||
*d++ = *s++;
|
||||
}
|
||||
while ( n >= size_of( sw ) )
|
||||
{
|
||||
*zpl_cast( sw* ) d = *zpl_cast( sw* ) s;
|
||||
n -= size_of( sw );
|
||||
d += size_of( sw );
|
||||
s += size_of( sw );
|
||||
}
|
||||
}
|
||||
for ( ; n; n-- )
|
||||
*d++ = *s++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( ( zpl_cast( uptr ) s % size_of( sw ) ) == ( zpl_cast( uptr ) d % size_of( sw ) ) )
|
||||
{
|
||||
while ( zpl_cast( uptr )( d + n ) % size_of( sw ) )
|
||||
{
|
||||
if ( ! n-- )
|
||||
return dest;
|
||||
d[ n ] = s[ n ];
|
||||
}
|
||||
while ( n >= size_of( sw ) )
|
||||
{
|
||||
n -= size_of( sw );
|
||||
*zpl_cast( sw* )( d + n ) = *zpl_cast( sw* )( s + n );
|
||||
}
|
||||
}
|
||||
while ( n )
|
||||
n--, d[ n ] = s[ n ];
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
ZPL_IMPL_INLINE void* mem_set( void* dest, u8 c, sw n )
|
||||
{
|
||||
if ( dest == NULL )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
u8* s = zpl_cast( u8* ) dest;
|
||||
sw k;
|
||||
u32 c32 = ( ( u32 )-1 ) / 255 * c;
|
||||
|
||||
if ( n == 0 )
|
||||
return dest;
|
||||
s[ 0 ] = s[ n - 1 ] = c;
|
||||
if ( n < 3 )
|
||||
return dest;
|
||||
s[ 1 ] = s[ n - 2 ] = c;
|
||||
s[ 2 ] = s[ n - 3 ] = c;
|
||||
if ( n < 7 )
|
||||
return dest;
|
||||
s[ 3 ] = s[ n - 4 ] = c;
|
||||
if ( n < 9 )
|
||||
return dest;
|
||||
|
||||
k = -zpl_cast( sptr ) s & 3;
|
||||
s += k;
|
||||
n -= k;
|
||||
n &= -4;
|
||||
|
||||
*zpl_cast( u32* )( s + 0 ) = c32;
|
||||
*zpl_cast( u32* )( s + n - 4 ) = c32;
|
||||
if ( n < 9 )
|
||||
return dest;
|
||||
*zpl_cast( u32* )( s + 4 ) = c32;
|
||||
*zpl_cast( u32* )( s + 8 ) = c32;
|
||||
*zpl_cast( u32* )( s + n - 12 ) = c32;
|
||||
*zpl_cast( u32* )( s + n - 8 ) = c32;
|
||||
if ( n < 25 )
|
||||
return dest;
|
||||
*zpl_cast( u32* )( s + 12 ) = c32;
|
||||
*zpl_cast( u32* )( s + 16 ) = c32;
|
||||
*zpl_cast( u32* )( s + 20 ) = c32;
|
||||
*zpl_cast( u32* )( s + 24 ) = c32;
|
||||
*zpl_cast( u32* )( s + n - 28 ) = c32;
|
||||
*zpl_cast( u32* )( s + n - 24 ) = c32;
|
||||
*zpl_cast( u32* )( s + n - 20 ) = c32;
|
||||
*zpl_cast( u32* )( s + n - 16 ) = c32;
|
||||
|
||||
k = 24 + ( zpl_cast( uptr ) s & 4 );
|
||||
s += k;
|
||||
n -= k;
|
||||
|
||||
{
|
||||
u64 c64 = ( zpl_cast( u64 ) c32 << 32 ) | c32;
|
||||
while ( n > 31 )
|
||||
{
|
||||
*zpl_cast( u64* )( s + 0 ) = c64;
|
||||
*zpl_cast( u64* )( s + 8 ) = c64;
|
||||
*zpl_cast( u64* )( s + 16 ) = c64;
|
||||
*zpl_cast( u64* )( s + 24 ) = c64;
|
||||
|
||||
n -= 32;
|
||||
s += 32;
|
||||
}
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
ZPL_IMPL_INLINE void* alloc_align( AllocatorInfo a, sw size, sw alignment )
|
||||
{
|
||||
@ -338,14 +584,6 @@ namespace gen
|
||||
}
|
||||
}
|
||||
|
||||
// ZPL_IMPL_INLINE AllocatorInfo heap( void )
|
||||
// {
|
||||
// AllocatorInfo a;
|
||||
// a.Proc = heap_allocator_proc;
|
||||
// a.Data = nullptr;
|
||||
// return a;
|
||||
// }
|
||||
|
||||
struct Arena
|
||||
{
|
||||
static
|
||||
@ -466,9 +704,234 @@ namespace gen
|
||||
return { allocator_proc, this };
|
||||
}
|
||||
};
|
||||
|
||||
#pragma endregion Memory
|
||||
|
||||
#pragma region String Ops
|
||||
ZPL_DEF_INLINE const char* char_first_occurence( const char* str, char c );
|
||||
|
||||
ZPL_DEF_INLINE b32 char_is_alpha( char c );
|
||||
ZPL_DEF_INLINE b32 char_is_alphanumeric( char c );
|
||||
ZPL_DEF_INLINE b32 char_is_digit( char c );
|
||||
ZPL_DEF_INLINE b32 char_is_hex_digit( char c );
|
||||
ZPL_DEF_INLINE b32 char_is_space( char c );
|
||||
ZPL_DEF_INLINE char char_to_lower( char c );
|
||||
ZPL_DEF_INLINE char char_to_upper( char c );
|
||||
|
||||
ZPL_DEF_INLINE s32 digit_to_int( char c );
|
||||
ZPL_DEF_INLINE s32 hex_digit_to_int( char c );
|
||||
|
||||
ZPL_DEF_INLINE s32 str_compare( const char* s1, const char* s2 );
|
||||
ZPL_DEF_INLINE s32 str_compare( const char* s1, const char* s2, sw len );
|
||||
ZPL_DEF_INLINE char* str_copy( char* dest, const char* source, sw len );
|
||||
ZPL_DEF_INLINE sw str_copy_nulpad( char* dest, const char* source, sw len );
|
||||
ZPL_DEF_INLINE sw str_len( const char* str );
|
||||
ZPL_DEF_INLINE sw str_len( const char* str, sw max_len );
|
||||
ZPL_DEF_INLINE char* str_reverse( char* str ); // NOTE: ASCII only
|
||||
|
||||
// NOTE: ASCII only
|
||||
ZPL_DEF_INLINE void str_to_lower( char* str );
|
||||
ZPL_DEF_INLINE void str_to_upper( char* str );
|
||||
|
||||
s64 str_to_i64( const char* str, char** end_ptr, s32 base ); // TODO : Support more than just decimal and hexadecimal
|
||||
void i64_to_str( s64 value, char* string, s32 base );
|
||||
void u64_to_str( u64 value, char* string, s32 base );
|
||||
|
||||
ZPL_IMPL_INLINE const char* char_first_occurence( const char* s, char c )
|
||||
{
|
||||
char ch = c;
|
||||
for ( ; *s != ch; s++ )
|
||||
{
|
||||
if ( *s == '\0' )
|
||||
return NULL;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
ZPL_IMPL_INLINE b32 char_is_alpha( char c )
|
||||
{
|
||||
if ( ( c >= 'A' && c <= 'Z' ) || ( c >= 'a' && c <= 'z' ) )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
ZPL_IMPL_INLINE b32 char_is_alphanumeric( char c )
|
||||
{
|
||||
return char_is_alpha( c ) || char_is_digit( c );
|
||||
}
|
||||
|
||||
ZPL_IMPL_INLINE b32 char_is_digit( char c )
|
||||
{
|
||||
if ( c >= '0' && c <= '9' )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
ZPL_IMPL_INLINE b32 char_is_hex_digit( char c )
|
||||
{
|
||||
if ( char_is_digit( c ) || ( c >= 'a' && c <= 'f' ) || ( c >= 'A' && c <= 'F' ) )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
ZPL_IMPL_INLINE b32 char_is_space( char c )
|
||||
{
|
||||
if ( c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' || c == '\v' )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
ZPL_IMPL_INLINE char char_to_lower( char c )
|
||||
{
|
||||
if ( c >= 'A' && c <= 'Z' )
|
||||
return 'a' + ( c - 'A' );
|
||||
return c;
|
||||
}
|
||||
|
||||
ZPL_IMPL_INLINE char char_to_upper( char c )
|
||||
{
|
||||
if ( c >= 'a' && c <= 'z' )
|
||||
return 'A' + ( c - 'a' );
|
||||
return c;
|
||||
}
|
||||
|
||||
ZPL_IMPL_INLINE s32 digit_to_int( char c )
|
||||
{
|
||||
return char_is_digit( c ) ? c - '0' : c - 'W';
|
||||
}
|
||||
|
||||
ZPL_IMPL_INLINE s32 hex_digit_to_int( char c )
|
||||
{
|
||||
if ( char_is_digit( c ) )
|
||||
return digit_to_int( c );
|
||||
else if ( is_between( c, 'a', 'f' ) )
|
||||
return c - 'a' + 10;
|
||||
else if ( is_between( c, 'A', 'F' ) )
|
||||
return c - 'A' + 10;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ZPL_IMPL_INLINE s32 str_compare( const char* s1, const char* s2 )
|
||||
{
|
||||
while ( *s1 && ( *s1 == *s2 ) )
|
||||
{
|
||||
s1++, s2++;
|
||||
}
|
||||
return *( u8* )s1 - *( u8* )s2;
|
||||
}
|
||||
|
||||
ZPL_IMPL_INLINE s32 str_compare( const char* s1, const char* s2, sw len )
|
||||
{
|
||||
for ( ; len > 0; s1++, s2++, len-- )
|
||||
{
|
||||
if ( *s1 != *s2 )
|
||||
return ( ( s1 < s2 ) ? -1 : +1 );
|
||||
else if ( *s1 == '\0' )
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ZPL_IMPL_INLINE char* str_copy( char* dest, const char* source, sw len )
|
||||
{
|
||||
ZPL_ASSERT_NOT_NULL( dest );
|
||||
if ( source )
|
||||
{
|
||||
char* str = dest;
|
||||
while ( len > 0 && *source )
|
||||
{
|
||||
*str++ = *source++;
|
||||
len--;
|
||||
}
|
||||
while ( len > 0 )
|
||||
{
|
||||
*str++ = '\0';
|
||||
len--;
|
||||
}
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
ZPL_IMPL_INLINE sw str_copy_nulpad( char* dest, const char* source, sw len )
|
||||
{
|
||||
sw result = 0;
|
||||
ZPL_ASSERT_NOT_NULL( dest );
|
||||
if ( source )
|
||||
{
|
||||
const char* source_start = source;
|
||||
char* str = dest;
|
||||
while ( len > 0 && *source )
|
||||
{
|
||||
*str++ = *source++;
|
||||
len--;
|
||||
}
|
||||
while ( len > 0 )
|
||||
{
|
||||
*str++ = '\0';
|
||||
len--;
|
||||
}
|
||||
|
||||
result = source - source_start;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ZPL_IMPL_INLINE sw str_len( const char* str )
|
||||
{
|
||||
if ( str == NULL )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
const char* p = str;
|
||||
while ( *str )
|
||||
str++;
|
||||
return str - p;
|
||||
}
|
||||
|
||||
ZPL_IMPL_INLINE sw str_len( const char* str, sw max_len )
|
||||
{
|
||||
const char* end = zpl_cast( const char* ) mem_find( str, 0, max_len );
|
||||
if ( end )
|
||||
return end - str;
|
||||
return max_len;
|
||||
}
|
||||
|
||||
ZPL_IMPL_INLINE char* str_reverse( char* str )
|
||||
{
|
||||
sw len = str_len( str );
|
||||
char* a = str + 0;
|
||||
char* b = str + len - 1;
|
||||
len /= 2;
|
||||
while ( len-- )
|
||||
{
|
||||
swap( char, *a, *b );
|
||||
a++, b--;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
ZPL_IMPL_INLINE void str_to_lower( char* str )
|
||||
{
|
||||
if ( ! str )
|
||||
return;
|
||||
while ( *str )
|
||||
{
|
||||
*str = char_to_lower( *str );
|
||||
str++;
|
||||
}
|
||||
}
|
||||
|
||||
ZPL_IMPL_INLINE void str_to_upper( char* str )
|
||||
{
|
||||
if ( ! str )
|
||||
return;
|
||||
while ( *str )
|
||||
{
|
||||
*str = char_to_upper( *str );
|
||||
str++;
|
||||
}
|
||||
}
|
||||
#pragma endregion String Ops
|
||||
|
||||
#pragma region Containers
|
||||
#pragma push_macro("template")
|
||||
#undef template
|
||||
@ -551,7 +1014,6 @@ namespace gen
|
||||
{
|
||||
Data[ idx ] = value;
|
||||
}
|
||||
// mem_set( Data + begin, value, end - begin)
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -618,6 +1080,8 @@ namespace gen
|
||||
{
|
||||
if ( ! grow( num ) )
|
||||
return false;
|
||||
|
||||
header = get_header();
|
||||
}
|
||||
|
||||
header->Num = num;
|
||||
@ -635,7 +1099,7 @@ namespace gen
|
||||
header.Num = new_capacity;
|
||||
|
||||
sw size = sizeof( Header ) + sizeof( Type ) * new_capacity;
|
||||
Header* new_header = reinterpret_cast< Header* >( alloc( header.Allocator, size ) );
|
||||
Header* new_header = rcast( Header*, alloc( header.Allocator, size ) );
|
||||
|
||||
if ( new_header == nullptr )
|
||||
return false;
|
||||
@ -703,6 +1167,19 @@ namespace gen
|
||||
return result;
|
||||
}
|
||||
|
||||
static
|
||||
HashTable init_reserve( AllocatorInfo allocator, sw num )
|
||||
{
|
||||
HashTable<Type> result = { { nullptr }, { nullptr } };
|
||||
|
||||
result.Hashes = Array<sw>::init_reserve( allocator, num );
|
||||
result.Hashes.get_header()->Num = num;
|
||||
|
||||
result.Entries = Array<Entry>::init_reserve( allocator, num );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void clear( void )
|
||||
{
|
||||
for ( sw idx = 0; idx < Hashes.num(); idx++ )
|
||||
@ -764,10 +1241,7 @@ namespace gen
|
||||
sw idx;
|
||||
sw last_added_index;
|
||||
|
||||
HashTable<Type> new_ht = init( Hashes.get_header()->Allocator );
|
||||
|
||||
new_ht.Hashes.resize( new_num );
|
||||
new_ht.Entries.reserve( new_ht.Hashes.num() );
|
||||
HashTable<Type> new_ht = init_reserve( Hashes.get_header()->Allocator, new_num );
|
||||
|
||||
Array<sw>::Header* hash_header = new_ht.Hashes.get_header();
|
||||
|
||||
@ -798,8 +1272,6 @@ namespace gen
|
||||
}
|
||||
|
||||
destroy();
|
||||
// Hashes = new_ht.Hashes;
|
||||
// Entries = new_ht.Entries;
|
||||
*this = new_ht;
|
||||
}
|
||||
|
||||
@ -926,6 +1398,12 @@ namespace gen
|
||||
#pragma pop_macro("template")
|
||||
#pragma endregion Containers
|
||||
|
||||
#pragma region Hashing
|
||||
|
||||
u32 crc32( void const* data, sw len );
|
||||
|
||||
#pragma endregion Hashing
|
||||
|
||||
#pragma region String
|
||||
// Constant string with length.
|
||||
struct StrC
|
||||
@ -933,18 +1411,20 @@ namespace gen
|
||||
sw Len;
|
||||
char const* Ptr;
|
||||
|
||||
static constexpr
|
||||
StrC from( char const* str )
|
||||
{
|
||||
return { str_len( str ), str };
|
||||
}
|
||||
|
||||
operator char const* () const
|
||||
{
|
||||
return Ptr;
|
||||
}
|
||||
};
|
||||
|
||||
#define txt_StrC( text ) \
|
||||
(StrC){ sizeof( text ) - 1, text }
|
||||
|
||||
StrC to_StrC( char const* str )
|
||||
{
|
||||
return { str_len( str ), str };
|
||||
}
|
||||
|
||||
// Dynamic String
|
||||
// This is directly based off the ZPL string api.
|
||||
// They used a header pattern
|
||||
@ -1023,29 +1503,10 @@ namespace gen
|
||||
}
|
||||
|
||||
static
|
||||
String fmt( AllocatorInfo allocator, char* buf, sw buf_size, char const* fmt, ... )
|
||||
{
|
||||
va_list va;
|
||||
va_start( va, fmt );
|
||||
str_fmt_va( buf, buf_size, fmt, va );
|
||||
va_end( va );
|
||||
|
||||
return make( allocator, buf );
|
||||
}
|
||||
String fmt( AllocatorInfo allocator, char* buf, sw buf_size, char const* fmt, ... );
|
||||
|
||||
static
|
||||
String fmt_buf( AllocatorInfo allocator, char const* fmt, ... )
|
||||
{
|
||||
local_persist thread_local
|
||||
char buf[ ZPL_PRINTF_MAXLEN ] = { 0 };
|
||||
|
||||
va_list va;
|
||||
va_start( va, fmt );
|
||||
str_fmt_va( buf, ZPL_PRINTF_MAXLEN, fmt, va );
|
||||
va_end( va );
|
||||
|
||||
return make( allocator, buf );
|
||||
}
|
||||
String fmt_buf( AllocatorInfo allocator, char const* fmt, ... );
|
||||
|
||||
static
|
||||
String join( AllocatorInfo allocator, char const** parts, sw num_parts, char const* glue )
|
||||
@ -1151,18 +1612,7 @@ namespace gen
|
||||
return append( other.Data, other.length() );
|
||||
}
|
||||
|
||||
bool append_fmt( char const* fmt, ... )
|
||||
{
|
||||
sw res;
|
||||
char buf[ ZPL_PRINTF_MAXLEN ] = { 0 };
|
||||
|
||||
va_list va;
|
||||
va_start( va, fmt );
|
||||
res = str_fmt_va( buf, count_of( buf ) - 1, fmt, va ) - 1;
|
||||
va_end( va );
|
||||
|
||||
return append( buf, res );
|
||||
}
|
||||
bool append_fmt( char const* fmt, ... );
|
||||
|
||||
sw avail_space() const
|
||||
{
|
||||
@ -1424,6 +1874,22 @@ namespace gen
|
||||
DirEntry* Dir;
|
||||
};
|
||||
|
||||
enum FileStandardType
|
||||
{
|
||||
EFileStandard_INPUT,
|
||||
EFileStandard_OUTPUT,
|
||||
EFileStandard_ERROR,
|
||||
|
||||
EFileStandard_COUNT,
|
||||
};
|
||||
|
||||
/**
|
||||
* Get standard file I/O.
|
||||
* @param std Check zpl_file_standard_type
|
||||
* @return File handle to standard I/O
|
||||
*/
|
||||
FileInfo* file_get_standard( FileStandardType std );
|
||||
|
||||
/**
|
||||
* Closes the file
|
||||
* @param file
|
||||
@ -1533,6 +1999,7 @@ namespace gen
|
||||
{
|
||||
if ( ! f->Ops.read_at )
|
||||
f->Ops = default_file_operations;
|
||||
|
||||
return f->Ops.write_at( f->FD, buffer, size, offset, bytes_written );
|
||||
}
|
||||
|
||||
@ -1540,6 +2007,17 @@ namespace gen
|
||||
|
||||
#pragma endregion File Handling
|
||||
|
||||
#pragma region Printing
|
||||
|
||||
// NOTE: A locally persisting buffer is used internally
|
||||
char* str_fmt_buf( char const* fmt, ... );
|
||||
char* str_fmt_buf_va( char const* fmt, va_list va );
|
||||
sw str_fmt_va( char* str, sw n, char const* fmt, va_list va );
|
||||
sw str_fmt_out_va( char const* fmt, va_list va );
|
||||
sw str_fmt_file_va( FileInfo* f, char const* fmt, va_list va );
|
||||
|
||||
#pragma endregion Printing
|
||||
|
||||
namespace Memory
|
||||
{
|
||||
// NOTE: This limits the size of the string that can be read from a file or generated to 10 megs.
|
||||
@ -1556,7 +2034,6 @@ namespace gen
|
||||
void cleanup();
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
sw log_fmt(char const* fmt, ...)
|
||||
{
|
||||
|
225
project/gen.cpp
225
project/gen.cpp
@ -1097,7 +1097,7 @@ namespace gen
|
||||
}
|
||||
|
||||
Code::Global = make_code();
|
||||
Code::Global->Name = get_cached_string( name("Global Code") );
|
||||
Code::Global->Name = get_cached_string( txt_StrC("Global Code") );
|
||||
Code::Global->Content = Code::Global->Name;
|
||||
|
||||
Code::Invalid = make_code();
|
||||
@ -1139,34 +1139,34 @@ namespace gen
|
||||
|
||||
access_private = make_code();
|
||||
access_private->Type = ECode::Access_Private;
|
||||
access_private->Name = get_cached_string( StrC::from("private:") );
|
||||
access_private->Name = get_cached_string( txt_StrC("private:") );
|
||||
access_private.set_global();
|
||||
|
||||
access_protected = make_code();
|
||||
access_protected->Type = ECode::Access_Protected;
|
||||
access_protected->Name = get_cached_string( StrC::from("protected:") );
|
||||
access_protected->Name = get_cached_string( txt_StrC("protected:") );
|
||||
access_protected.set_global();
|
||||
|
||||
access_public = make_code();
|
||||
access_public->Type = ECode::Access_Public;
|
||||
access_public->Name = get_cached_string( StrC::from("public:") );
|
||||
access_public->Name = get_cached_string( txt_StrC("public:") );
|
||||
access_public.set_global();
|
||||
|
||||
module_global_fragment = make_code();
|
||||
module_global_fragment->Type = ECode::Untyped;
|
||||
module_global_fragment->Name = get_cached_string( StrC::from("module;") );
|
||||
module_global_fragment->Name = get_cached_string( txt_StrC("module;") );
|
||||
module_global_fragment->Content = module_global_fragment->Name;
|
||||
module_global_fragment.set_global();
|
||||
|
||||
module_private_fragment = make_code();
|
||||
module_private_fragment->Type = ECode::Untyped;
|
||||
module_private_fragment->Name = get_cached_string( StrC::from("module : private;") );
|
||||
module_private_fragment->Name = get_cached_string( txt_StrC("module : private;") );
|
||||
module_private_fragment->Content = module_private_fragment->Name;
|
||||
module_private_fragment.set_global();
|
||||
|
||||
pragma_once = make_code();
|
||||
pragma_once->Type = ECode::Untyped;
|
||||
pragma_once->Name = get_cached_string( StrC::from("#pragma once") );
|
||||
pragma_once->Name = get_cached_string( txt_StrC("#pragma once") );
|
||||
pragma_once->Content = pragma_once->Name;
|
||||
pragma_once.set_global();
|
||||
|
||||
@ -1733,13 +1733,13 @@ namespace gen
|
||||
{ \
|
||||
if ( Name_.Len <= 0 ) \
|
||||
{ \
|
||||
log_failure( "gen::" txt(Context_) ": Invalid name length provided - %d", Name_.Len ); \
|
||||
log_failure( "gen::" stringize(Context_) ": Invalid name length provided - %d", Name_.Len ); \
|
||||
return Code::Invalid; \
|
||||
} \
|
||||
\
|
||||
if ( Name_.Ptr == nullptr ) \
|
||||
{ \
|
||||
log_failure( "gen::" txt(Context_) ": name is null" ); \
|
||||
log_failure( "gen::" stringize(Context_) ": name is null" ); \
|
||||
return Code::Invalid; \
|
||||
} \
|
||||
}
|
||||
@ -1747,7 +1747,7 @@ namespace gen
|
||||
# define null_check( Context_, Code_ ) \
|
||||
if ( ! Code_ ) \
|
||||
{ \
|
||||
log_failure( "gen::" txt(Context_) ": " txt(Code_) " provided is null" ); \
|
||||
log_failure( "gen::" stringize(Context_) ": " stringize(Code_) " provided is null" ); \
|
||||
return Code::Invalid; \
|
||||
}
|
||||
|
||||
@ -1755,13 +1755,13 @@ namespace gen
|
||||
{ \
|
||||
if ( ! Code_ ) \
|
||||
{ \
|
||||
log_failure( "gen::" txt(Context_) ": " txt(Code_) " provided is null" ); \
|
||||
log_failure( "gen::" stringize(Context_) ": " stringize(Code_) " provided is null" ); \
|
||||
return Code::Invalid; \
|
||||
} \
|
||||
\
|
||||
if ( Code_->is_invalid() ) \
|
||||
{ \
|
||||
log_failure("gen::" txt(Context_) ": " txt(Code_) " provided is invalid" ); \
|
||||
log_failure("gen::" stringize(Context_) ": " stringize(Code_) " provided is invalid" ); \
|
||||
return Code::Invalid; \
|
||||
} \
|
||||
}
|
||||
@ -2633,7 +2633,7 @@ namespace gen
|
||||
\
|
||||
if ( num <= 0 ) \
|
||||
{ \
|
||||
log_failure("gen::" txt(Name_) ": num cannot be zero or negative"); \
|
||||
log_failure("gen::" stringize(Name_) ": num cannot be zero or negative"); \
|
||||
return Code::Invalid; \
|
||||
}
|
||||
|
||||
@ -2642,7 +2642,7 @@ namespace gen
|
||||
\
|
||||
if ( num <= 0 ) \
|
||||
{ \
|
||||
log_failure("gen::" txt(Name_) ": num cannot be zero or negative"); \
|
||||
log_failure("gen::" stringize(Name_) ": num cannot be zero or negative"); \
|
||||
return Code::Invalid; \
|
||||
} \
|
||||
\
|
||||
@ -2660,7 +2660,7 @@ namespace gen
|
||||
\
|
||||
if ( ! entry ) \
|
||||
{ \
|
||||
log_failure("gen::" txt(Name_) ": Provided an null entry"); \
|
||||
log_failure("gen::" stringize(Name_) ": Provided an null entry"); \
|
||||
return Code::Invalid; \
|
||||
} \
|
||||
\
|
||||
@ -2674,7 +2674,7 @@ namespace gen
|
||||
\
|
||||
if ( ! entry ) \
|
||||
{ \
|
||||
log_failure("gen::" txt(Name_) ": Provided an null entry"); \
|
||||
log_failure("gen::" stringize(Name_) ": Provided an null entry"); \
|
||||
return Code::Invalid; \
|
||||
} \
|
||||
\
|
||||
@ -2682,7 +2682,7 @@ namespace gen
|
||||
{
|
||||
|
||||
# define def_body_code_validation_end( Name_ ) \
|
||||
log_failure("gen::" txt(Name_) ": Entry type is not allowed: %s", entry->debug_str() ); \
|
||||
log_failure("gen::" stringize(Name_) ": Entry type is not allowed: %s", entry->debug_str() ); \
|
||||
return Code::Invalid; \
|
||||
\
|
||||
default: \
|
||||
@ -3451,7 +3451,7 @@ namespace gen
|
||||
local_persist thread_local
|
||||
Array<Token> Tokens = { nullptr };
|
||||
|
||||
s32 left = content.Len -1;
|
||||
s32 left = content.Len;
|
||||
char const* scanner = content.Ptr;
|
||||
|
||||
char const* word = scanner;
|
||||
@ -3898,16 +3898,16 @@ namespace gen
|
||||
}
|
||||
|
||||
#pragma region Helper Macros
|
||||
# define check_parse_args( func, def ) \
|
||||
if ( def.Len <= 0 ) \
|
||||
{ \
|
||||
log_failure( "gen::" txt(func) ": length must greater than 0" ); \
|
||||
return Code::Invalid; \
|
||||
} \
|
||||
if ( def.Ptr == nullptr ) \
|
||||
{ \
|
||||
log_failure( "gen::" txt(func) ": def was null" ); \
|
||||
return Code::Invalid; \
|
||||
# define check_parse_args( func, def ) \
|
||||
if ( def.Len <= 0 ) \
|
||||
{ \
|
||||
log_failure( "gen::" stringize(func) ": length must greater than 0" ); \
|
||||
return Code::Invalid; \
|
||||
} \
|
||||
if ( def.Ptr == nullptr ) \
|
||||
{ \
|
||||
log_failure( "gen::" stringize(func) ": def was null" ); \
|
||||
return Code::Invalid; \
|
||||
}
|
||||
|
||||
# define nexttok toks.next()
|
||||
@ -3950,13 +3950,13 @@ namespace gen
|
||||
|
||||
if ( left == 0 )
|
||||
{
|
||||
log_failure( "%s: Error, unexpected end of typedef definition ( '[]' scope started )", txt(parse_typedef) );
|
||||
log_failure( "%s: Error, unexpected end of typedef definition ( '[]' scope started )", stringize(parse_typedef) );
|
||||
return Code::Invalid;
|
||||
}
|
||||
|
||||
if ( currtok.Type == TokType::BraceSquare_Close )
|
||||
{
|
||||
log_failure( "%s: Error, empty array expression in typedef definition", txt(parse_typedef) );
|
||||
log_failure( "%s: Error, empty array expression in typedef definition", stringize(parse_typedef) );
|
||||
return Code::Invalid;
|
||||
}
|
||||
|
||||
@ -3973,13 +3973,13 @@ namespace gen
|
||||
|
||||
if ( left == 0 )
|
||||
{
|
||||
log_failure( "%s: Error, unexpected end of type definition, expected ]", txt(parse_typedef) );
|
||||
log_failure( "%s: Error, unexpected end of type definition, expected ]", stringize(parse_typedef) );
|
||||
return Code::Invalid;
|
||||
}
|
||||
|
||||
if ( currtok.Type != TokType::BraceSquare_Close )
|
||||
{
|
||||
log_failure( "%s: Error, expected ] in type definition, not %s", txt(parse_typedef), str_tok_type( currtok.Type ) );
|
||||
log_failure( "%s: Error, expected ] in type definition, not %s", stringize(parse_typedef), str_tok_type( currtok.Type ) );
|
||||
return Code::Invalid;
|
||||
}
|
||||
|
||||
@ -4179,12 +4179,12 @@ namespace gen
|
||||
{
|
||||
using namespace Parser;
|
||||
|
||||
Code params = parse_params( toks, txt(parse_function) );
|
||||
Code params = parse_params( toks, stringize(parse_function) );
|
||||
|
||||
Code body = { nullptr };
|
||||
if ( check( TokType::BraceCurly_Open ) )
|
||||
{
|
||||
body = parse_function_body( toks, txt(parse_function) );
|
||||
body = parse_function_body( toks, stringize(parse_function) );
|
||||
if ( body == Code::Invalid )
|
||||
return Code::Invalid;
|
||||
}
|
||||
@ -4438,13 +4438,13 @@ namespace gen
|
||||
eat( TokType::Operator );
|
||||
|
||||
// Parse Params
|
||||
Code params = parse_params( toks, txt(parse_operator) );
|
||||
Code params = parse_params( toks, stringize(parse_operator) );
|
||||
|
||||
// Parse Body
|
||||
Code body = { nullptr };
|
||||
if ( check( TokType::BraceCurly_Open ) )
|
||||
{
|
||||
body = parse_function_body( toks, txt(parse_function) );
|
||||
body = parse_function_body( toks, stringize(parse_function) );
|
||||
if ( body == Code::Invalid )
|
||||
return Code::Invalid;
|
||||
}
|
||||
@ -4471,7 +4471,7 @@ namespace gen
|
||||
{
|
||||
using namespace Parser;
|
||||
|
||||
Code array_expr = parse_array_decl( toks, txt(parse_variable) );
|
||||
Code array_expr = parse_array_decl( toks, stringize(parse_variable) );
|
||||
|
||||
Code expr = Code::Invalid;
|
||||
|
||||
@ -4561,7 +4561,7 @@ namespace gen
|
||||
|
||||
Code result = Code::Invalid;
|
||||
|
||||
Code type = parse_type( toks, txt(parse_variable) );
|
||||
Code type = parse_type( toks, stringize(parse_variable) );
|
||||
|
||||
if ( type == Code::Invalid )
|
||||
return Code::Invalid;
|
||||
@ -4569,7 +4569,7 @@ namespace gen
|
||||
if ( check( TokType::Operator) )
|
||||
{
|
||||
// Dealing with an operator overload
|
||||
result = parse_operator_after_ret_type( ModuleFlag::None, attributes, specifiers, type, toks, txt(parse_template) );
|
||||
result = parse_operator_after_ret_type( ModuleFlag::None, attributes, specifiers, type, toks, stringize(parse_template) );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -4580,7 +4580,7 @@ namespace gen
|
||||
{
|
||||
// Dealing with a function
|
||||
|
||||
result = parse_function_after_name( ModuleFlag::None, attributes, specifiers, type, name, toks, txt(parse_template) );
|
||||
result = parse_function_after_name( ModuleFlag::None, attributes, specifiers, type, name, toks, stringize(parse_template) );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -4591,7 +4591,7 @@ namespace gen
|
||||
}
|
||||
|
||||
// Dealing with a variable
|
||||
result = parse_variable_after_name( ModuleFlag::None, attributes, specifiers, type, name, toks, txt(parse_template) );
|
||||
result = parse_variable_after_name( ModuleFlag::None, attributes, specifiers, type, name, toks, stringize(parse_template) );
|
||||
}
|
||||
}
|
||||
|
||||
@ -4746,7 +4746,7 @@ namespace gen
|
||||
break;
|
||||
|
||||
default:
|
||||
log_failure( "gen::parse_class_struct_body: invalid specifier " txt(spec) " for variable" );
|
||||
log_failure( "gen::parse_class_struct_body: invalid specifier " "%s" " for variable", ESpecifier::to_str(spec) );
|
||||
return Code::Invalid;
|
||||
}
|
||||
|
||||
@ -4948,7 +4948,7 @@ namespace gen
|
||||
|
||||
case TokType::Decl_Extern_Linkage:
|
||||
if ( which == Extern_Linkage_Body )
|
||||
log_failure( "gen::parse_extern_link_body: nested extern linkage" );
|
||||
log_failure( "gen::parse_global_nspace: nested extern linkage" );
|
||||
|
||||
member = parse_extern_link_body( toks, context );
|
||||
break;
|
||||
@ -4979,7 +4979,7 @@ namespace gen
|
||||
|
||||
case TokType::Module_Export:
|
||||
if ( which == Export_Body )
|
||||
log_failure( "gen::parse_extern_link_body: nested export declaration" );
|
||||
log_failure( "gen::parse_global_nspace: nested export declaration" );
|
||||
|
||||
member = parse_export_body( toks, context );
|
||||
break;
|
||||
@ -5054,7 +5054,7 @@ namespace gen
|
||||
break;
|
||||
|
||||
default:
|
||||
log_failure( "gen::parse_class_struct_body: invalid specifier " txt(spec) " for variable" );
|
||||
log_failure( "gen::parse_global_nspace: invalid specifier " "%s" " for variable", ESpecifier::to_str(spec) );
|
||||
return Code::Invalid;
|
||||
}
|
||||
|
||||
@ -5110,7 +5110,7 @@ namespace gen
|
||||
if ( toks.Arr == nullptr )
|
||||
return Code::Invalid;
|
||||
|
||||
return parse_class_struct( TokType::Decl_Class, toks, txt(parse_class) );
|
||||
return parse_class_struct( TokType::Decl_Class, toks, stringize(parse_class) );
|
||||
}
|
||||
|
||||
internal
|
||||
@ -5155,7 +5155,7 @@ namespace gen
|
||||
{
|
||||
eat( TokType::Assign_Classifer );
|
||||
|
||||
type = parse_type( toks, txt(parse_enum) );
|
||||
type = parse_type( toks, stringize(parse_enum) );
|
||||
if ( type == Code::Invalid )
|
||||
return Code::Invalid;
|
||||
}
|
||||
@ -5229,7 +5229,7 @@ namespace gen
|
||||
if ( toks.Arr == nullptr )
|
||||
return Code::Invalid;
|
||||
|
||||
return parse_enum( toks, txt(parse_enum) );
|
||||
return parse_enum( toks, stringize(parse_enum) );
|
||||
}
|
||||
|
||||
internal inline
|
||||
@ -5247,7 +5247,7 @@ namespace gen
|
||||
if ( toks.Arr == nullptr )
|
||||
return Code::Invalid;
|
||||
|
||||
return parse_export_body( toks, txt(parse_export_body) );
|
||||
return parse_export_body( toks, stringize(parse_export_body) );
|
||||
}
|
||||
|
||||
internal inline
|
||||
@ -5295,7 +5295,7 @@ namespace gen
|
||||
if ( toks.Arr == nullptr )
|
||||
return Code::Invalid;
|
||||
|
||||
return parse_extern_link( toks, txt(parse_extern_link) );
|
||||
return parse_extern_link( toks, stringize(parse_extern_link) );
|
||||
}
|
||||
|
||||
internal
|
||||
@ -5309,7 +5309,7 @@ namespace gen
|
||||
Code function = { nullptr };
|
||||
|
||||
// Type declaration or return type
|
||||
Code type = parse_type( toks, txt(parse_friend) );
|
||||
Code type = parse_type( toks, stringize(parse_friend) );
|
||||
if ( type == Code::Invalid )
|
||||
return Code::Invalid;
|
||||
|
||||
@ -5317,10 +5317,10 @@ namespace gen
|
||||
if ( currtok.Type == TokType::Identifier )
|
||||
{
|
||||
// Name
|
||||
Token name = parse_identifier( toks, txt(parse_friend) );
|
||||
Token name = parse_identifier( toks, stringize(parse_friend) );
|
||||
|
||||
// Parameter list
|
||||
Code params = parse_params( toks, txt(parse_friend) );
|
||||
Code params = parse_params( toks, stringize(parse_friend) );
|
||||
|
||||
function = make_code();
|
||||
function->Type = Function_Fwd;
|
||||
@ -5355,7 +5355,7 @@ namespace gen
|
||||
if ( toks.Arr == nullptr )
|
||||
return Code::Invalid;
|
||||
|
||||
return parse_friend( toks, txt(parse_friend) );
|
||||
return parse_friend( toks, stringize(parse_friend) );
|
||||
}
|
||||
|
||||
internal
|
||||
@ -5388,7 +5388,7 @@ namespace gen
|
||||
break;
|
||||
|
||||
default:
|
||||
log_failure( "gen::parse_variable: invalid specifier " txt(spec) " for variable" );
|
||||
log_failure( "gen::parse_functon: invalid specifier " "%s" " for functon", ESpecifier::to_str(spec) );
|
||||
return Code::Invalid;
|
||||
}
|
||||
|
||||
@ -5402,11 +5402,11 @@ namespace gen
|
||||
specifiers = def_specifiers( num_specifiers, specs_found );
|
||||
}
|
||||
|
||||
Code ret_type = parse_type( toks, txt(parse_function) );
|
||||
Code ret_type = parse_type( toks, stringize(parse_function) );
|
||||
if ( ret_type == Code::Invalid )
|
||||
return Code::Invalid;
|
||||
|
||||
Token name = parse_identifier( toks, txt(parse_function) );
|
||||
Token name = parse_identifier( toks, stringize(parse_function) );
|
||||
if ( ! name )
|
||||
return Code::Invalid;
|
||||
|
||||
@ -5425,7 +5425,7 @@ namespace gen
|
||||
if ( toks.Arr == nullptr )
|
||||
return Code::Invalid;
|
||||
|
||||
return parse_functon( toks, txt(parse_function) );
|
||||
return parse_functon( toks, stringize(parse_function) );
|
||||
}
|
||||
|
||||
Code parse_global_body( StrC def )
|
||||
@ -5437,7 +5437,7 @@ namespace gen
|
||||
if ( toks.Arr == nullptr )
|
||||
return Code::Invalid;
|
||||
|
||||
return parse_global_nspace( ECode::Global_Body, toks, txt(parse_global_body) );
|
||||
return parse_global_nspace( ECode::Global_Body, toks, stringize(parse_global_body) );
|
||||
}
|
||||
|
||||
internal
|
||||
@ -5446,9 +5446,9 @@ namespace gen
|
||||
using namespace Parser;
|
||||
eat( TokType::Decl_Namespace );
|
||||
|
||||
Token name = parse_identifier( toks, txt(parse_namespace) );
|
||||
Token name = parse_identifier( toks, stringize(parse_namespace) );
|
||||
|
||||
Code body = parse_global_nspace( ECode::Namespace_Body, toks, txt(parse_namespace) );
|
||||
Code body = parse_global_nspace( ECode::Namespace_Body, toks, stringize(parse_namespace) );
|
||||
if ( body == Code::Invalid )
|
||||
return Code::Invalid;
|
||||
|
||||
@ -5471,7 +5471,7 @@ namespace gen
|
||||
if ( toks.Arr == nullptr )
|
||||
return Code::Invalid;
|
||||
|
||||
return parse_namespace( toks, txt(parse_namespace) );
|
||||
return parse_namespace( toks, stringize(parse_namespace) );
|
||||
}
|
||||
|
||||
internal
|
||||
@ -5500,7 +5500,7 @@ namespace gen
|
||||
break;
|
||||
|
||||
default:
|
||||
log_failure( "gen::parse_variable: invalid specifier " txt(spec) " for variable" );
|
||||
log_failure( "gen::parse_operator: invalid specifier " "%s" " for operator", ESpecifier::to_str(spec) );
|
||||
return Code::Invalid;
|
||||
}
|
||||
|
||||
@ -5515,7 +5515,7 @@ namespace gen
|
||||
}
|
||||
|
||||
// Parse Return Type
|
||||
Code ret_type = parse_type( toks, txt(parse_operator) );
|
||||
Code ret_type = parse_type( toks, stringize(parse_operator) );
|
||||
|
||||
Code result = parse_operator_after_ret_type( ModuleFlag::None, attributes, specifiers, ret_type, toks, context );
|
||||
return result;
|
||||
@ -5530,7 +5530,7 @@ namespace gen
|
||||
if ( toks.Arr == nullptr )
|
||||
return Code::Invalid;
|
||||
|
||||
return parse_operator( toks, txt(parse_operator) );
|
||||
return parse_operator( toks, stringize(parse_operator) );
|
||||
}
|
||||
|
||||
Code parse_operator_cast( Parser::TokArray& toks, char const* context )
|
||||
@ -5539,7 +5539,7 @@ namespace gen
|
||||
|
||||
eat( TokType::Decl_Operator );
|
||||
|
||||
Code type = parse_type( toks, txt(parse_operator_cast) );
|
||||
Code type = parse_type( toks, stringize(parse_operator_cast) );
|
||||
|
||||
eat( TokType::Capture_Start );
|
||||
eat( TokType::Capture_End );
|
||||
@ -5597,13 +5597,13 @@ namespace gen
|
||||
if ( toks.Arr == nullptr )
|
||||
return Code::Invalid;
|
||||
|
||||
return parse_operator_cast( toks, txt(parse_operator_cast) );
|
||||
return parse_operator_cast( toks, stringize(parse_operator_cast) );
|
||||
}
|
||||
|
||||
internal inline
|
||||
Code parse_struct( Parser::TokArray& toks, char const* context )
|
||||
{
|
||||
return parse_class_struct( Parser::TokType::Decl_Struct, toks, txt(parse_struct) );
|
||||
return parse_class_struct( Parser::TokType::Decl_Struct, toks, stringize(parse_struct) );
|
||||
}
|
||||
|
||||
Code parse_struct( StrC def )
|
||||
@ -5615,7 +5615,7 @@ namespace gen
|
||||
if ( toks.Arr == nullptr )
|
||||
return Code::Invalid;
|
||||
|
||||
return parse_class_struct( TokType::Decl_Struct, toks, txt(parse_struct) );
|
||||
return parse_class_struct( TokType::Decl_Struct, toks, stringize(parse_struct) );
|
||||
}
|
||||
|
||||
internal
|
||||
@ -5629,7 +5629,7 @@ namespace gen
|
||||
|
||||
eat( TokType::Decl_Template );
|
||||
|
||||
Code params = parse_params( toks, txt(parse_template), UseTemplateCapture );
|
||||
Code params = parse_params( toks, stringize(parse_template), UseTemplateCapture );
|
||||
if ( params == Code::Invalid )
|
||||
return Code::Invalid;
|
||||
|
||||
@ -5639,19 +5639,19 @@ namespace gen
|
||||
{
|
||||
if ( check( TokType::Decl_Class ) )
|
||||
{
|
||||
definition = parse_class( toks, txt(parse_template) );
|
||||
definition = parse_class( toks, stringize(parse_template) );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( check( TokType::Decl_Struct ) )
|
||||
{
|
||||
definition = parse_enum( toks, txt(parse_template) );
|
||||
definition = parse_enum( toks, stringize(parse_template) );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( check( TokType::Decl_Using ))
|
||||
{
|
||||
definition = parse_using( toks, txt(parse_template) );
|
||||
definition = parse_using( toks, stringize(parse_template) );
|
||||
break;
|
||||
}
|
||||
|
||||
@ -5693,7 +5693,7 @@ namespace gen
|
||||
break;
|
||||
|
||||
default:
|
||||
log_failure( "gen::parse_template: invalid specifier " txt(spec) " for variable or function" );
|
||||
log_failure( "gen::parse_template: invalid specifier %s for variable or function", ESpecifier::to_str( spec ) );
|
||||
return Code::Invalid;
|
||||
}
|
||||
|
||||
@ -5711,7 +5711,7 @@ namespace gen
|
||||
specifiers = def_specifiers( num_specifiers, specs_found );
|
||||
}
|
||||
|
||||
definition = parse_operator_function_or_variable( expects_function, attributes, specifiers, toks, txt(parse_template) );
|
||||
definition = parse_operator_function_or_variable( expects_function, attributes, specifiers, toks, stringize(parse_template) );
|
||||
break;
|
||||
}
|
||||
|
||||
@ -5734,7 +5734,7 @@ namespace gen
|
||||
if ( toks.Arr == nullptr )
|
||||
return Code::Invalid;
|
||||
|
||||
return parse_template( toks, txt(parse_template) );
|
||||
return parse_template( toks, stringize(parse_template) );
|
||||
}
|
||||
|
||||
internal
|
||||
@ -5915,7 +5915,7 @@ namespace gen
|
||||
if ( toks.Arr == nullptr )
|
||||
return Code::Invalid;
|
||||
|
||||
Code result = parse_type( toks, txt(parse_type) );
|
||||
Code result = parse_type( toks, stringize(parse_type) );
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -5931,7 +5931,7 @@ namespace gen
|
||||
|
||||
eat( TokType::Decl_Typedef );
|
||||
|
||||
type = parse_type( toks, txt(parse_typedef) );
|
||||
type = parse_type( toks, stringize(parse_typedef) );
|
||||
|
||||
if ( ! check( TokType::Identifier ) )
|
||||
{
|
||||
@ -5942,7 +5942,7 @@ namespace gen
|
||||
name = currtok;
|
||||
eat( TokType::Identifier );
|
||||
|
||||
array_expr = parse_array_decl( toks, txt(parse_typedef) );
|
||||
array_expr = parse_array_decl( toks, stringize(parse_typedef) );
|
||||
|
||||
eat( TokType::Statement_End );
|
||||
|
||||
@ -5970,7 +5970,7 @@ namespace gen
|
||||
if ( toks.Arr == nullptr )
|
||||
return Code::Invalid;
|
||||
|
||||
return parse_typedef( toks, txt(parse_typedef) );
|
||||
return parse_typedef( toks, stringize(parse_typedef) );
|
||||
}
|
||||
|
||||
internal
|
||||
@ -6002,7 +6002,7 @@ namespace gen
|
||||
|
||||
while ( ! check( TokType::BraceCurly_Close ) )
|
||||
{
|
||||
Code entry = parse_variable( toks, txt(parse_union) );
|
||||
Code entry = parse_variable( toks, stringize(parse_union) );
|
||||
|
||||
if ( entry )
|
||||
body->add_entry( entry );
|
||||
@ -6036,7 +6036,7 @@ namespace gen
|
||||
if ( toks.Arr == nullptr )
|
||||
return Code::Invalid;
|
||||
|
||||
return parse_union( toks, txt(parse_union) );
|
||||
return parse_union( toks, stringize(parse_union) );
|
||||
}
|
||||
|
||||
internal
|
||||
@ -6072,10 +6072,10 @@ namespace gen
|
||||
|
||||
eat( TokType::Operator );
|
||||
|
||||
type = parse_type( toks, txt(parse_typedef) );
|
||||
type = parse_type( toks, stringize(parse_typedef) );
|
||||
}
|
||||
|
||||
array_expr = parse_array_decl( toks, txt(parse_typedef) );
|
||||
array_expr = parse_array_decl( toks, stringize(parse_typedef) );
|
||||
|
||||
eat( TokType::Statement_End );
|
||||
|
||||
@ -6104,7 +6104,7 @@ namespace gen
|
||||
if ( toks.Arr == nullptr )
|
||||
return Code::Invalid;
|
||||
|
||||
return parse_using( toks, txt(parse_using) );
|
||||
return parse_using( toks, stringize(parse_using) );
|
||||
}
|
||||
|
||||
internal
|
||||
@ -6144,7 +6144,7 @@ namespace gen
|
||||
break;
|
||||
|
||||
default:
|
||||
log_failure( "gen::parse_variable: invalid specifier " txt(spec) " for variable" );
|
||||
log_failure( "gen::parse_variable: invalid specifier %s for variable", ESpecifier::to_str( spec ) );
|
||||
return Code::Invalid;
|
||||
}
|
||||
|
||||
@ -6162,7 +6162,7 @@ namespace gen
|
||||
specifiers = def_specifiers( num_specifiers, specs_found );
|
||||
}
|
||||
|
||||
Code type = parse_type( toks, txt(parse_variable) );
|
||||
Code type = parse_type( toks, stringize(parse_variable) );
|
||||
|
||||
if ( type == Code::Invalid )
|
||||
return Code::Invalid;
|
||||
@ -6170,7 +6170,7 @@ namespace gen
|
||||
name = currtok;
|
||||
eat( TokType::Identifier );
|
||||
|
||||
Code result = parse_variable_after_name( ModuleFlag::None, attributes, specifiers, type, name, toks, txt(parse_variable) );
|
||||
Code result = parse_variable_after_name( ModuleFlag::None, attributes, specifiers, type, name, toks, stringize(parse_variable) );
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -6184,7 +6184,7 @@ namespace gen
|
||||
if ( toks.Arr == nullptr )
|
||||
return Code::Invalid;
|
||||
|
||||
return parse_variable( toks, txt(parse_variable) );
|
||||
return parse_variable( toks, stringize(parse_variable) );
|
||||
}
|
||||
|
||||
// Undef helper macros
|
||||
@ -6197,42 +6197,31 @@ namespace gen
|
||||
#pragma endregion Parsing Constructors
|
||||
|
||||
#pragma region Untyped Constructors
|
||||
struct TokEntry
|
||||
{
|
||||
char const* Str;
|
||||
sw Length;
|
||||
};
|
||||
|
||||
sw token_fmt_va( char* buf, uw buf_size, char const* fmt, s32 num_tokens, va_list va )
|
||||
sw token_fmt_va( char* buf, uw buf_size, s32 num_tokens, va_list va )
|
||||
{
|
||||
char const* buf_begin = buf;
|
||||
sw remaining = buf_size;
|
||||
|
||||
HashTable<TokEntry> tok_map;
|
||||
HashTable<StrC> tok_map;
|
||||
{
|
||||
// TODO : Switch this to use an arena that makes use of the stack (cap the size of the token table to around 4096 bytes)
|
||||
tok_map = HashTable<TokEntry>::init( Memory::GlobalAllocator );
|
||||
tok_map = HashTable<StrC>::init( Memory::GlobalAllocator );
|
||||
|
||||
s32 left = num_tokens;
|
||||
s32 left = num_tokens - 1;
|
||||
|
||||
while ( left-- )
|
||||
{
|
||||
char const* token = va_arg( va, char const* );
|
||||
char const* value = va_arg( va, char const* );
|
||||
StrC value = va_arg( va, StrC );
|
||||
|
||||
TokEntry entry
|
||||
{
|
||||
value,
|
||||
str_len(value, (sw)128)
|
||||
};
|
||||
u32 key = crc32( token, str_len(token) );
|
||||
|
||||
u32 key = crc32( token, str_len(token, 32) );
|
||||
|
||||
tok_map.set( key, entry );
|
||||
tok_map.set( key, value );
|
||||
}
|
||||
}
|
||||
|
||||
char current = *fmt;
|
||||
char const* fmt = va_arg( va, char const* );
|
||||
char current = *fmt;
|
||||
|
||||
while ( current )
|
||||
{
|
||||
@ -6263,12 +6252,12 @@ namespace gen
|
||||
char const* token = fmt + 1;
|
||||
|
||||
u32 key = crc32( token, tok_len );
|
||||
TokEntry* value = tok_map.get( key );
|
||||
StrC* value = tok_map.get( key );
|
||||
|
||||
if ( value )
|
||||
{
|
||||
sw left = value->Length;
|
||||
char const* str = value->Str;
|
||||
sw left = value->Len;
|
||||
char const* str = value->Ptr;
|
||||
|
||||
while ( left-- )
|
||||
{
|
||||
@ -6295,7 +6284,7 @@ namespace gen
|
||||
|
||||
tok_map.clear();
|
||||
|
||||
sw result = buf_size - remaining + 1;
|
||||
sw result = buf_size - remaining;
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -6330,21 +6319,21 @@ namespace gen
|
||||
return result;
|
||||
}
|
||||
|
||||
Code untyped_token_fmt( char const* fmt, s32 num_tokens, ... )
|
||||
Code untyped_token_fmt( s32 num_tokens, ... )
|
||||
{
|
||||
local_persist thread_local
|
||||
char buf[ZPL_PRINTF_MAXLEN] = { 0 };
|
||||
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
sw length = token_fmt_va(buf, ZPL_PRINTF_MAXLEN, fmt, num_tokens, va);
|
||||
va_start(va, num_tokens);
|
||||
sw length = token_fmt_va(buf, ZPL_PRINTF_MAXLEN, num_tokens, va);
|
||||
va_end(va);
|
||||
|
||||
Code
|
||||
result = make_code();
|
||||
result->Name = get_cached_string( { str_len(fmt, MaxNameLength), fmt } );
|
||||
result->Name = get_cached_string( { length, buf } );
|
||||
result->Type = ECode::Untyped;
|
||||
result->Content = get_cached_string( { length, buf } );
|
||||
result->Content = result->Name;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ namespace gen
|
||||
{
|
||||
static
|
||||
StrC lookup[Num_Types] = {
|
||||
# define Entry( Type ) { txt_to_StrC( Type ) },
|
||||
# define Entry( Type ) { sizeof(stringize(Type)), stringize(Type) },
|
||||
Define_Types
|
||||
# undef Entry
|
||||
};
|
||||
@ -189,7 +189,7 @@ namespace gen
|
||||
{
|
||||
local_persist
|
||||
char const* lookup[ Num_Ops ] = {
|
||||
# define Entry( Type_, Token_ ) txt(Token_),
|
||||
# define Entry( Type_, Token_ ) stringize(Token_),
|
||||
Define_Operators
|
||||
# undef Entry
|
||||
","
|
||||
@ -252,7 +252,7 @@ namespace gen
|
||||
# define internal internal
|
||||
# define local_persist local_persist
|
||||
|
||||
# define Entry( Spec_, Code_ ) { txt_to_StrC(Code_) },
|
||||
# define Entry( Spec_, Code_ ) { sizeof(stringize(Code_)), stringize(Code_) },
|
||||
Define_Specifiers
|
||||
# undef Entry
|
||||
|
||||
@ -352,9 +352,9 @@ namespace gen
|
||||
# define GEN_API_Import_Code __declspec(dllimport)
|
||||
# define GEN_Attribute_Keyword __declspec
|
||||
|
||||
constexpr char const* API_Export = txt( GEN_API_Export_Code );
|
||||
constexpr char const* API_Import = txt( GEN_API_Import_Code );
|
||||
constexpr char const* Keyword = txt( GEN_Attribute_Keyword);
|
||||
constexpr char const* API_Export = stringize( GEN_API_Export_Code );
|
||||
constexpr char const* API_Import = stringize( GEN_API_Import_Code );
|
||||
constexpr char const* Keyword = stringize( GEN_Attribute_Keyword);
|
||||
|
||||
#elif ZPL_HAS_ATTRIBUTE( visibility ) || ZPL_GCC_VERSION_CHECK( 3, 3, 0 ) || ZPL_INTEL_VERSION_CHECK( 13, 0, 0 )
|
||||
# define GEN_API_Export_Code __attribute__ ((visibility ("default")))
|
||||
@ -501,7 +501,7 @@ namespace gen
|
||||
|
||||
char const* debug_str()
|
||||
{
|
||||
char const* fmt = txt(
|
||||
char const* fmt = stringize(
|
||||
\nCode Debug:
|
||||
\nType : %s
|
||||
\nParent : %s
|
||||
@ -773,26 +773,26 @@ namespace gen
|
||||
, ModuleFlag mflags = ModuleFlag::None );
|
||||
|
||||
Code def_class_body ( s32 num, ... );
|
||||
Code def_class_body ( s32 num, Code* codes );
|
||||
Code def_enum_body ( s32 num, ... );
|
||||
Code def_enum_body ( s32 num, Code* codes );
|
||||
Code def_export_body ( s32 num, ... );
|
||||
Code def_export_body ( s32 num, Code* codes);
|
||||
Code def_extern_link_body( s32 num, ... );
|
||||
Code def_extern_link_body( s32 num, Code* codes );
|
||||
Code def_function_body ( s32 num, ... );
|
||||
Code def_function_body ( s32 num, Code* codes );
|
||||
Code def_global_body ( s32 num, ... );
|
||||
Code def_global_body ( s32 num, Code* codes );
|
||||
Code def_namespace_body ( s32 num, ... );
|
||||
Code def_namespace_body ( s32 num, Code* codes );
|
||||
Code def_params ( s32 num, ... );
|
||||
Code def_params ( s32 num, Code* params );
|
||||
Code def_specifiers ( s32 num , ... );
|
||||
Code def_specifiers ( s32 num, SpecifierT* specs );
|
||||
Code def_specifiers ( s32 num, ... );
|
||||
Code def_struct_body ( s32 num, ... );
|
||||
Code def_struct_body ( s32 num, Code* codes );
|
||||
Code def_union_body ( s32 num, ... );
|
||||
Code def_class_body ( s32 num, Code* codes );
|
||||
Code def_enum_body ( s32 num, Code* codes );
|
||||
Code def_export_body ( s32 num, Code* codes);
|
||||
Code def_extern_link_body( s32 num, Code* codes );
|
||||
Code def_function_body ( s32 num, Code* codes );
|
||||
Code def_global_body ( s32 num, Code* codes );
|
||||
Code def_namespace_body ( s32 num, Code* codes );
|
||||
Code def_params ( s32 num, Code* params );
|
||||
Code def_specifiers ( s32 num, SpecifierT* specs );
|
||||
Code def_struct_body ( s32 num, Code* codes );
|
||||
Code def_union_body ( s32 num, Code* codes );
|
||||
# pragma endregion Upfront
|
||||
|
||||
@ -819,18 +819,20 @@ namespace gen
|
||||
# pragma endregion Parsing
|
||||
|
||||
# pragma region Untyped text
|
||||
sw token_fmt_va( char* buf, uw buf_size, char const* fmt, s32 num_tokens, va_list va );
|
||||
sw token_fmt_va( char* buf, uw buf_size, s32 num_tokens, va_list va );
|
||||
|
||||
//! Do not use directly. Use the token_fmt macro instead.
|
||||
// Takes a format string (char const*) and a list of tokens (StrC) and returns a StrC of the formatted string.
|
||||
inline
|
||||
StrC token_fmt( char const* fmt, sw num_tokens, ... )
|
||||
StrC _token_fmt( sw num, ... )
|
||||
{
|
||||
local_persist thread_local
|
||||
char buf[ZPL_PRINTF_MAXLEN] = { 0 };
|
||||
mem_set( buf, 0, ZPL_PRINTF_MAXLEN );
|
||||
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
sw result = token_fmt_va(buf, ZPL_PRINTF_MAXLEN, fmt, num_tokens, va);
|
||||
va_start(va, num );
|
||||
sw result = token_fmt_va(buf, ZPL_PRINTF_MAXLEN, num, va);
|
||||
va_end(va);
|
||||
|
||||
return { result, buf };
|
||||
@ -969,10 +971,15 @@ namespace gen
|
||||
|
||||
// Convienence for defining any name used with the gen api.
|
||||
// Lets you provide the length and string literal to the functions without the need for the DSL.
|
||||
# define name( Id_ ) { txt_to_StrC( Id_ ) }
|
||||
# define name( Id_ ) { sizeof(stringize( Id_ )) - 1, stringize(Id_) }
|
||||
|
||||
// Same as name just used to indicate intention of literal for code instead of names.
|
||||
# define code( ... ) { txt_to_StrC( __VA_ARGS__ ) }
|
||||
# define code( ... ) { sizeof(stringize(__VA_ARGS__)) - 1, stringize( __VA_ARGS__ ) }
|
||||
|
||||
# define args( ... ) macro_num_args( __VA_ARGS__ ), __VA_ARGS__
|
||||
|
||||
// Takes a format string (char const*) and a list of tokens (StrC) and returns a StrC of the formatted string.
|
||||
# define token_fmt( ... ) _token_fmt( (macro_num_args( __VA_ARGS__ ) + 1) / 2, __VA_ARGS__ )
|
||||
#pragma endregion Macros
|
||||
|
||||
#pragma region Constants
|
||||
|
@ -13,51 +13,45 @@ foreach ( $arg in $args )
|
||||
}
|
||||
}
|
||||
|
||||
$path_root = git rev-parse --show-toplevel
|
||||
$path_build = Join-Path $path_root build
|
||||
$path_scripts = Join-Path $path_root scripts
|
||||
$path_test = Join-Path $path_root test
|
||||
$path_gen = Join-Path $path_test gen
|
||||
$path_test_build = Join-Path $path_test build
|
||||
$path_gen_build = Join-Path $path_gen build
|
||||
|
||||
$path_root = git rev-parse --show-toplevel
|
||||
$path_build = Join-Path $path_root build
|
||||
$path_scripts = Join-Path $path_root scripts
|
||||
write-host "`n`nBuilding Test`n"
|
||||
|
||||
if ( -not( Test-Path $path_gen_build ) )
|
||||
{
|
||||
# Generate build files for meta-program
|
||||
Push-Location $path_gen
|
||||
$args_meson = @()
|
||||
$args_meson += "setup"
|
||||
$args_meson += $path_gen_build
|
||||
|
||||
# if ( $test -eq $true )
|
||||
# {
|
||||
#region Test Build
|
||||
write-host "`n`nBuilding Test`n"
|
||||
|
||||
$path_test = Join-Path $path_root test
|
||||
$path_gen = Join-Path $path_test gen
|
||||
$path_test_build = Join-Path $path_test build
|
||||
$path_gen_build = Join-Path $path_gen build
|
||||
|
||||
# Generate files using metaprogram.
|
||||
if ( -not( Test-Path $path_gen_build ) )
|
||||
{
|
||||
$args_meson = @()
|
||||
$args_meson += "setup"
|
||||
$args_meson += $path_gen_build
|
||||
|
||||
Push-Location $path_gen
|
||||
& meson $args_meson
|
||||
Pop-Location
|
||||
}
|
||||
& meson $args_meson
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
# Compile meta-program
|
||||
Push-Location $path_root
|
||||
$args_ninja = @()
|
||||
$args_ninja += "-C"
|
||||
$args_ninja += $path_gen_build
|
||||
|
||||
Push-Location $path_root
|
||||
& ninja $args_ninja
|
||||
Pop-Location
|
||||
Pop-Location
|
||||
|
||||
# Test NonParsed
|
||||
if ($true) {
|
||||
Push-location $path_gen
|
||||
# Run meta-program
|
||||
$gencpp = Join-Path $path_gen_build gencpp.exe
|
||||
|
||||
Push-location $path_gen
|
||||
|
||||
Write-Host `nGenerating files...
|
||||
Write-Host `nGenerating files -- Parsed...
|
||||
& $gencpp
|
||||
|
||||
# Format generated files
|
||||
Write-Host `nBeginning format...
|
||||
$formatParams = @(
|
||||
'-i' # In-place
|
||||
@ -72,60 +66,30 @@ $path_scripts = Join-Path $path_root scripts
|
||||
|
||||
clang-format $formatParams $targetFiles
|
||||
Write-Host "`nFormatting complete"
|
||||
Pop-Location
|
||||
}
|
||||
Pop-Location
|
||||
|
||||
# Test Parsed
|
||||
if ($true) {
|
||||
$gencpp = Join-Path $path_gen_build gencpp_parsed.exe
|
||||
# Build the program depending on generated files.
|
||||
if ( -not( Test-Path $path_test_build ) )
|
||||
{
|
||||
Push-Location $path_test
|
||||
$args_meson = @()
|
||||
$args_meson += "setup"
|
||||
$args_meson += $path_test_build
|
||||
|
||||
Push-location $path_gen
|
||||
# & meson $args_meson
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
Write-Host `nGenerating files -- using Parse API...
|
||||
& $gencpp
|
||||
Push-Location $path_root
|
||||
$args_ninja = @()
|
||||
$args_ninja += "-C"
|
||||
$args_ninja += $path_test_build
|
||||
|
||||
Write-Host `nBeginning format...
|
||||
$formatParams = @(
|
||||
'-i' # In-place
|
||||
'-style=file' # Search for a .clang-format file in the parent directory of the source file.
|
||||
'-verbose'
|
||||
)
|
||||
|
||||
$include = @('*.gen.hpp', '*.gen.cpp')
|
||||
$exclude = $null
|
||||
|
||||
$targetFiles = @(Get-ChildItem -Recurse -Path $path_gen -Include $include -Exclude $exclude | Select-Object -ExpandProperty FullName)
|
||||
|
||||
clang-format $formatParams $targetFiles
|
||||
Write-Host "`nFormatting complete"
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
|
||||
# Build the program depending on generated files.
|
||||
# if ( -not( Test-Path $path_test_build ) )k
|
||||
# {
|
||||
# $args_meson = @()
|
||||
# $args_meson += "setup"
|
||||
# $args_meson += $path_test_build
|
||||
|
||||
# Push-Location $path_test
|
||||
# & meson $args_meson
|
||||
# Pop-Location
|
||||
# }
|
||||
|
||||
# $args_ninja = @()
|
||||
# $args_ninja += "-C"
|
||||
# $args_ninja += $path_test_build
|
||||
|
||||
# Push-Location $path_root
|
||||
# ninja $args_ninja
|
||||
# Pop-Location
|
||||
Pop-Location
|
||||
|
||||
# $testcpp = Join-Path $path_test_build testcpp.exe
|
||||
Push-Location $path_test
|
||||
$testcpp = Join-Path $path_test_build testcpp.exe
|
||||
|
||||
# Push-Location $path_test
|
||||
# & $testcpp
|
||||
# Pop-Location
|
||||
# endregion Test Build
|
||||
# }
|
||||
Pop-Location
|
||||
|
@ -32,8 +32,8 @@ Code gen__array( StrC type )
|
||||
name = { name_len, name_str };
|
||||
};
|
||||
|
||||
Code array = parse_struct( token_fmt(
|
||||
txt(
|
||||
Code array = parse_struct( token_fmt( "ArrayType", name, "type", type,
|
||||
stringize(
|
||||
struct <ArrayType>
|
||||
{
|
||||
using Header = ArrayHeader;
|
||||
@ -208,11 +208,7 @@ Code gen__array( StrC type )
|
||||
return Data;
|
||||
}
|
||||
};
|
||||
),
|
||||
// Tokens
|
||||
2
|
||||
, "ArrayType", (char const*) name
|
||||
, "type", (char const*) type
|
||||
)
|
||||
));
|
||||
|
||||
return array;
|
||||
@ -226,7 +222,7 @@ struct GenArrayRequest
|
||||
};
|
||||
Array<GenArrayRequest> GenArrayRequests;
|
||||
|
||||
void gen__array_request( StrC type, sw size, StrC dep = {} )
|
||||
void gen__array_request( StrC type, StrC dep = {} )
|
||||
{
|
||||
do_once_start
|
||||
GenArrayRequests = Array<GenArrayRequest>::init( Memory::GlobalAllocator );
|
||||
@ -247,7 +243,7 @@ void gen__array_request( StrC type, sw size, StrC dep = {} )
|
||||
GenArrayRequest request = { dep, type };
|
||||
GenArrayRequests.append( request );
|
||||
}
|
||||
#define gen_array( type ) gen__array_request( { txt_to_StrC(type) }, sizeof(type) )
|
||||
#define gen_array( type ) gen__array_request( code(type) )
|
||||
|
||||
u32 gen_array_file()
|
||||
{
|
||||
@ -255,9 +251,11 @@ u32 gen_array_file()
|
||||
gen_array_file;
|
||||
gen_array_file.open( "array.Parsed.gen.hpp" );
|
||||
|
||||
Code include_zpl = def_include( StrC::from("Bloat.hpp") );
|
||||
Code include_zpl = def_include( txt_StrC("Bloat.hpp") );
|
||||
gen_array_file.print( include_zpl );
|
||||
|
||||
gen_array_file.print( def_using_namespace( name(gen)));
|
||||
|
||||
Code array_base = gen__array_base();
|
||||
gen_array_file.print( array_base );
|
||||
|
||||
|
@ -27,8 +27,8 @@ Code gen__buffer( StrC type )
|
||||
name = { name_len, name_str };
|
||||
};
|
||||
|
||||
Code buffer = parse_struct( token_fmt(
|
||||
txt(
|
||||
Code buffer = parse_struct( token_fmt( "BufferName", name, "type", type,
|
||||
stringize(
|
||||
struct <BufferName>
|
||||
{
|
||||
using Header = BufferHeader;
|
||||
@ -123,10 +123,7 @@ Code gen__buffer( StrC type )
|
||||
|
||||
Type* Data;
|
||||
};
|
||||
),
|
||||
2
|
||||
, "BufferName", (char const*) name
|
||||
, "type", (char const*) type
|
||||
)
|
||||
));
|
||||
|
||||
return buffer;
|
||||
@ -160,7 +157,7 @@ void gen__buffer_request( StrC type, StrC dep = {} )
|
||||
GenBufferRequest request = { dep, type };
|
||||
GenBufferRequests.append( request );
|
||||
}
|
||||
#define gen_buffer( type ) gen__buffer_request( { txt_to_StrC(type) } )
|
||||
#define gen_buffer( type ) gen__buffer_request( code(type) )
|
||||
|
||||
u32 gen_buffer_file()
|
||||
{
|
||||
@ -168,7 +165,9 @@ u32 gen_buffer_file()
|
||||
gen_buffer_file;
|
||||
gen_buffer_file.open( "buffer.Parsed.gen.hpp" );
|
||||
|
||||
gen_buffer_file.print( def_include( StrC::from("Bloat.hpp")) );
|
||||
gen_buffer_file.print( def_include( txt_StrC("Bloat.hpp")) );
|
||||
gen_buffer_file.print( def_using_namespace( name(gen)));
|
||||
|
||||
gen_buffer_file.print( gen__buffer_base() );
|
||||
|
||||
GenBufferRequest* current = GenBufferRequests;
|
||||
|
@ -18,7 +18,7 @@ Code gen__hashtable_base()
|
||||
));
|
||||
}
|
||||
|
||||
Code gen__hashtable( StrC type, sw type_size )
|
||||
Code gen__hashtable( StrC type )
|
||||
{
|
||||
StringCached name;
|
||||
{
|
||||
@ -28,26 +28,23 @@ Code gen__hashtable( StrC type, sw type_size )
|
||||
name = get_cached_string({ len, name_str });
|
||||
}
|
||||
|
||||
Code ht_entry = parse_struct( token_fmt(
|
||||
txt(
|
||||
Code ht_entry = parse_struct( token_fmt( "HashTableName", (StrC)name, "type", type,
|
||||
stringize(
|
||||
struct <HashTableName>_Entry
|
||||
{
|
||||
u64 Key;
|
||||
sw Next;
|
||||
<type> Value;
|
||||
};
|
||||
),
|
||||
2
|
||||
, "HashTableName", (char const*) name
|
||||
, "type", (char const*) type
|
||||
)
|
||||
));
|
||||
|
||||
StringCached ht_entry_name = get_cached_string( token_fmt( "<HashTableName>_Entry", 1, "HashTableName", name ) );
|
||||
StringCached ht_entry_name = get_cached_string( token_fmt( "HashTableName", (StrC)name, "<HashTableName>_Entry" ));
|
||||
|
||||
Code array_ht_entry = gen__array( ht_entry_name );
|
||||
|
||||
Code hashtable = parse_struct( token_fmt(
|
||||
txt(
|
||||
Code hashtable = parse_struct( token_fmt( "HashTableName", (StrC)name, "type", type,
|
||||
stringize(
|
||||
struct <HashTableName>
|
||||
{
|
||||
using Type = <type>;
|
||||
@ -275,10 +272,7 @@ Code gen__hashtable( StrC type, sw type_size )
|
||||
return 0.75f * Hashes.num() < Entries.num();
|
||||
}
|
||||
};
|
||||
),
|
||||
2
|
||||
, "HashTableName", (char const*) name
|
||||
, "type", (char const*) type
|
||||
)
|
||||
));
|
||||
|
||||
return def_global_body( 3, ht_entry, array_ht_entry, hashtable );
|
||||
@ -288,11 +282,10 @@ struct GenHashTableRequest
|
||||
{
|
||||
StrC Dependency;
|
||||
StrC Type;
|
||||
sw TypeSize;
|
||||
};
|
||||
Array<GenHashTableRequest> GenHashTableRequests;
|
||||
|
||||
void gen__hashtable_request( StrC type, sw size, StrC dep = {} )
|
||||
void gen__hashtable_request( StrC type, StrC dep = {} )
|
||||
{
|
||||
do_once_start
|
||||
GenHashTableRequests = Array<GenHashTableRequest>::init( Memory::GlobalAllocator );
|
||||
@ -312,21 +305,24 @@ void gen__hashtable_request( StrC type, sw size, StrC dep = {} )
|
||||
return;
|
||||
}
|
||||
|
||||
GenHashTableRequest request = { dep, type, size};
|
||||
GenHashTableRequest request = { dep, type };
|
||||
GenHashTableRequests.append( request );
|
||||
}
|
||||
#define gen_hashtable( type ) gen__hashtable_request( { txt_to_StrC(type) }, sizeof( type ))
|
||||
#define gen_hashtable( type ) gen__hashtable_request( code(type) )
|
||||
|
||||
u32 gen_hashtable_file()
|
||||
{
|
||||
Builder
|
||||
gen_buffer_file;
|
||||
gen_buffer_file.open( "hashtable.Parsed.gen.hpp" );
|
||||
gen_hashtable_file;
|
||||
gen_hashtable_file.open( "hashtable.Parsed.gen.hpp" );
|
||||
|
||||
gen_buffer_file.print( def_include( StrC::from("Bloat.hpp")) );
|
||||
gen_buffer_file.print( def_include( StrC::from("Array.Parsed.hpp")) );
|
||||
gen_buffer_file.print( def_include( StrC::from("array.Parsed.gen.hpp")) );
|
||||
gen_buffer_file.print( gen__hashtable_base());
|
||||
gen_hashtable_file.print( def_include( txt_StrC("Bloat.hpp")) );
|
||||
gen_hashtable_file.print( def_include( txt_StrC("Array.Parsed.hpp")) );
|
||||
gen_hashtable_file.print( def_include( txt_StrC("array.Parsed.gen.hpp")) );
|
||||
|
||||
gen_hashtable_file.print( def_using_namespace( name(gen)));
|
||||
|
||||
gen_hashtable_file.print( gen__hashtable_base());
|
||||
|
||||
GenHashTableRequest* current = GenHashTableRequests;
|
||||
s32 left = GenHashTableRequests.num();
|
||||
@ -334,7 +330,7 @@ u32 gen_hashtable_file()
|
||||
{
|
||||
GenHashTableRequest const& request = * current;
|
||||
|
||||
Code generated_buffer = gen__hashtable( current->Type, current->TypeSize );
|
||||
Code generated_buffer = gen__hashtable( current->Type );
|
||||
|
||||
if ( request.Dependency )
|
||||
{
|
||||
@ -344,15 +340,15 @@ u32 gen_hashtable_file()
|
||||
Code cmt = def_comment( { cmt_len, cmt_str } );
|
||||
Code include = def_include( request.Dependency );
|
||||
|
||||
gen_buffer_file.print( cmt );
|
||||
gen_buffer_file.print( include );
|
||||
gen_hashtable_file.print( cmt );
|
||||
gen_hashtable_file.print( include );
|
||||
}
|
||||
|
||||
gen_buffer_file.print( generated_buffer );
|
||||
gen_hashtable_file.print( generated_buffer );
|
||||
current++;
|
||||
}
|
||||
|
||||
gen_buffer_file.write();
|
||||
gen_hashtable_file.write();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ Code gen__ring( StrC type )
|
||||
{
|
||||
static Code t_allocator_info = def_type( name(AllocatorInfo) );
|
||||
|
||||
String name;
|
||||
StringCached name;
|
||||
{
|
||||
char const* name_str = str_fmt_buf( "Ring_%s\0", type.Ptr );
|
||||
s32 name_len = str_len( name_str );
|
||||
@ -18,8 +18,10 @@ Code gen__ring( StrC type )
|
||||
name = get_cached_string({ name_len, name_str });
|
||||
};
|
||||
|
||||
Code ring = parse_struct( token_fmt(
|
||||
txt(
|
||||
StrC buffer_name = to_StrC( str_fmt_buf( "Buffer_%s", type.Ptr ));
|
||||
|
||||
Code ring = parse_struct( token_fmt( "RingName", (StrC)name, "type", type, "BufferName", buffer_name,
|
||||
stringize(
|
||||
struct <RingName>
|
||||
{
|
||||
using Type = <type>;
|
||||
@ -87,11 +89,7 @@ Code gen__ring( StrC type )
|
||||
uw Tail;
|
||||
<BufferName> Buffer;
|
||||
};
|
||||
),
|
||||
3
|
||||
, "RingName", (char const*) name
|
||||
, "type", (char const*) type
|
||||
, "BufferName", str_fmt_buf( "Buffer_%s", type.Ptr )
|
||||
)
|
||||
));
|
||||
|
||||
return ring;
|
||||
@ -104,7 +102,7 @@ struct GenRingRequest
|
||||
};
|
||||
Array<GenRingRequest> GenRingRequests;
|
||||
|
||||
void gen__ring_request( StrC type, sw size, StrC dep = {} )
|
||||
void gen__ring_request( StrC type, StrC dep = {} )
|
||||
{
|
||||
do_once_start
|
||||
GenRingRequests = Array<GenRingRequest>::init( Memory::GlobalAllocator );
|
||||
@ -128,7 +126,7 @@ void gen__ring_request( StrC type, sw size, StrC dep = {} )
|
||||
GenRingRequest request = { dep, type };
|
||||
GenRingRequests.append( request );
|
||||
}
|
||||
#define gen_ring( type ) gen__ring_request( { txt_to_StrC(type) }, sizeof( type ))
|
||||
#define gen_ring( type ) gen__ring_request( code(type) )
|
||||
|
||||
u32 gen_ring_file()
|
||||
{
|
||||
@ -136,10 +134,12 @@ u32 gen_ring_file()
|
||||
gen_ring_file;
|
||||
gen_ring_file.open( "ring.Parsed.gen.hpp" );
|
||||
|
||||
gen_ring_file.print( def_include( StrC::from("Bloat.hpp")) );
|
||||
gen_ring_file.print( def_include( StrC::from("buffer.Parsed.gen.hpp")) );
|
||||
gen_ring_file.print( def_include( txt_StrC("Bloat.hpp")) );
|
||||
gen_ring_file.print( def_include( txt_StrC("buffer.Parsed.gen.hpp")) );
|
||||
// gen_ring_file.print( gen__ring_base() );
|
||||
|
||||
gen_ring_file.print( def_using_namespace( name(gen)));
|
||||
|
||||
GenRingRequest* current = GenRingRequests;
|
||||
s32 left = GenRingRequests.num();
|
||||
while (left--)
|
||||
|
@ -10,7 +10,7 @@ u32 gen_sanity()
|
||||
gen_sanity_file;
|
||||
gen_sanity_file.open("./sanity.Parsed.gen.hpp");
|
||||
|
||||
gen_sanity_file.print( def_comment( StrC::from(
|
||||
gen_sanity_file.print( def_comment( txt_StrC(
|
||||
"The following will show a series of base cases for the gen parsed api.\n"
|
||||
)));
|
||||
|
||||
@ -36,7 +36,7 @@ u32 gen_sanity()
|
||||
{};
|
||||
));
|
||||
|
||||
empty_body.body()->add_entry( def_comment( StrC::from("Empty class body") ) );
|
||||
empty_body.body()->add_entry( def_comment( txt_StrC("Empty class body") ) );
|
||||
|
||||
gen_sanity_file.print(fwd);
|
||||
gen_sanity_file.print(empty_body);
|
||||
@ -72,7 +72,7 @@ u32 gen_sanity()
|
||||
|
||||
// External Linkage
|
||||
{
|
||||
Code empty_comment = def_comment( StrC::from("Empty external linkage") );
|
||||
Code empty_comment = def_comment( txt_StrC("Empty external linkage") );
|
||||
|
||||
Code c_extern = parse_extern_link( code(
|
||||
extern "C"
|
||||
@ -118,7 +118,7 @@ u32 gen_sanity()
|
||||
}
|
||||
));
|
||||
|
||||
def.body()->add_entry( def_comment( StrC::from("Empty function body") ) );
|
||||
def.body()->add_entry( def_comment( txt_StrC("Empty function body") ) );
|
||||
|
||||
gen_sanity_file.print(fwd);
|
||||
gen_sanity_file.print(def);
|
||||
@ -134,7 +134,7 @@ u32 gen_sanity()
|
||||
}
|
||||
));
|
||||
|
||||
def.body()->add_entry( def_comment( StrC::from("Empty namespace body") ) );
|
||||
def.body()->add_entry( def_comment( txt_StrC("Empty namespace body") ) );
|
||||
|
||||
gen_sanity_file.print(def);
|
||||
}
|
||||
@ -201,7 +201,7 @@ u32 gen_sanity()
|
||||
}
|
||||
));
|
||||
|
||||
def.body()->add_entry( def_comment( StrC::from("Empty function body") ) );
|
||||
def.body()->add_entry( def_comment( txt_StrC("Empty function body") ) );
|
||||
|
||||
gen_sanity_file.print(fwd);
|
||||
gen_sanity_file.print(def);
|
||||
@ -237,7 +237,7 @@ u32 gen_sanity()
|
||||
{};
|
||||
));
|
||||
|
||||
empty_body.body()->add_entry( def_comment( StrC::from("Empty struct body") ) );
|
||||
empty_body.body()->add_entry( def_comment( txt_StrC("Empty struct body") ) );
|
||||
|
||||
gen_sanity_file.print(fwd);
|
||||
gen_sanity_file.print(empty_body);
|
||||
@ -253,7 +253,7 @@ u32 gen_sanity()
|
||||
};
|
||||
));
|
||||
|
||||
empty.body()->add_entry( def_comment( StrC::from("Empty union body") ) );
|
||||
empty.body()->add_entry( def_comment( txt_StrC("Empty union body") ) );
|
||||
|
||||
gen_sanity_file.print( parse_typedef( code( typedef unsigned short u16; )) );
|
||||
gen_sanity_file.print( parse_typedef( code( typedef unsigned long u32; )) );
|
||||
@ -330,7 +330,7 @@ u32 gen_sanity()
|
||||
|
||||
gen_sanity_file.print_fmt("\n");
|
||||
|
||||
gen_sanity_file.print( def_comment( StrC::from(
|
||||
gen_sanity_file.print( def_comment( txt_StrC(
|
||||
"End of base case tests\n"
|
||||
)));
|
||||
|
||||
|
@ -8,7 +8,4 @@ be better on in c++ as templates, since the templates they generate are trivial
|
||||
An exmaple of a non-trival generation is a container for elements with SOA or AOS policy for layout.
|
||||
(If a unified element syntax is desired)
|
||||
|
||||
The test is divided between two major sets of tests: Parsed and Nonparsed.
|
||||
|
||||
Parsed uses the parsing api strictly.
|
||||
NonParsed only uses the upfront and incremental constructors.
|
||||
The test is divided between two major sets of tests: Parsed and Upfront.
|
||||
|
40
test/SOA.hpp
40
test/SOA.hpp
@ -30,17 +30,15 @@ Code gen_SOA( Code struct_def, bool use_dynamic = false )
|
||||
Code entry_arr = { nullptr };
|
||||
if ( use_dynamic)
|
||||
{
|
||||
entry_arr = parse_variable( token_fmt( "Array<<type>> <name>;", 2
|
||||
, "type", (char const*)var_type->Name
|
||||
, "name", (char const*)struct_mem->Name )
|
||||
);
|
||||
entry_arr = parse_variable( token_fmt( "type", (StrC)var_type->Name, "name", (StrC)struct_mem->Name,
|
||||
stringize( Array<<type>> <name>; )
|
||||
));
|
||||
}
|
||||
else
|
||||
{
|
||||
entry_arr = parse_variable( token_fmt( "<type> <name>[100];", 2
|
||||
, "type", (char const*)var_type->Name
|
||||
, "name", (char const*)struct_mem->Name )
|
||||
);
|
||||
entry_arr = parse_variable( token_fmt( "type", (StrC)var_type->Name, "name", (StrC)struct_mem->Name,
|
||||
stringize( <type> <name>[100]; )
|
||||
));
|
||||
}
|
||||
|
||||
vars.append( entry_arr );
|
||||
@ -51,15 +49,14 @@ Code gen_SOA( Code struct_def, bool use_dynamic = false )
|
||||
|
||||
Code make;
|
||||
{
|
||||
make = parse_function( token_fmt(
|
||||
txt(
|
||||
static
|
||||
<SOA_Type> make( AllocatorInfo allocator )
|
||||
{
|
||||
<SOA_Type> soa = {};
|
||||
}
|
||||
),
|
||||
1, "SOA_Type", (char const*)name
|
||||
make = parse_function( token_fmt("SOA_Type", name,
|
||||
stringize(
|
||||
static
|
||||
<SOA_Type> make( AllocatorInfo allocator )
|
||||
{
|
||||
<SOA_Type> soa = {};
|
||||
}
|
||||
)
|
||||
));
|
||||
|
||||
if ( use_dynamic )
|
||||
@ -68,9 +65,8 @@ Code gen_SOA( Code struct_def, bool use_dynamic = false )
|
||||
{
|
||||
Code member = vars[idx];
|
||||
|
||||
Code arr_init = def_execution( token_fmt( "soa.<var_name> = <var_type>::init( allocator );", 2
|
||||
, "var_name", (char const*)member->Name
|
||||
, "var_type", (char const*)member->entry(0)->Name
|
||||
Code arr_init = def_execution( token_fmt( "var_name", (StrC)member->Name, "var_type", (StrC)member->entry(0)->Name,
|
||||
stringize( soa.<var_name> = <var_type>::init( allocator ); )
|
||||
));
|
||||
|
||||
make.body()->add_entry( arr_init );
|
||||
@ -94,8 +90,8 @@ Code gen_SOA( Code struct_def, bool use_dynamic = false )
|
||||
{
|
||||
Code member = vars[idx];
|
||||
|
||||
content.append_fmt( token_fmt( "<var_name>[idx],", 1
|
||||
, "var_name", (char const*)member->Name
|
||||
content.append_fmt( token_fmt( "var_name", (StrC)member->Name,
|
||||
"<var_name>[idx],"
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -94,16 +94,18 @@ Code gen__array( StrC type )
|
||||
|
||||
Code append = def_function( name(append), def_param(t_alias, name(value)), t_bool
|
||||
, def_execution( code(
|
||||
Header& header = get_header();
|
||||
Header* header = get_header();
|
||||
|
||||
if ( header.Num == header.Capacity )
|
||||
if ( header->Num == header->Capacity )
|
||||
{
|
||||
if ( ! grow( header.Capacity ))
|
||||
if ( ! grow( header->Capacity ))
|
||||
return false;
|
||||
|
||||
header = get_header();
|
||||
}
|
||||
|
||||
Data[ header.Num ] = value;
|
||||
header.Num++;
|
||||
Data[ header->Num ] = value;
|
||||
header->Num++;
|
||||
|
||||
return true;
|
||||
))
|
||||
@ -111,14 +113,14 @@ Code gen__array( StrC type )
|
||||
|
||||
Code back = def_function( name(back), __, t_alias_ref
|
||||
, def_execution( code(
|
||||
Header& header = get_header();
|
||||
Header& header = * get_header();
|
||||
return Data[ header.Num - 1 ];
|
||||
))
|
||||
);
|
||||
|
||||
Code clear = def_function( name(clear), __, t_void
|
||||
, def_execution( code(
|
||||
Header& header = get_header();
|
||||
Header& header = * get_header();
|
||||
header.Num = 0;
|
||||
))
|
||||
);
|
||||
@ -132,7 +134,7 @@ Code gen__array( StrC type )
|
||||
);
|
||||
|
||||
Code body = untyped_str( code(
|
||||
Header& header = get_header();
|
||||
Header& header = * get_header();
|
||||
|
||||
if ( begin < 0 || end >= header.Num )
|
||||
return false;
|
||||
@ -150,20 +152,20 @@ Code gen__array( StrC type )
|
||||
|
||||
Code free = def_function( name(free), __, t_void
|
||||
, def_execution( code(
|
||||
Header& header = get_header();
|
||||
zpl::free( header.Allocator, & header );
|
||||
Header* header = get_header();
|
||||
gen::free( header->Allocator, header );
|
||||
))
|
||||
);
|
||||
|
||||
Code get_header = def_function( name(get_header), __, t_header_ref
|
||||
Code get_header = def_function( name(get_header), __, t_header_ptr
|
||||
, def_execution( code(
|
||||
return * ( rcast( Header*, Data ) - 1 );
|
||||
return rcast( Header*, Data ) - 1;
|
||||
))
|
||||
);
|
||||
|
||||
Code grow = def_function( name(grow), def_param( t_uw, name(min_capacity)), t_bool
|
||||
, def_execution( code(
|
||||
Header& header = get_header();
|
||||
Header& header = * get_header();
|
||||
|
||||
uw new_capacity = grow_formula( header.Capacity );
|
||||
|
||||
@ -176,13 +178,13 @@ Code gen__array( StrC type )
|
||||
|
||||
Code num = def_function( name(num), __, t_uw
|
||||
, def_execution( code(
|
||||
return get_header().Num;
|
||||
return get_header()->Num;
|
||||
))
|
||||
);
|
||||
|
||||
Code pop = def_function( name(pop), __, t_bool
|
||||
, def_execution( code(
|
||||
Header& header = get_header();
|
||||
Header& header = * get_header();
|
||||
|
||||
ZPL_ASSERT( header.Num > 0 );
|
||||
header.Num--;
|
||||
@ -191,7 +193,7 @@ Code gen__array( StrC type )
|
||||
|
||||
Code remove_at = def_function( name(remove_at), def_param( t_uw, name(idx)), t_void
|
||||
, def_execution( code(
|
||||
Header* header = & get_header();
|
||||
Header* header = get_header();
|
||||
ZPL_ASSERT( idx < header->Num );
|
||||
|
||||
mem_move( header + idx, header + idx + 1, sizeof( Type ) * ( header->Num - idx - 1 ) );
|
||||
@ -201,7 +203,7 @@ Code gen__array( StrC type )
|
||||
|
||||
Code reserve = def_function( name(reserve), def_param( t_uw, name(new_capacity)), t_bool
|
||||
, def_execution( code(
|
||||
Header& header = get_header();
|
||||
Header& header = * get_header();
|
||||
|
||||
if ( header.Capacity < new_capacity )
|
||||
return set_capacity( new_capacity );
|
||||
@ -212,15 +214,17 @@ Code gen__array( StrC type )
|
||||
|
||||
Code resize = def_function( name(resize), def_param( t_uw, name(num)), t_bool
|
||||
, def_execution( code(
|
||||
Header& header = get_header();
|
||||
Header* header = get_header();
|
||||
|
||||
if ( num > header.Capacity )
|
||||
if ( num > header->Capacity )
|
||||
{
|
||||
if ( ! grow( header.Capacity ))
|
||||
if ( ! grow( header->Capacity ))
|
||||
return false;
|
||||
|
||||
header = get_header();
|
||||
}
|
||||
|
||||
header.Num = num;
|
||||
header->Num = num;
|
||||
return true;
|
||||
))
|
||||
);
|
||||
@ -228,7 +232,7 @@ Code gen__array( StrC type )
|
||||
Code set_capacity;
|
||||
{
|
||||
Code body = def_execution( code(
|
||||
Header& header = get_header();
|
||||
Header& header = * get_header();
|
||||
|
||||
if ( new_capacity == header.Capacity )
|
||||
return true;
|
||||
@ -244,13 +248,11 @@ Code gen__array( StrC type )
|
||||
|
||||
mem_move( new_header, & header, sizeof( Header ) + sizeof(Type) * header.Num );
|
||||
|
||||
new_header->Allocator = header.Allocator;
|
||||
new_header->Num = header.Num;
|
||||
new_header->Capacity = new_capacity;
|
||||
new_header->Capacity = new_capacity;
|
||||
|
||||
zpl::free( header.Allocator, & header );
|
||||
gen::free( header.Allocator, & header );
|
||||
|
||||
Data = (Type*) new_header + 1;
|
||||
Data = rcast( Type*, new_header + 1);
|
||||
|
||||
return true;
|
||||
));
|
||||
@ -323,17 +325,19 @@ void gen__array_request( StrC type, StrC dep = {} )
|
||||
GenArrayRequest request = { dep, type };
|
||||
GenArrayRequests.append( request );
|
||||
}
|
||||
#define gen_array( type ) gen__array_request( { txt_to_StrC(type) } )
|
||||
#define gen_array( type ) gen__array_request( code(type) )
|
||||
|
||||
u32 gen_array_file()
|
||||
{
|
||||
Builder
|
||||
gen_array_file;
|
||||
gen_array_file.open( "array.NonParsed.gen.hpp" );
|
||||
gen_array_file.open( "array.Upfront.gen.hpp" );
|
||||
|
||||
Code include_zpl = def_include( StrC::from("Bloat.hpp") );
|
||||
Code include_zpl = def_include( txt_StrC("Bloat.hpp") );
|
||||
gen_array_file.print( include_zpl );
|
||||
|
||||
gen_array_file.print( def_using_namespace( name(gen)));
|
||||
|
||||
Code array_base = gen__array_base();
|
||||
gen_array_file.print( array_base );
|
||||
|
@ -208,7 +208,7 @@ struct GenBufferRequest
|
||||
};
|
||||
Array<GenBufferRequest> GenBufferRequests;
|
||||
|
||||
void gen__buffer_request( StrC type, sw size, StrC dep = {} )
|
||||
void gen__buffer_request( StrC type, StrC dep = {} )
|
||||
{
|
||||
do_once_start
|
||||
GenBufferRequests = Array<GenBufferRequest>::init( Memory::GlobalAllocator );
|
||||
@ -226,18 +226,20 @@ void gen__buffer_request( StrC type, sw size, StrC dep = {} )
|
||||
return;
|
||||
}
|
||||
|
||||
GenBufferRequest request = { dep, type, size};
|
||||
GenBufferRequest request = { dep, type};
|
||||
GenBufferRequests.append( request );
|
||||
}
|
||||
#define gen_buffer( type ) gen__buffer_request( { txt_to_StrC(type) }, sizeof( type ))
|
||||
#define gen_buffer( type ) gen__buffer_request( code(type))
|
||||
|
||||
u32 gen_buffer_file()
|
||||
{
|
||||
Builder
|
||||
gen_buffer_file;
|
||||
gen_buffer_file.open( "buffer.NonParsed.gen.hpp" );
|
||||
gen_buffer_file.open( "buffer.Upfront.gen.hpp" );
|
||||
|
||||
gen_buffer_file.print( def_include( txt_StrC("Bloat.hpp")) );
|
||||
gen_buffer_file.print( def_using_namespace( name(gen)) );
|
||||
|
||||
gen_buffer_file.print( def_include( StrC::from("Bloat.hpp")) );
|
||||
gen_buffer_file.print( gen__buffer_base() );
|
||||
|
||||
GenBufferRequest* current = GenBufferRequests;
|
@ -2,7 +2,7 @@
|
||||
|
||||
#if gen_time
|
||||
#include "gen.hpp"
|
||||
#include "Array.NonParsed.hpp"
|
||||
#include "Array.Upfront.hpp"
|
||||
|
||||
using namespace gen;
|
||||
|
||||
@ -74,7 +74,7 @@ Code gen__hashtable( StrC type )
|
||||
|
||||
Code init;
|
||||
{
|
||||
char const* tmpl = txt(
|
||||
char const* tmpl = stringize(
|
||||
<type> result = { 0 };
|
||||
|
||||
result.Hashes = Array_sw ::init( allocator );
|
||||
@ -82,11 +82,31 @@ Code gen__hashtable( StrC type )
|
||||
|
||||
return result;
|
||||
);
|
||||
Code body = def_execution( token_fmt( tmpl, 1, "type", name ) );
|
||||
Code body = def_execution( token_fmt( "type", (StrC)name, tmpl ) );
|
||||
|
||||
init = def_function( name(init), def_param( t_allocator_info, name(allocator)), t_ht_type, body, spec_static_member );
|
||||
}
|
||||
|
||||
|
||||
Code init_reserve;
|
||||
{
|
||||
char const* tmpl = stringize(
|
||||
<type> result = { { nullptr }, { nullptr } };
|
||||
|
||||
result.Hashes = Array_sw::init_reserve( allocator, num );
|
||||
result.Hashes.get_header()->Num = num;
|
||||
|
||||
result.Entries = Array_Entry::init_reserve( allocator, num );
|
||||
|
||||
return result;
|
||||
);
|
||||
Code body = def_execution( token_fmt( "type", (StrC)name, tmpl ) );
|
||||
|
||||
Code params = def_params( 2, def_param( t_allocator_info, name(allocator)), def_param( t_sw, name(num)));
|
||||
|
||||
init_reserve = def_function( name(init_reserve), params, t_ht_type, body, spec_static_member );
|
||||
}
|
||||
|
||||
Code clear = def_function( name(clear), __, t_void
|
||||
, def_execution( code(
|
||||
for ( s32 idx = 0; idx < Hashes.num(); idx++ )
|
||||
@ -98,9 +118,9 @@ Code gen__hashtable( StrC type )
|
||||
|
||||
Code destroy = def_function( name(destroy), __, t_void
|
||||
, def_execution( code(
|
||||
if ( Hashes )
|
||||
if ( Hashes && Hashes.get_header()->Capacity )
|
||||
Hashes.free();
|
||||
if ( Entries )
|
||||
if ( Entries && Hashes.get_header()->Capacity )
|
||||
Entries.free();
|
||||
))
|
||||
);
|
||||
@ -108,7 +128,7 @@ Code gen__hashtable( StrC type )
|
||||
Code get = def_function( name(get), def_param( t_u64, name(key)), t_type_ptr
|
||||
, def_execution( code(
|
||||
sw idx = find( key ).EntryIndex;
|
||||
if ( idx > 0 )
|
||||
if ( idx >= 0 )
|
||||
return & Entries[ idx ].Value;
|
||||
|
||||
return nullptr;
|
||||
@ -117,10 +137,10 @@ Code gen__hashtable( StrC type )
|
||||
|
||||
Code using_map_proc;
|
||||
{
|
||||
char const* tmpl = txt(
|
||||
char const* tmpl = stringize(
|
||||
void (*) ( u64 key, <type> value )
|
||||
);
|
||||
Code value = untyped_str( token_fmt( tmpl, 1, "type", t_type.to_string() ) );
|
||||
Code value = untyped_str( token_fmt( "type", (StrC)t_type.to_string(), tmpl ) );
|
||||
|
||||
using_map_proc = def_using ( name(MapProc), value);
|
||||
}
|
||||
@ -143,10 +163,10 @@ Code gen__hashtable( StrC type )
|
||||
|
||||
Code using_map_mut_proc;
|
||||
{
|
||||
char const* tmpl = txt(
|
||||
char const* tmpl = stringize(
|
||||
void (*) ( u64 key, <type> value )
|
||||
);
|
||||
Code value = untyped_str( token_fmt( tmpl, 1, "type", t_type_ptr.to_string() ) );
|
||||
Code value = untyped_str( token_fmt( "type", (StrC)t_type_ptr.to_string(), tmpl ) );
|
||||
|
||||
using_map_mut_proc = def_using ( name(MapMutProc), value);
|
||||
}
|
||||
@ -176,14 +196,13 @@ Code gen__hashtable( StrC type )
|
||||
|
||||
Code rehash;
|
||||
{
|
||||
char const* tmpl = txt(
|
||||
char const* tmpl = stringize(
|
||||
sw idx;
|
||||
sw last_added_index;
|
||||
|
||||
<type> new_ht = <type>::init( Hashes.get_header().Allocator );
|
||||
<type> new_ht = init_reserve( Hashes.get_header()->Allocator, new_num );
|
||||
|
||||
new_ht.Hashes.resize( new_num );
|
||||
new_ht.Entries.reserve( new_ht.Hashes.num() );
|
||||
Array_sw::Header* hash_header = new_ht.Hashes.get_header();
|
||||
|
||||
for ( idx = 0; idx < new_ht.Hashes.num(); ++idx )
|
||||
new_ht.Hashes[ idx ] = -1;
|
||||
@ -211,22 +230,17 @@ Code gen__hashtable( StrC type )
|
||||
new_ht.Entries[ last_added_index ].Value = entry.Value;
|
||||
}
|
||||
|
||||
// *this = new_ht;
|
||||
|
||||
// old_ht.destroy();
|
||||
|
||||
destroy();
|
||||
Hashes = new_ht.Hashes;
|
||||
Entries = new_ht.Entries;
|
||||
*this = new_ht;
|
||||
);
|
||||
Code body = def_execution( token_fmt( tmpl, 1, "type", name ) );
|
||||
Code body = def_execution( token_fmt( "type", (StrC)name, tmpl ) );
|
||||
|
||||
rehash = def_function( name(rehash), def_param( t_sw, name(new_num)), t_void, body );
|
||||
}
|
||||
|
||||
Code rehash_fast;
|
||||
{
|
||||
char const* tmpl = txt(
|
||||
char const* tmpl = stringize(
|
||||
sw idx;
|
||||
|
||||
for ( idx = 0; idx < Entries.num(); idx++ )
|
||||
@ -242,7 +256,7 @@ Code gen__hashtable( StrC type )
|
||||
FindResult find_result;
|
||||
}
|
||||
);
|
||||
Code body = def_execution( token_fmt( tmpl, 1, "type", name ) );
|
||||
Code body = def_execution( token_fmt( "type", name, tmpl ) );
|
||||
|
||||
rehash_fast = def_function( name(rehash_fast), __, t_void, body );
|
||||
}
|
||||
@ -358,7 +372,7 @@ Code gen__hashtable( StrC type )
|
||||
))
|
||||
);
|
||||
|
||||
hashtable = def_struct( name, def_struct_body( 24
|
||||
hashtable = def_struct( name, def_struct_body( 25
|
||||
, using_entry
|
||||
, using_array_entry
|
||||
, using_find_result
|
||||
@ -366,6 +380,7 @@ Code gen__hashtable( StrC type )
|
||||
, using_map_mut_proc
|
||||
|
||||
, init
|
||||
, init_reserve
|
||||
|
||||
, clear
|
||||
, destroy
|
||||
@ -423,19 +438,21 @@ void gen__hashtable_request( StrC type, StrC dep = {} )
|
||||
GenHashTableRequest request = { dep, type };
|
||||
GenHashTableRequests.append( request );
|
||||
}
|
||||
#define gen_hashtable( type ) gen__hashtable_request( { txt_to_StrC(type) } )
|
||||
#define gen_hashtable( type ) gen__hashtable_request( code(type))
|
||||
|
||||
u32 gen_hashtable_file()
|
||||
{
|
||||
Builder
|
||||
gen_buffer_file;
|
||||
gen_buffer_file.open( "hashtable.NonParsed.gen.hpp" );
|
||||
gen_hashtable_file;
|
||||
gen_hashtable_file.open( "hashtable.Upfront.gen.hpp" );
|
||||
|
||||
gen_buffer_file.print( def_include( StrC::from("Bloat.hpp")) );
|
||||
gen_buffer_file.print( def_include( StrC::from("Array.NonParsed.hpp")) );
|
||||
gen_buffer_file.print( def_include( StrC::from("array.NonParsed.gen.hpp")) );
|
||||
gen_hashtable_file.print( def_include( txt_StrC("Bloat.hpp")) );
|
||||
gen_hashtable_file.print( def_include( txt_StrC("Array.Upfront.hpp")) );
|
||||
gen_hashtable_file.print( def_include( txt_StrC("array.Upfront.gen.hpp")) );
|
||||
|
||||
gen_buffer_file.print( gen__hashtable_base());
|
||||
gen_hashtable_file.print( def_using_namespace( name(gen)));
|
||||
|
||||
gen_hashtable_file.print( gen__hashtable_base());
|
||||
|
||||
GenHashTableRequest* current = GenHashTableRequests;
|
||||
s32 left = GenHashTableRequests.num();
|
||||
@ -453,15 +470,15 @@ u32 gen_hashtable_file()
|
||||
Code cmt = def_comment( { cmt_len, cmt_str } );
|
||||
Code include = def_include( request.Dependency );
|
||||
|
||||
gen_buffer_file.print( cmt );
|
||||
gen_buffer_file.print( include );
|
||||
gen_hashtable_file.print( cmt );
|
||||
gen_hashtable_file.print( include );
|
||||
}
|
||||
|
||||
gen_buffer_file.print( generated_buffer );
|
||||
gen_hashtable_file.print( generated_buffer );
|
||||
current++;
|
||||
}
|
||||
|
||||
gen_buffer_file.write();
|
||||
gen_hashtable_file.write();
|
||||
return 0;
|
||||
}
|
||||
|
@ -2,11 +2,11 @@
|
||||
|
||||
#if gen_time
|
||||
#include "gen.hpp"
|
||||
#include "Buffer.NonParsed.hpp"
|
||||
#include "Buffer.Upfront.hpp"
|
||||
|
||||
using namespace gen;
|
||||
|
||||
Code gen__ring( StrC type, sw type_size )
|
||||
Code gen__ring( StrC type )
|
||||
{
|
||||
static Code t_allocator_info = def_type( name(AllocatorInfo) );
|
||||
|
||||
@ -50,7 +50,7 @@ Code gen__ring( StrC type, sw type_size )
|
||||
, def_param( t_uw, name(max_size) )
|
||||
);
|
||||
|
||||
char const* tmpl = txt(
|
||||
char const* tmpl = stringize(
|
||||
<type> result = { 0 };
|
||||
|
||||
result.Backing = allocator;
|
||||
@ -64,10 +64,7 @@ Code gen__ring( StrC type, sw type_size )
|
||||
|
||||
return result;
|
||||
);
|
||||
Code body = def_execution( token_fmt( tmpl, 2
|
||||
, "type", (char const*)name
|
||||
, "data_type", (char const*)type
|
||||
));
|
||||
Code body = def_execution( token_fmt( "type", (StrC)name, "data_type", type, tmpl ));
|
||||
|
||||
init = def_function( name(init), params, t_ring_type, body, spec_static_member );
|
||||
}
|
||||
@ -160,11 +157,10 @@ struct GenRingRequest
|
||||
{
|
||||
StrC Dependency;
|
||||
StrC Type;
|
||||
sw TypeSize;
|
||||
};
|
||||
Array<GenRingRequest> GenRingRequests;
|
||||
|
||||
void gen__ring_request( StrC type, sw size, StrC dep = {} )
|
||||
void gen__ring_request( StrC type, StrC dep = {} )
|
||||
{
|
||||
do_once_start
|
||||
GenRingRequests = Array<GenRingRequest>::init( Memory::GlobalAllocator );
|
||||
@ -183,22 +179,23 @@ void gen__ring_request( StrC type, sw size, StrC dep = {} )
|
||||
}
|
||||
|
||||
// Ring definition depends on a array and buffer definition.
|
||||
gen__buffer_request( type, size, dep );
|
||||
gen__buffer_request( type, dep );
|
||||
|
||||
GenRingRequest request = { dep, type, size};
|
||||
GenRingRequest request = { dep, type };
|
||||
GenRingRequests.append( request );
|
||||
}
|
||||
#define gen_ring( type ) gen__ring_request( { txt_to_StrC(type) }, sizeof( type ))
|
||||
#define gen_ring( type ) gen__ring_request( code(type) )
|
||||
|
||||
u32 gen_ring_file()
|
||||
{
|
||||
Builder
|
||||
gen_ring_file;
|
||||
gen_ring_file.open( "ring.NonParsed.gen.hpp" );
|
||||
gen_ring_file.open( "ring.Upfront.gen.hpp" );
|
||||
|
||||
gen_ring_file.print( def_include( StrC::from("Bloat.hpp")) );
|
||||
gen_ring_file.print( def_include( StrC::from("buffer.NonParsed.gen.hpp")) );
|
||||
// gen_ring_file.print( gen__ring_base() );
|
||||
gen_ring_file.print( def_include( txt_StrC("Bloat.hpp")) );
|
||||
gen_ring_file.print( def_include( txt_StrC("buffer.Upfront.gen.hpp")) );
|
||||
|
||||
gen_ring_file.print( def_using_namespace( name(gen)));
|
||||
|
||||
GenRingRequest* current = GenRingRequests;
|
||||
s32 left = GenRingRequests.num();
|
||||
@ -206,7 +203,7 @@ u32 gen_ring_file()
|
||||
{
|
||||
GenRingRequest const& request = * current;
|
||||
|
||||
Code generated_ring = gen__ring( current->Type, current->TypeSize );
|
||||
Code generated_ring = gen__ring( current->Type );
|
||||
|
||||
if ( request.Dependency )
|
||||
{
|
@ -7,17 +7,17 @@ u32 gen_sanity()
|
||||
{
|
||||
Builder
|
||||
gen_sanity_file;
|
||||
gen_sanity_file.open("./sanity.NonParsed.gen.hpp");
|
||||
gen_sanity_file.open("./sanity.Upfront.gen.hpp");
|
||||
|
||||
// Comment
|
||||
{
|
||||
Code comment_test = def_comment( StrC::from("Sanity check: def_comment test") );
|
||||
Code comment_test = def_comment( txt_StrC("Sanity check: def_comment test") );
|
||||
|
||||
gen_sanity_file.print(comment_test);
|
||||
}
|
||||
|
||||
gen_sanity_file.print_fmt("\n");
|
||||
gen_sanity_file.print( def_comment( StrC::from(
|
||||
gen_sanity_file.print( def_comment( txt_StrC(
|
||||
"The following will show a series of base cases for the gen api.\n"
|
||||
)));
|
||||
|
||||
@ -26,7 +26,7 @@ u32 gen_sanity()
|
||||
Code fwd = def_class( name(TestEmptyClass) );
|
||||
Code empty_body;
|
||||
{
|
||||
Code cmt = def_comment( StrC::from("Empty class body") );
|
||||
Code cmt = def_comment( txt_StrC("Empty class body") );
|
||||
Code body = def_class_body( 1, cmt );
|
||||
|
||||
empty_body = def_class( name(TestEmptyClass), body );
|
||||
@ -74,7 +74,7 @@ u32 gen_sanity()
|
||||
// External Linkage
|
||||
{
|
||||
Code body = def_extern_link_body( 1
|
||||
, def_comment( StrC::from("Empty extern body") )
|
||||
, def_comment( txt_StrC("Empty extern body") )
|
||||
);
|
||||
|
||||
Code c_extern = def_extern_link( name(C), body );
|
||||
@ -102,7 +102,7 @@ u32 gen_sanity()
|
||||
Code def;
|
||||
{
|
||||
Code body = def_function_body( 1
|
||||
, def_comment( StrC::from("Empty function body") )
|
||||
, def_comment( txt_StrC("Empty function body") )
|
||||
);
|
||||
|
||||
def = def_function( name(test_function), __, __, body );
|
||||
@ -116,7 +116,7 @@ u32 gen_sanity()
|
||||
|
||||
// Include
|
||||
{
|
||||
Code include = def_include( StrC::from("../DummyInclude.hpp") );
|
||||
Code include = def_include( txt_StrC("../DummyInclude.hpp") );
|
||||
|
||||
gen_sanity_file.print(include);
|
||||
}
|
||||
@ -144,7 +144,7 @@ u32 gen_sanity()
|
||||
Code namespace_def;
|
||||
{
|
||||
Code body = def_namespace_body( 1
|
||||
, def_comment( StrC::from("Empty namespace body") )
|
||||
, def_comment( txt_StrC("Empty namespace body") )
|
||||
);
|
||||
|
||||
namespace_def = def_namespace( name(TestNamespace), body );
|
||||
@ -215,7 +215,7 @@ u32 gen_sanity()
|
||||
Code def, def2;
|
||||
{
|
||||
Code body = def_function_body( 1
|
||||
, def_comment( StrC::from("Empty function body") )
|
||||
, def_comment( txt_StrC("Empty function body") )
|
||||
);
|
||||
|
||||
Code params = def_params( 2
|
||||
@ -261,7 +261,7 @@ u32 gen_sanity()
|
||||
Code fwd = def_class( name(TestEmptyStruct) );
|
||||
Code empty_body;
|
||||
{
|
||||
Code cmt = def_comment( StrC::from("Empty struct body") );
|
||||
Code cmt = def_comment( txt_StrC("Empty struct body") );
|
||||
Code body = def_class_body( 1, cmt );
|
||||
|
||||
empty_body = def_class( name(TestEmptyStruct), body );
|
||||
@ -276,7 +276,7 @@ u32 gen_sanity()
|
||||
// Union
|
||||
{
|
||||
Code body = def_union_body( 1
|
||||
, def_comment( StrC::from("Empty union body") )
|
||||
, def_comment( txt_StrC("Empty union body") )
|
||||
);
|
||||
|
||||
Code def = def_union( name(TestEmptyUnion), body );
|
||||
@ -314,7 +314,7 @@ u32 gen_sanity()
|
||||
|
||||
Code tmpl = def_template( def_param( t_class, name(Type) )
|
||||
, def_function( name(test_template), def_param( t_Type, name(a) ), __
|
||||
, def_function_body(1, def_comment( StrC::from("Empty template function body")))
|
||||
, def_function_body(1, def_comment( txt_StrC("Empty template function body")))
|
||||
)
|
||||
);
|
||||
|
||||
@ -323,7 +323,7 @@ u32 gen_sanity()
|
||||
|
||||
gen_sanity_file.print_fmt("\n");
|
||||
|
||||
gen_sanity_file.print( def_comment( StrC::from(
|
||||
gen_sanity_file.print( def_comment( txt_StrC(
|
||||
"End of base case tests.\n"
|
||||
)));
|
||||
|
@ -11,8 +11,7 @@ includes = include_directories(
|
||||
# get_sources = files('./get_sources.ps1')
|
||||
# sources = files(run_command('powershell', get_sources, check: true).stdout().strip().split('\n'))
|
||||
|
||||
sources = [ '../test.NonParsed.cpp' ]
|
||||
sources_parsed = [ '../test.Parsed.cpp' ]
|
||||
sources = [ '../test.cpp' ]
|
||||
|
||||
if get_option('buildtype').startswith('debug')
|
||||
|
||||
@ -26,4 +25,3 @@ endif
|
||||
add_project_arguments('-Dgen_time', language : ['c', 'cpp'])
|
||||
|
||||
executable( 'gencpp', sources, include_directories : includes )
|
||||
executable( 'gencpp_parsed', sources_parsed, include_directories : includes )
|
||||
|
@ -1,9 +1,9 @@
|
||||
#include "Bloat.cpp"
|
||||
#include "NonParsed\Array.NonParsed.hpp"
|
||||
#include "NonParsed\Buffer.NonParsed.hpp"
|
||||
#include "NonParsed\HashTable.NonParsed.hpp"
|
||||
#include "NonParsed\Ring.NonParsed.hpp"
|
||||
#include "NonParsed\Sanity.NonParsed.hpp"
|
||||
#include "Upfront\Array.Upfront.hpp"
|
||||
#include "Upfront\Buffer.Upfront.hpp"
|
||||
#include "Upfront\HashTable.Upfront.hpp"
|
||||
#include "Upfront\Ring.Upfront.hpp"
|
||||
#include "Upfront\Sanity.Upfront.hpp"
|
||||
|
||||
|
||||
#ifdef gen_time
|
||||
@ -20,7 +20,7 @@ int gen_main()
|
||||
gen_sanity();
|
||||
|
||||
gen_array( u8 );
|
||||
// gen_array( sw );
|
||||
gen_array( sw );
|
||||
|
||||
gen_buffer( u8 );
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
using namespace gen;
|
||||
|
||||
// TODO : Rewrite this to include both upfront and parsed testing.
|
||||
|
||||
int gen_main()
|
||||
{
|
||||
@ -41,7 +42,7 @@ int gen_main()
|
||||
using u16 = unsigned short;
|
||||
)));
|
||||
|
||||
soa_test.print( def_include( StrC::from("Bloat.hpp")));
|
||||
soa_test.print( def_include( txt_StrC("Bloat.hpp")));
|
||||
|
||||
soa_test.print( def_using_namespace( name(gen) ) );
|
||||
|
||||
@ -55,7 +56,7 @@ int gen_main()
|
||||
u64 D;
|
||||
};
|
||||
)),
|
||||
true
|
||||
false
|
||||
));
|
||||
|
||||
soa_test.write();
|
Loading…
Reference in New Issue
Block a user