mirror of
https://github.com/Ed94/gencpp.git
synced 2025-07-10 23:55:43 -07:00
Parser constructor passes all current tests...
Pretty much have a working library now... Albiet with problably quite a few hidden bugs in parsing. Next steps are to start converting library to use its own Arena, Pool, Array, HashTable types. And either work on zpl dependency gutting or making a more robust set of tests.
This commit is contained in:
202
test/Parsed/Buffer.Parsed.hpp
Normal file
202
test/Parsed/Buffer.Parsed.hpp
Normal file
@ -0,0 +1,202 @@
|
||||
#pragma once
|
||||
|
||||
#if gen_time
|
||||
#include "gen.hpp"
|
||||
|
||||
using namespace gen;
|
||||
|
||||
Code gen__buffer_base()
|
||||
{
|
||||
return parse_global_body( code(
|
||||
struct BufferHeader
|
||||
{
|
||||
AllocatorInfo Backing;
|
||||
uw Capacity;
|
||||
uw Num;
|
||||
};
|
||||
));
|
||||
}
|
||||
|
||||
Code gen__buffer( StrC type )
|
||||
{
|
||||
StrC name;
|
||||
{
|
||||
char const* name_str = str_fmt_buf( "Buffer_%s\0", type.Ptr );
|
||||
s32 name_len = str_len( name_str );
|
||||
|
||||
name = { name_len, name_str };
|
||||
};
|
||||
|
||||
Code buffer = parse_struct( token_fmt(
|
||||
txt(
|
||||
struct <BufferName>
|
||||
{
|
||||
using Header = BufferHeader;
|
||||
using Type = <type>;
|
||||
|
||||
static <BufferName> init( AllocatorInfo allocator, sw capacity )
|
||||
{
|
||||
Header* header = rcast( Header*, alloc( allocator, sizeof( Header ) + capacity * sizeof( Type ) ) );
|
||||
|
||||
if ( header == nullptr )
|
||||
return { nullptr };
|
||||
|
||||
header->Backing = allocator;
|
||||
header->Capacity = capacity;
|
||||
header->Num = 0;
|
||||
|
||||
return { rcast( Type*, header + 1 ) };
|
||||
}
|
||||
|
||||
<BufferName> init( AllocatorInfo allocator, <BufferName> other )
|
||||
{
|
||||
Header& other_header = other.get_header();
|
||||
Header* header = rcast( Header*, alloc( allocator, sizeof( Header ) + other_header.Capacity * sizeof( Type ) ) );
|
||||
|
||||
if ( header == nullptr )
|
||||
return { nullptr };
|
||||
|
||||
header->Backing = allocator;
|
||||
header->Capacity = other_header.Capacity;
|
||||
header->Num = other_header.Num;
|
||||
|
||||
mem_copy( header + 1, other.Data, other_header.Num * sizeof( Type ) );
|
||||
|
||||
return { rcast( Type*, header + 1 ) };
|
||||
}
|
||||
|
||||
void append( Type value )
|
||||
{
|
||||
Header& header = get_header();
|
||||
Data[ header.Num ] = value;
|
||||
header.Num++;
|
||||
}
|
||||
|
||||
void append( Type* values, sw num )
|
||||
{
|
||||
Header& header = get_header();
|
||||
ZPL_ASSERT( header.Num + num <= header.Capacity);
|
||||
|
||||
mem_copy( Data + header.Num, values, num * sizeof( Type ) );
|
||||
header.Num += num;
|
||||
}
|
||||
|
||||
void clear( void )
|
||||
{
|
||||
Header& header = get_header();
|
||||
header.Num = 0;
|
||||
}
|
||||
|
||||
Type& end( void )
|
||||
{
|
||||
Header& header = get_header();
|
||||
return Data[ header.Num - 1 ];
|
||||
}
|
||||
|
||||
void free( void )
|
||||
{
|
||||
Header& header = get_header();
|
||||
zpl::free( header.Backing, &header );
|
||||
}
|
||||
|
||||
Header& get_header( void )
|
||||
{
|
||||
return *( rcast( Header*, Data ) - 1 );
|
||||
}
|
||||
|
||||
sw num( void )
|
||||
{
|
||||
return get_header().Num;
|
||||
}
|
||||
|
||||
void wipe( void )
|
||||
{
|
||||
Header& header = get_header();
|
||||
header.Num = 0;
|
||||
mem_set( Data, 0, header.Capacity * sizeof( Type ) );
|
||||
}
|
||||
|
||||
operator Type*()
|
||||
{
|
||||
return Data;
|
||||
}
|
||||
|
||||
Type* Data;
|
||||
};
|
||||
),
|
||||
2
|
||||
, "BufferName", (char const*) name
|
||||
, "type", (char const*) type
|
||||
));
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
struct GenBufferRequest
|
||||
{
|
||||
StrC Dependency;
|
||||
StrC Type;
|
||||
};
|
||||
Array(GenBufferRequest) GenBufferRequests;
|
||||
|
||||
void gen__buffer_request( StrC type, StrC dep = {} )
|
||||
{
|
||||
do_once_start
|
||||
array_init( GenBufferRequests, Memory::GlobalAllocator );
|
||||
do_once_end
|
||||
|
||||
// Make sure we don't already have a request for the type.
|
||||
for ( sw idx = 0; idx < array_count( GenBufferRequests ); ++idx )
|
||||
{
|
||||
StrC const reqest_type = GenBufferRequests[ idx ].Type;
|
||||
|
||||
if ( reqest_type.Len != type.Len )
|
||||
continue;
|
||||
|
||||
if ( str_compare( reqest_type.Ptr, type.Ptr, reqest_type.Len ) == 0 )
|
||||
return;
|
||||
}
|
||||
|
||||
GenBufferRequest request = { dep, type };
|
||||
array_append( GenBufferRequests, request );
|
||||
}
|
||||
#define gen_buffer( type ) gen__buffer_request( { txt_to_StrC(type) } )
|
||||
|
||||
u32 gen_buffer_file()
|
||||
{
|
||||
Builder
|
||||
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( gen__buffer_base() );
|
||||
|
||||
GenBufferRequest* current = GenBufferRequests;
|
||||
s32 left = array_count( GenBufferRequests );
|
||||
while (left--)
|
||||
{
|
||||
GenBufferRequest const& request = * current;
|
||||
|
||||
Code generated_buffer = gen__buffer( current->Type );
|
||||
|
||||
if ( request.Dependency )
|
||||
{
|
||||
char const* cmt_str = str_fmt_buf( "// Dependency for %s type", request.Type );
|
||||
s32 cmt_len = str_len( cmt_str );
|
||||
|
||||
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_buffer_file.print( generated_buffer );
|
||||
current++;
|
||||
}
|
||||
|
||||
gen_buffer_file.write();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // gen_time
|
Reference in New Issue
Block a user